Kyverno Policy Exception Guide¶
If you have a violation of a Kyverno policy, one of the following actions can be taken to remedy the situation. The actions are listed from most-preferred to least preferred.
Fix the resource problem¶
Whenever possible, attempt to fix the problem in the resource that is causing the violation. This eliminates the risk and provides the highest security posture.
If you cannot fix the problem, you must discuss your exception plan with your security team to insure the risk is acceptable for your cluster.
Add a specific exclusion¶
Each policy has a matchConditions key that takes CEL expressions. A resource is only evaluated when every condition is true, so exclusions are written as expressions that are false for the resources you want to skip. Keep the expression as specific as possible.
Kyverno expands pod policies automatically to pod controllers (i.e. Deployments, Daemonsets, StatefulSets, Jobs, CronJobs). Autogen rewrites
object.*to the embedded pod template, which has nometadata, so match onrequest.*rather thanobject.metadata.*when excluding by name or namespace.
Here is an example of how to exclude pods named bar-* in namespace foo from a policy:
policies:
somePolicy:
matchConditions:
# Add a justification here for why the exclusion is needed
- name: exclude-foo-bar
expression: "!(request.namespace == 'foo' && request.name.startsWith('bar'))"
Risk: Matching resource names in this namespace now have the ability to violate this policy.
Exclude a namespace¶
In some cases, you may need to apply a policy only on specific namespaces. This type of exclusion usually applies to features that you only have enabled but don’t apply to some namespaces (e.g. istio sidecar injection). To exclude by namespace, use the excludeNamespaces key:
policies:
somePolicy:
excludeNamespaces:
# Add a justification here for why the exclusion is needed
- foo
To exclude a namespace from every policy, set policies.excludeNamespaces instead. The two lists are merged.
Risk: Any resources in the namespace now have the ability to violate this policy.
Only include specific namespaces¶
In some cases, you may want to only apply a policy to a specified list of namespaces. For example, you want to insure Guaranteed Quality of Service on high priority namespaces. To do this, add a matchConditions entry that only passes for those namespaces:
policies:
somePolicy:
matchConditions:
- name: only-foo-and-bar
expression: "request.namespace in ['foo', 'bar']"
To change which resource kinds a policy matches at all, override matchConstraints. This replaces the policy’s default resourceRules outright, so restate the full block. See Kyverno’s match documentation for the available fields.
Risk: All resources outside of the specified namespace(s) have the ability to violate the policy.
Add or remove an allowance to the policy¶
Some policies have a list of allowed, disallowed, or required values that can be expanded or reduced to change the scope of the policy. For example, you may want to add an additional registry to the allowed registries policy. You will need to look at the parameters section for the policy to see what is available. Below is an example of adding an allowance:
policies:
somePolicy:
parameters:
allow:
# Enter a comment for justifying the new set of values
- safevalue
If you only need an allowance added for a subset of the cluster, it may be better to add a policy under
additionalPolicieswith a different set of allowances and usematchConditionsto apply it to each namespace.
Risk: All resources, cluster wide, will be able to use the value specified as allowed.
Add a PolicyException¶
A PolicyException exempts specific resources from a named policy without editing the policy itself. This is how packages ship their own exemptions. Add one under additionalPolicyExceptions, referencing the policy by its rendered name:
additionalPolicyExceptions:
some-exception:
spec:
policyRefs:
- name: somePolicy
kind: ValidatingPolicy
matchConditions:
# Add a justification here for why the exception is needed
- name: exempt-bar
expression: "request.namespace == 'foo' && request.name.startsWith('bar')"
A
policyRefs.namethat doesn’t match a deployed policy does not error — the PolicyException is created and silently never applies. Confirm the name againstkubectl get vpol,mpol,gpol.
Risk: The referenced resources can violate the policy without any further review.
Disable the policy¶
As a last resort, policies can be disabled using the enabled flag, like the following:
policies:
somePolicy:
# Enter a comment to justify why the policy is not needed
enabled: false