Applying Policies
Applying Policies asks how a written policy actually reaches resources: which requests it intercepts, how you narrow or widen that set, and how existing objects get covered.
match and exclude
match is mandatory and decides which requests a rule sees: resources.kinds, names, namespaces, operations, selector (labels on the resource), and namespaceSelector (labels on the namespace). any ORs blocks, all ANDs them. exclude subtracts from the matched set using the same syntax.
Preconditions
preconditions run after match and before the rule body and can use variables and JMESPath, for example checking {{ request.operation }}. They keep patterns readable by filtering early rather than encoding everything in one expression.
Autogen
Admission sees a Deployment, not the Pods it creates. For Pod controllers - Deployment, StatefulSet, DaemonSet, Job, CronJob - Kyverno automatically generates Pod-level rules from a Pod rule, suffixing the generated rule name with the controller. Disable with the annotation pod-policies.kyverno.io/autogen-controllers: none.
Existing resources
Admission fires only on new requests. Background scanning reports on existing objects; changing them requires a mutate rule with mutateExisting targets or a redeploy.
Worked example
A rule denies privileged containers and matches Pod. A Deployment that produces privileged Pods is still denied, because autogen produced Deployment-scoped rules. Reasoning: without autogen the policy catches only bare Pods, which is a well-known bypass; the generated rules close it and also appear in test expectations.
Traps
Using namespaceSelector on cluster-scoped resources; expecting namespaces patterns to match non-namespaced kinds; assuming mutations retroactively fix running workloads; and deploying a policy with no exclude for system namespaces, which can block cluster upgrades.