View and audit Kyverno policy results with reports.

Policy reports are Kubernetes Custom Resources, generated and managed automatically by Kyverno, which contain the results of applying matching Kubernetes resources to Kyverno ClusterPolicy or Policy resources. They are created for validate and verifyImages rules when a resource is matched by one or more rules according to the policy definition. If resources violate multiple rules, there will be multiple entries. When resources are deleted, their entry will be removed from the report. Reports, therefore, always represent the current state of the cluster and do not record historical information.

For example, if a validate policy in Audit mode exists containing a single rule which requires that all resources set the label team and a user creates a Pod which does not set the team label, Kyverno will allow the Pod’s creation but record it as a fail result in a policy report due to the Pod being in violation of the policy and rule. Policies configured with spec.validationFailureAction: Enforce immediately block violating resources and results will only be reported for pass evaluations. Policy reports are an ideal way to observe the impact a Kyverno policy may have in a cluster without causing disruption. The insights gained from these policy reports may be used to provide valuable feedback to both users/developers so they may take appropriate action to bring offending resources into alignment, and to policy authors or cluster operators to help them refine policies prior to changing them to Enforce mode. Because reports are decoupled from policies, standard Kubernetes RBAC can then be applied to separate those who can see and manipulate policies from those who can view reports.

Policy reports are created based on two different triggers: an admission event (a CREATE, UPDATE, or DELETE action performed against a resource) or the result of a background scan discovering existing resources. Policy reports, like Kyverno policies, have both Namespaced and cluster-scoped variants; a PolicyReport is a Namespaced resource while a ClusterPolicyReport is a cluster-scoped resource. However, unlike Policy and ClusterPolicy resources, the PolicyReport and ClusterPolicyReport resources contain results from resources which are at the same scope and not what is determined by the Kyverno policy. For example, a ClusterPolicy (a cluster-scoped policy) contains a rule which matches on Pods (a Namespaced resource). Results generated from this policy and rule are written to a PolicyReport in the Namespace where the Pod exists.

Kyverno uses a standard and open format published by the Kubernetes Policy working group which proposes a common policy report format across Kubernetes tools. Below is an example of a ClusterPolicyReport which shows Namespaces in violation of a validate rule which requires the team label be present.

 2kind: ClusterPolicyReport
 4  creationTimestamp: "2022-10-18T11:55:20Z"
 5  generation: 1
 6  labels:
 7 kyverno
 8  name: cpol-require-ns-labels
 9  resourceVersion: "950"
10  uid: 6dde3d0d-d2e8-48d9-8b56-47b3c5e7a3b3
12- category: Best Practices
13  message: 'validation error: The label `team` is required. rule check-for-ns-labels
14    failed at path /metadata/labels/team/'
15  policy: require-ns-labels
16  resources:
17  - apiVersion: v1
18    kind: Namespace
19    name: kube-node-lease
20    uid: 06e5056f-76a3-461a-8d45-2793b8bd5bbc
21  result: fail
22  rule: check-for-ns-labels
23  scored: true
24  severity: medium
25  source: kyverno
26  timestamp:
27    nanos: 0
28    seconds: 1666094105

The report’s contents can be found under the results[] object in which it displays a number of fields including the resource that was matched against the rule in the parent policy.

Policy reports are created in a 1:1 relationship with a Kyverno policy. The naming follows the convention <policy_type>-<policy_name> where <policy_type> uses the alias pol (for Policy) or cpol (for ClusterPolicy).

Policy reports have a few configuration options available. For details, see the container flags section.

Reports are automatically chunked in increments of 1,000 results. Once a single report reaches this number of results, a second report with an incremented resource name will be created.

Report result logic

Entries in a policy report contain a result field which can be either pass, skip, warn, error, or fail.

passThe resource was applicable to a rule and the pattern passed evaluation.
skipPreconditions were not satisfied (if applicable) in a rule, or an applicable PolicyException exists and so further processing was not performed.
failThe resource failed the pattern evaluation.
warnThe annotation has been set to "false" in the policy converting otherwise fail results to warn.
errorVariable substitution failed outside of preconditions and elsewhere in the rule (ex., in the pattern).

Viewing policy report summaries

You can view a summary of the Namespaced policy reports using the following command:

1kubectl get policyreport -A

For example, below are the policy reports for a small test cluster (polr is the alias for PolicyReports) in which the only policy installed is named disallow-privileged-containers.

