During my preparation for the Kyverno Certified Associate exam, I hit an interesting part that I would like to talk about today. Which options do we have to exclude entire namespaces from Kyverno policies?
Depending on what we want to achieve, we have three different options at hand to accomplish our goal.
Option 1 – admission request exclusion
The first option allows us to exclude a Kubernetes namespace entirely from the admission requests sent to the Kyverno admission controller. By default, this is the case for the kyverno and kube-system namespaces.
You can change it by configuring the config.excludeKyvernoNamespace and config.webhooks options in the Helm chart. The latter one is used to add additional namespaces to the exclusion list.
config:
excludeKyvernoNamespace: true
webhooks:
namespaceSelector:
matchExpressions:
- key: kubernetes.io/metadata.name
operator: NotIn
values:
- kube-system
- grafana-alloy
A major downside of this option is that you create a loophole for the excluded namespaces as you exclude them entirely from Kyverno. However, the policy reporting for those excluded namespaces still works. Resources that comply with a policy are marked as Pass, and non-compliant resources as Fail.
Option 1 should only include the kyverno and kube-system namespaces to guarantee the Kubernetes cluster operation with its critical components. That means, for application namespaces, we need other options to exclude them from specific policies instead of doing a catch-all approach.
Option 2 – exclude parameter in policy object
One of the options to exclude namespaces from individual policies is the exclude parameter in the policy template.
...
spec:
background: true
rules:
- name: privilege-escalation
match:
any:
- resources:
kinds:
- Pod
operations:
- CREATE
- UPDATE
exclude:
any:
- resources:
namespaces:
- grafana-alloy
- kube-system
validate:
...
In the example above, I excluded the grafana-alloy and kube-system namespaces from the disallow-privilege-escalation policy, which I used as an example.
The advantage of this approach is that for application namespaces, admission requests are handled by Kyverno, and it is determined by the policy if rules are applied to the resources in that namespace.
However, this option also has a disadvantage. It is not as critical as option 1, but worth mentioning. When you use the exclude parameter in a policy template, the affected resources will not show up in the policy reporting, as seen below.
Even though option 2 is far better and more flexible, it still has its downsides, which led us to the final option 3.
Option 3 – Kyverno’s policy exception feature
Kyverno’s policy exception feature is not enabled by default. When you want to use it, you configure feature.policyExceptions.enabled and feature.policyExceptions.namespace in the Helm chart.
features:
policyExceptions:
enabled: true
namespace: "kyverno"
In the configuration example above, we only allow policy exceptions to be created in the kyverno namespace. The other allowed option is * for every namespace.
Once the feature is enabled, policy exceptions can be created, as seen below.
apiVersion: kyverno.io/v2
kind: PolicyException
metadata:
name: exclude-disallow-privilege-escalation
namespace: kyverno
spec:
background: true
exceptions:
- policyName: disallow-privilege-escalation
ruleNames:
- privilege-escalation
- autogen-privilege-escalation
match:
any:
- resources:
namespaces:
- grafana-alloy
- kube-system
- kyverno
Policy exceptions can target several policies and individual rules of a policy. In the example, we specify the policy disallow-privilege-escalation, and all rules include the auto-generated ones. Then, we define the matching resources our Kubernetes namespaces.
One of the advantages, besides a more fine-grained configuration for excluding resources from one or several policies, is the policy reporting of those resources compared to options 1 and 2.
Resources that fall under a policy exception are shown with a Skip status in the policy reporting. This provides visibility about the policy status for resources in the Kubernetes cluster, whether they are compliant, non-compliant, or excluded.
Summary
Kyverno provides a variety of options on how to exclude resources from Kyverno policies, as we learned today. In my opinion, the preferred solution should be the usage of Kyverno’s policy exception feature. However, it always depends on, and you might prefer for your use case option 1 or 2 rather than option 3. It is great to have the freedom of choice.


