What does a Kyverno PolicyException name, and what does it not switch off?
answer
- an exemption is its own object
- names the policy, then the rules
- its own match block picks resources
- the policy object is untouched
- the controller decides if it counts
basics
~20 sA Kyverno PolicyException names the policy and the specific rule names it waives, plus a match block selecting which resources the waiver covers. It never disables the policy itself; anything the match block misses is still enforced.
solid answer
~50 sA PolicyException is a namespaced Kyverno custom resource with two halves. Its `spec.exceptions` list names one or more policies by `policyName` and, inside each, the exact `ruleNames` being waived, so a policy with five rules keeps the other four live. Its own `match` block selects which resources the waiver applies to by namespace, kind, name or label selector. A resource is exempted only when both halves hit: the rule that would have denied it is listed, and the resource matches. The policy object is not modified, so every other workload is still denied. Two settings sit above the object: the Kyverno admission controller must be configured to process PolicyExceptions at all, and operators can restrict which namespace exception objects are honoured from. Otherwise the API server stores a perfectly valid object that the engine simply ignores.
go deeper
Be ready to state the two halves out loud: the policies and rule names being waived, and the match block choosing the resources. Say clearly that the policy itself is not modified.
Explain that the exemption applies only where rule list and match block intersect, and that a controller-level setting decides whether exception objects are read at all.
Show that you treat a stored exception as unverified until you have seen it take effect, and that you think about which namespaces are allowed to hold these objects.
Own the position that exemptions must be enumerable objects rather than edits to the control, and be able to say what your platform gives up by allowing them at all.
## The problem a PolicyException solves A Kyverno policy is written for the whole cluster, but almost every real cluster has one workload that legitimately cannot satisfy one rule: a vendor appliance shipped as a closed image that is not built from your approved base image, for example. You have three bad options and one good one. You can delete the rule (everyone loses the control), you can drop the policy to audit mode (nobody is blocked any more), you can edit the policy to carve the workload out inline (the policy accretes special cases and the security team owns every edit), or you can record the carve-out as its own object. The last one is the PolicyException. ## The object has two halves **Half one: which rules.** `spec.exceptions` is a list. Each entry has a `policyName` and a `ruleNames` list naming rules inside that policy. This is deliberately rule-level, not policy-level. If `require-approved-base-image` also carries a rule forbidding a mutable image tag, an exception naming only `check-base-image` leaves the tag rule enforcing. Naming the policy is not enough on its own; the rules are what get waived. **Half two: which resources.** `spec.match` is the exception's own match block, in the same shape Kyverno uses elsewhere: `any` or `all`, each holding a `resources` selector with fields such as `namespaces`, `kinds`, `names` and a label `selector`. This is evaluated against the resource under admission, not against the policy. So a vendor appliance exception typically matches namespace `vendor-appliance`, kinds `Pod` and `Deployment`, and a label selector on the appliance's labels. Both halves must hit. A resource is skipped for a rule only if that rule is listed **and** the resource matches. That conjunction is the whole safety property: an exemption is scoped by rule and by resource, and everything outside the intersection is enforced exactly as before. ## What it does not do It does not modify the ClusterPolicy or Policy object. The policy stays in enforce mode for the rest of the cluster; the exception is consulted per admission request. It is not a mode switch, not a pause, and not a deletion. A reviewer who reads the policy alone therefore sees a control that looks fully enforced, which is exactly why the exception objects have to be enumerated separately when someone asks what is actually being enforced. It also is not self-authorising. Two things above the object decide whether it counts: - **Feature processing.** The Kyverno admission controller has to be configured to evaluate PolicyExceptions. If that is off, your object is accepted by the API server, shows up in `kubectl get policyexceptions`, and does absolutely nothing. Acceptance by the API server proves the schema is valid, nothing more. - **Where exceptions are honoured.** Operators can pin exception objects to a single designated namespace so that only objects created there are read. This exists precisely so that the ability to write an exception can be granted narrowly instead of wherever a team already has write access. ## The failure that follows from missing that Because the object is namespaced, teams assume the namespace bounds its power and that a Role granting `create` on `policyexceptions` in a team's own namespace is harmless. It is not harmless: in a cluster that honours exceptions from that namespace, the team that a policy just blocked can write the object that unblocks it. The exemption path stops being a decision someone made and becomes a self-service opt-out. Whether the object can reach resources outside its own namespace depends on how the controller is configured, so verify it on your cluster rather than assuming. ## A worked shape For an appliance in the `vendor-appliance` namespace that cannot use the approved base image, the exception names `policyName: require-approved-base-image` with `ruleNames: [check-base-image]`, and matches namespace `vendor-appliance`, kind `Pod`, label `app: vendor-appliance`. Result: that appliance's pods skip that one rule; every other pod in that namespace, and every pod everywhere else, is still checked; and every other rule in that policy still applies to the appliance itself. ## What a good answer sounds like Name both halves, say the two must intersect, and say plainly that the policy is untouched. The extra half sentence that distinguishes a good answer from a memorised one is that a stored PolicyException is not a working PolicyException until the controller is configured to read it.
- A policy has five rules and the exception lists one rule name. What happens to the other four?They still evaluate against the exempted workload and can still deny it. `ruleNames` is the unit of waiver, so the exemption is as narrow as the list. This is why naming the policy without naming rules is not a valid mental model, and why an exception carrying a wildcard over every rule is a much bigger grant than it looks.
- You applied a PolicyException, the API server accepted it, and the deploy is still denied. What do you check first?Whether the Kyverno controller is configured to process PolicyExceptions at all, and whether objects in that namespace are honoured. A stored object that is never read is the most common cause. Only then check that the denying rule name is actually listed and that the match block matches the resource the API server is admitting.
- Does a PolicyException put the policy into audit mode?No. Audit mode is a property of the policy and changes behaviour for every resource it matches. A PolicyException changes nothing about the policy object; it makes the engine skip specific rules for specific resources, and the policy keeps blocking everything else.
It is a named guest pass for one door on one day, not the door being propped open.
saying these in an interview costs you the question
- Says a PolicyException disables the whole policy
- Assumes naming the policy waives every rule in it
- Thinks the object's namespace automatically limits its reach
- Believes the API server accepting the object proves it took effect
- Confuses it with editing the policy's own exclude block