Example Scenarios

Follow along scenarios for creating and viewing your first policy reports.

Example: Trigger a PolicyReport

By default, a PolicyReport object (Namespaced) is created in the same Namespace where resources apply to one or more Kyverno policies, be they Policy or ClusterPolicy policies.

A single Kyverno ClusterPolicy exists with a single rule which ensures Pods cannot mount Secrets as environment variables.

 1apiVersion: kyverno.io/v1
 2kind: ClusterPolicy
 3metadata:
 4  name: secrets-not-from-env-vars
 5spec:
 6  background: true
 7  validationFailureAction: Audit
 8  rules:
 9  - name: secrets-not-from-env-vars
10    match:
11      any:
12      - resources:
13          kinds:
14          - Pod
15    validate:
16      message: "Secrets must be mounted as volumes, not as environment variables."
17      pattern:
18        spec:
19          containers:
20          - name: "*"
21            =(env):
22            - =(valueFrom):
23                X(secretKeyRef): "null"

Creating a Pod in this Namespace which does not use any Secrets (and thereby does not violate the secrets-not-from-env-vars rule in the ClusterPolicy) will generate the first entry in the PolicyReport, but listed as a PASS.

 1$ kubectl run busybox --image busybox:1.28 -- sleep 9999
 2pod/busybox created
 3
 4$ kubectl get po
 5NAME      READY   STATUS    RESTARTS   AGE
 6busybox   1/1     Running   0          66s
 7
 8$ kubectl get polr
 9NAME                             PASS   FAIL   WARN   ERROR   SKIP   AGE
10cpol-secrets-not-from-env-vars   1      0      0      0       0      6s

Inspect the PolicyReport in the default Namespace to view its contents. Notice that the busybox Pod is listed as having passed.

 1$ kubectl get polr cpol-secrets-not-from-env-vars -o yaml
 2
 3<snipped>
 4results:
 5- message: validation rule 'secrets-not-from-env-vars' passed.
 6  policy: secrets-not-from-env-vars
 7  resources:
 8  - apiVersion: v1
 9    kind: Pod
10    name: busybox
11    namespace: default
12    uid: 0dd94825-cc6e-435b-982b-fb76ac2fdc2a
13  result: pass
14  rule: secrets-not-from-env-vars
15  scored: true
16  source: kyverno
17  timestamp:
18    nanos: 0
19    seconds: 1666097147
20summary:
21  error: 0
22  fail: 0
23  pass: 1
24  skip: 0
25  warn: 0

Create another Pod which violates the rule in the sample policy. Because the rule is written with validationFailureAction: Audit, resources are allowed to be created which violate the rule. If this occurs, another entry will be created in the PolicyReport which denotes this condition as a FAIL. By contrast, if validationFailureAction: Enforce and an offending resource was attempted creation, it would be immediately blocked and therefore would not generate another entry in the report. However, if the resource passed then a PASS result would be created in the report.

 1apiVersion: v1
 2kind: Pod
 3metadata:
 4  name: secret-pod
 5spec:
 6  containers:
 7  - name: busybox
 8    image: busybox:1.28
 9    env:
10    - name: SECRET_STUFF
11      valueFrom:
12        secretKeyRef:
13          name: mysecret
14          key: mysecretname

Since the above Pod spec was allowed and it violated the rule, there should now be a failure entry in the PolicyReport in the default Namespace.

 1$ kubectl get polr polr-ns-default -o yaml
 2
 3<snipped>
 4- message: 'validation error: Secrets must be mounted as volumes, not as environment
 5    variables. rule secrets-not-from-env-vars failed at path /spec/containers/0/env/0/valueFrom/secretKeyRef/'
 6  policy: secrets-not-from-env-vars
 7  resources:
 8  - apiVersion: v1
 9    kind: Pod
10    name: secret-pod
11    namespace: default
12    uid: 72a7422c-fb6f-486f-b274-1ca0de55d49d
13  result: fail
14  rule: secrets-not-from-env-vars
15  scored: true
16  source: kyverno
17  timestamp:
18    nanos: 0
19    seconds: 1666098438
20summary:
21  error: 0
22  fail: 1
23  pass: 1
24  skip: 0
25  warn: 0

Lastly, delete the Pod called secret-pod and once again check the PolicyReport object.

1$ kubectl delete po secret-pod
2pod "secret-pod" deleted
3
4$ kubectl get polr cpol-secrets-not-from-env-vars
5NAME                             PASS   FAIL   WARN   ERROR   SKIP   AGE
6cpol-secrets-not-from-env-vars   1      0      0      0       0      2m21s

