skip to content

How do you show an auditor every live Kyverno PolicyException and who can create one?

level: seniorimportance: must knowfreq 50%

answer

  1. the list is not the whole answer
  2. join each object back to its policy
  3. a stored object is not always a live one
  4. who holds create on the kind
  5. creator lives in the audit log

basics

~20 s

List PolicyException objects across all namespaces, map each to the policy and rules it waives and the resources it covers, then show who holds create on that kind. The object records no creator; that comes from audit logs.

solid answer

~50 s

Three artefacts answer it. First, the inventory: `kubectl get policyexceptions -A -o yaml`, reading each object's `spec.exceptions` for the policy and rule names it waives and its `match` block for the resources covered, then joining that back to the policies so the auditor sees which control is off for whom. Second, which of those are actually live: whether the Kyverno controller processes PolicyExceptions at all, and whether it is restricted to a designated namespace, are controller settings, so objects sitting elsewhere may be inert and the raw list can overstate. Third, and the real control, RBAC: PolicyException is a namespaced kind, so enumerate Roles, ClusterRoles and their bindings granting create or update on it, plus who can edit the Kyverno deployment and change those settings. The object itself does not record who created it; that comes from the API-server audit log.

go deeper

for a junior

Know that exemptions are ordinary Kubernetes objects you can list across all namespaces, and that each one names a policy and specific rules.

for a middle

Be able to read an exception and state which control it disables and for which resources, and to explain that a stored object is not necessarily one the engine reads.

for a senior

Drive the answer to RBAC: who holds create on the kind, in which namespaces, and who can change the controller settings that decide where exceptions count.

for a principal

Own the design position that authoring an exemption must be separated from owning the workload, and be ready to defend what that costs teams in turnaround time.

## What the auditor is actually asking The question sounds like a report request and is really a control question. Behind it: your policies claim a control is enforced; exemptions are the documented way that claim is false for specific workloads; so show me the complete set of exemptions, what each one turns off, and demonstrate that creating one is a privilege rather than a capability everyone already has. ## Artefact one: the inventory `kubectl get policyexceptions -A` gives you the objects; `-o yaml` gives you the substance. For each object, three things must reach the auditor in plain language: - **Which control is off.** From `spec.exceptions`: the `policyName` and the `ruleNames`. Join this against the policy to translate `check-base-image` into a sentence such as, this workload may run an image that is not built from an approved base image. - **For whom.** From `spec.match`: namespaces, kinds, names, label selectors. A match naming a namespace and nothing else is a much larger statement than a match naming one label, and the auditor should be told which they are looking at. - **How wide the rule side is.** A wildcard in `ruleNames` waives everything under that policy, including rules added to it after the exception was written. That detail belongs in the report, not in a footnote. What the object will not give you is any assertion about why the exemption exists or how long it should last; the record that carries owner, justification and review is a governance artefact maintained alongside, and it is a different discussion from this one. ## Artefact two: which of them are live This is where an inexperienced answer goes wrong by handing over the object list as if it were the answer. Whether exception objects are evaluated is a property of the Kyverno admission controller, not of the objects. Two settings matter: whether PolicyException processing is enabled at all, and whether the controller reads exceptions only from a designated namespace. If processing is off, everything on your list is inert decoration. If exceptions are pinned to one namespace, objects elsewhere are inert while looking identical in a listing. So the honest report has a column for it, and the honest answer is that you read the controller's configuration rather than inferring it. If you claim a specific object is live, the strongest evidence is an admission that actually took the exception path, not the object's existence. ## Artefact three: RBAC, which is the real control PolicyException is a namespaced Kubernetes kind, so access is granted the ordinary way and audited the ordinary way. Enumerate: - Roles and RoleBindings granting `create`, `update` or `patch` on `policyexceptions` in any namespace, and especially in whatever namespace the controller honours. - ClusterRoles and ClusterRoleBindings that do the same everywhere, including aggregated ones a team inherited without anyone deciding to grant it. - Anyone who can edit the Kyverno controller's deployment or its Helm values, because they can turn processing on, or widen where exceptions are read from, without touching a single exception object. - Cluster administrators, who are above all of this and should be named as such rather than quietly omitted. The failure mode this uncovers is the one worth naming out loud: if teams can create PolicyException objects in namespaces the controller honours, then the team a policy just blocked is the team that can write the object unblocking it. The guardrail becomes advisory with extra typing, and nothing in the policy YAML shows it. The structural fix is that exception objects live in a namespace the workload teams cannot write to, and creating one is a review someone else performs. Do not reason from the object being namespaced to the conclusion that its reach is namespace-bounded; how far a given object's match block can reach depends on the controller's configuration, so verify it on your cluster instead of asserting it. ## Who created it The object carries no creator field. `metadata.managedFields` records the client that wrote each field, which is a tool name, not a person. The authoritative answer is the API-server audit log, which records the authenticated user for the create request; this presumes audit logging is on and retained long enough to cover the period the auditor asked about, which is worth confirming before you promise it. ## What separates a strong answer A weak answer produces a list. A strong answer produces a list, a statement about which entries are actually in force, an RBAC review naming who could have written each one and who can change the rules of the game, and an honest sentence about creator attribution depending on audit-log retention. The auditor learns more from the last three than from the first.

  • The object has no creator field. How do you tell the auditor who wrote it?
    From the API-server audit log, which records the authenticated user on the create request. `metadata.managedFields` only names the client that set each field, so it identifies a tool rather than a person. Check retention first: if the log does not go back far enough, say so rather than implying attribution you cannot produce.
  • Why is granting create on policyexceptions inside a team's own namespace risky?
    Because if the controller honours exceptions from that namespace, the team a policy blocked can author the object that unblocks it. The exemption stops being a decision someone reviewed. Keep exception objects in a namespace the workload teams cannot write to, and grant create there narrowly.
  • Your listing shows twelve exceptions but the platform team insists only four are in force. Who is right?
    Possibly both. Objects outside the namespace the controller reads, or any object at all when exception processing is disabled, are stored and inert. Read the controller configuration, then confirm on a live admission rather than arguing from the object list either way.
  • What can you say about whether a listed exception is still needed?
    From the object, very little; it records no owner, reason or review date. Answer with what you can evidence, which is what each one waives and for whom, and treat the justification and review record as a separate governance artefact maintained beside the object rather than inside it.

saying these in an interview costs you the question

  • Hands over the object list and calls it evidence
  • Claims the object records who created it
  • Assumes a namespaced kind is automatically scope-limited
  • Ignores who can edit the Kyverno controller configuration
  • Forgets that a wildcard rule list covers future rules too
  • Never checks whether exception processing is enabled

context