1$ kubectl get polr -A
2NAMESPACE     NAME                                  PASS   FAIL   WARN   ERROR   SKIP   AGE
3kube-system   cpol-disallow-privileged-containers   14     0      0      0       0      6s
4kyverno       cpol-disallow-privileged-containers   2      0      0      0       0      5s
5default       cpol-disallow-privileged-containers   0      1      0      0       0      5s

Similarly, you can view the cluster-wide report using:

1kubectl get clusterpolicyreport

Viewing policy violations

Since the report provides information on all rule and resource execution, returning only select entries requires a filter expression.

Policy reports can be inspected using either kubectl describe or kubectl get. For example, here is a command, requiring yq, to view only failures for the (Namespaced) report called cpol-disallow-privileged-containers:

1kubectl get polr cpol-disallow-privileged-containers -o jsonpath='{.results[?(@.result=="fail")]}' | yq -p json -
 1category: Pod Security Standards (Baseline)
 2message: 'validation error: Privileged mode is disallowed. The fields spec.containers[*].securityContext.privileged and spec.initContainers[*].securityContext.privileged must be unset or set to `false`.          . rule privileged-containers failed at path /spec/containers/0/securityContext/privileged/'
 3policy: disallow-privileged-containers
 5  - apiVersion: v1
 6    kind: Pod
 7    name: h0nk
 8    namespace: default
 9    uid: 71a4a8c8-8e02-46ed-af3d-db38f590a5b6
10result: fail
11rule: privileged-containers
12scored: true
13severity: medium
14source: kyverno
16  nanos: 0
17  seconds: 1.666094801e+09
19category: Pod Security Standards (Baseline)
20message: 'validation error: Privileged mode is disallowed. The fields spec.containers[*].securityContext.privileged and spec.initContainers[*].securityContext.privileged must be unset or set to `false`.          . rule privileged-containers failed at path /spec/containers/0/securityContext/privileged/'
21policy: disallow-privileged-containers
23  - apiVersion: v1
24    kind: Pod
25    name: badpod
26    namespace: default
27    uid: 8ef79afd-f2b4-44f8-8c50-dabdda45b8c0
28result: fail
29rule: privileged-containers
30scored: true
31severity: medium
32source: kyverno
34  nanos: 0
35  seconds: 1.666095335e+09

Report internals

The PolicyReport and ClusterPolicyReport are the final resources composed of matching resources as determined by Kyverno Policy and ClusterPolicy objects, however these reports are built of four intermediary resources. For matching resources which were caught during admission mode, AdmissionReport and ClusterAdmissionReport resources are created. For results of background processing, BackgroundScanReport and ClusterBackgroundScanReport resources are created. An example of a ClusterAdmissionReport is shown below.

 2kind: ClusterAdmissionReport
 4  creationTimestamp: "2022-10-18T13:15:09Z"
 5  generation: 1
 6  labels:
 7 kyverno
 8 a7ec5160f220c5b83c26b5c8f7dc35b6
 9 61946422-14ba-4aa2-94b4-229d38446381
10 "4773"
11  name: c0cc7337-9bcd-4d53-abb2-93f7f5555216
12  resourceVersion: "4986"
13  uid: 10babc6c-9e6e-4386-abed-c13f50091523
15  owner:
16    apiVersion: v1
17    kind: Namespace
18    name: testing
19    uid: 61946422-14ba-4aa2-94b4-229d38446381
20  results:
21  - message: 'validation error: The label `thisshouldntexist` is required. rule check-for-labels-on-namespace
22      failed at path /metadata/labels/thisshouldntexist/'
23    policy: require-ns-labels
24    result: fail
25    rule: check-for-labels-on-namespace
26    scored: true
27    source: kyverno
28    timestamp:
29      nanos: 0
30      seconds: 1666098909
31  summary:
32    error: 0
33    fail: 1
34    pass: 0
35    skip: 0
36    warn: 0

These intermediary resources have the same basic contents as a policy report and are used internally by Kyverno to build the final policy report. Kyverno will merge these results automatically into the appropriate policy report and there is no manual interaction typically required.

For more details on the internal reporting processes, see the developer docs here.

Background Scans

Periodically reapply policies to existing resources for reporting.

Example Scenarios

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

Last modified August 09, 2023 at 1:41 AM PST: Updates for 1.10.2 (#936) (5051c1e)