Notice how the PolicyReport has removed the previously-failed entry when the violating Pod was deleted.

Example: Trigger a ClusterPolicyReport

A ClusterPolicyReport is the same concept as a PolicyReport only it contains resources which are cluster scoped rather than Namespaced.

As an example, create the following sample ClusterPolicy containing a single rule which validates that all new Namespaces should contain the label called thisshouldntexist and have some value. Notice how validationFailureAction: Audit and background: true in this ClusterPolicy.

 1apiVersion: kyverno.io/v1
 2kind: ClusterPolicy
 3metadata:
 4  name: require-ns-labels
 5spec:
 6  validationFailureAction: Audit
 7  background: true
 8  rules:
 9  - name: check-for-labels-on-namespace
10    match:
11      any:
12      - resources:
13          kinds:
14          - Namespace
15    validate:
16      message: "The label `thisshouldntexist` is required."
17      pattern:
18        metadata:
19          labels:
20            thisshouldntexist: "?*"

After creating this sample ClusterPolicy, check for the existence of a ClusterPolicyReport object.

1$ kubectl get cpolr
2NAME                     PASS   FAIL   WARN   ERROR   SKIP   AGE
3cpol-require-ns-labels   0      5      0      0       0      76m

Notice that a ClusterPolicyReport named cpol-require-ns-labels exists with five failures. The number of combined results here will depend on the number of Namespaces in your cluster. At the moment the policy was created, Kyverno began inspecting existing Namespaces to evaluate them against the policy.

The ClusterPolicyReport, when inspected, has the same structure as the PolicyReport object and contains entries in the results and summary objects with the outcomes of a policy audit.

 1results:
 2- message: 'validation error: The label `thisshouldntexist` is required. rule check-for-labels-on-namespace
 3    failed at path /metadata/labels/thisshouldntexist/'
 4  policy: require-ns-labels
 5  resources:
 6  - apiVersion: v1
 7    kind: Namespace
 8    name: kube-node-lease
 9    uid: 06e5056f-76a3-461a-8d45-2793b8bd5bbc
10  result: fail
11  rule: check-for-labels-on-namespace
12  scored: true
13  source: kyverno
14  timestamp:
15    nanos: 0
16    seconds: 1666098654
17- message: 'validation error: The label `thisshouldntexist` is required. rule check-for-labels-on-namespace
18    failed at path /metadata/labels/thisshouldntexist/'
19  policy: require-ns-labels
20  resources:
21  - apiVersion: v1
22    kind: Namespace
23    name: default
24    uid: 4ffe22fd-0927-4ed1-8b04-50ca7ed58626
25  result: fail
26  rule: check-for-labels-on-namespace
27  scored: true
28  source: kyverno
29  timestamp:
30    nanos: 0
31    seconds: 1666098654
32- message: 'validation error: The label `thisshouldntexist` is required. rule check-for-labels-on-namespace
33    failed at path /metadata/labels/thisshouldntexist/'
34  policy: require-ns-labels
35  resources:
36  - apiVersion: v1
37    kind: Namespace
38    name: kyverno
39    uid: 5d87cd66-ce30-4abc-b863-f3b97715a5f1
40  result: fail
41  rule: check-for-labels-on-namespace
42  scored: true
43  source: kyverno
44  timestamp:
45    nanos: 0
46    seconds: 1666098654
47- message: 'validation error: The label `thisshouldntexist` is required. rule check-for-labels-on-namespace
48    failed at path /metadata/labels/thisshouldntexist/'
49  policy: require-ns-labels
50  resources:
51  - apiVersion: v1
52    kind: Namespace
53    name: kube-public
54    uid: c077ee71-435b-4921-9e05-8751fee71b64
55  result: fail
56  rule: check-for-labels-on-namespace
57  scored: true
58  source: kyverno
59  timestamp:
60    nanos: 0
61    seconds: 1666098654
62- message: 'validation error: The label `thisshouldntexist` is required. rule check-for-labels-on-namespace
63    failed at path /metadata/labels/thisshouldntexist/'
64  policy: require-ns-labels
65  resources:
66  - apiVersion: v1
67    kind: Namespace
68    name: kube-system
69    uid: e63fabde-b572-4b07-b899-b2230f4eac69
70  result: fail
71  rule: check-for-labels-on-namespace
72  scored: true
73  source: kyverno
74  timestamp:
75    nanos: 0
76    seconds: 1666098654
77summary:
78  error: 0
79  fail: 5
80  pass: 0
81  skip: 0
82  warn: 0
Last modified May 14, 2023 at 5:48 PM PST: Add Service call and versioning (#843) (b911373)