Kyverno Policies
Summary
- Kyverno is a Kubernetes-native policy engine where policies are YAML custom resources, not a separate language.
- Insight: because rules are Kubernetes objects, you author, review, and GitOps them exactly like any other manifest.
- Key Concepts: ClusterPolicy and Policy, rule types validate / mutate / generate / verifyImages, and
backgroundreporting for existing objects. - When to Use: teams that want guardrails (require limits, probes, labels; block
:latest) without learning Rego. - Limitations: cross-object logic and very complex rules are easier in a general language; Kyverno favors pattern matching and CEL-style expressions.
Recipe
Install Kyverno with Helm, then apply a ClusterPolicy in audit mode, watch reports, and switch to enforce.
helm repo add kyverno https://kyverno.github.io/kyverno/
helm install kyverno kyverno/kyverno -n kyverno --create-namespacekubectl apply -f require-limits.yaml
kubectl get clusterpolicy
kubectl get policyreport -AWorking Example
This ClusterPolicy requires every container to set CPU and memory limits and to define a readiness probe. It starts in Audit so it does not break existing workloads.
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: require-limits-and-probes
spec:
validationFailureAction: Audit # switch to Enforce after review
background: true
rules:
- name: require-resource-limits
match:
any:
- resources:
kinds: ["Pod"]
validate:
message: "CPU and memory limits are required."
pattern:
spec:
containers:
- resources:
limits:
memory: "?*"
cpu: "?*"
- name: require-readiness-probe
match:
any:
- resources:
kinds: ["Pod"]
validate:
message: "A readinessProbe is required."
pattern:
spec:
containers:
- readinessProbe:
"?*": "?*"Apply it, create a Deployment without limits, and inspect the generated report.
kubectl apply -f require-limits-and-probes.yaml
kubectl get policyreport -A -o wideOnce reports are clean, flip validationFailureAction to Enforce and reapply. Now violating writes are rejected at admission time.
Deep Dive
Rule types
A single policy can hold many rules, and each rule is one of four types.
validate accepts or rejects. mutate patches incoming objects. generate creates companion resources. verifyImages checks signatures and attestations.
Pattern matching versus expressions
The pattern block is a declarative overlay: ?* means "any non-empty value" and * means "any value including empty."
For richer logic, Kyverno supports deny conditions and CEL expressions, letting you compare fields or count elements.
validate:
message: "Image must not use the latest tag."
deny:
conditions:
any:
- key: "{{ images.containers.*.tag }}"
operator: AnyIn
values: ["latest", ""]Mutation for safe defaults
Mutate rules add defaults so authors do not have to. This example injects a default runAsNonRoot.
- name: default-non-root
match:
any:
- resources:
kinds: ["Pod"]
mutate:
patchStrategicMerge:
spec:
securityContext:
runAsNonRoot: trueBackground scanning
With background: true, Kyverno evaluates existing objects on a schedule and writes PolicyReport and ClusterPolicyReport results.
This surfaces drift in workloads created before the policy existed, without blocking them.
Enforcement actions
validationFailureAction: Audit reports only; Enforce rejects at admission. You can also set actions per rule with validationFailureActionOverrides scoped by namespace.
This lets you enforce strictly in payments while auditing in sandbox from one policy.
Generate rules for companion resources
Generate rules create objects automatically when a trigger appears, such as a default NetworkPolicy or ResourceQuota for every new namespace.
- name: default-deny-netpol
match:
any:
- resources:
kinds: ["Namespace"]
generate:
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
name: default-deny
namespace: "{{ request.object.metadata.name }}"
synchronize: true
data:
spec:
podSelector: {}
policyTypes: ["Ingress", "Egress"]With synchronize: true, Kyverno keeps the generated object in step with the rule and recreates it if someone deletes it.
Gotchas
Kyverno rejects writes only through its webhook, so if the Kyverno Pods are unhealthy, enforcement stops or writes block depending on the webhook failurePolicy.
Run Kyverno with multiple replicas and resource requests so it stays available under load.
pattern matching is easy to get subtly wrong: ?* requires a non-empty value, but a field set to 0 or false still counts as present. Test edge cases.
Policies apply to the object as the API server sees it after other mutations. If another mutating webhook runs later, your validate rule may see different data than the final object; keep policy ordering in mind.
Background scan does not enforce - it only reports. Do not assume a clean report means writes are blocked; check validationFailureAction.
Pod-level policies do not automatically cover Pod controllers. Kyverno auto-generates rules for Deployments, Jobs, and similar from a Pod rule, but confirm autogen is enabled if you disabled it.
Alternatives
OPA Gatekeeper uses Rego and constraint templates; pick it when you need a full policy language and a central constraint library.
ValidatingAdmissionPolicy (CEL) is built into the API server with no add-on to run; pick it for simple, high-volume checks where you want zero extra infrastructure.
Pod Security Admission covers the specific Pod Security Standards with no engine at all; use it as a baseline and layer Kyverno on top for custom rules.
FAQs
Do I need to learn a new language for Kyverno? No. Policies are YAML with pattern overlays and optional CEL expressions, which is why teams often start here.
Can Kyverno fix existing non-compliant workloads? It can report them via background scans and mutate them on their next write, but admission never rewrites already-stored objects retroactively.
How do I test policies before applying to a cluster? Use the kyverno CLI's apply and test commands against manifests in CI, then dry-run against a real cluster.
Does a Pod rule cover Deployments? Yes, through Kyverno's autogen feature, which derives equivalent rules for Pod controllers unless you disable it.
What happens if Kyverno is down? Behavior follows the webhook failurePolicy. With Fail, matching writes are blocked; with Ignore, they pass unchecked.
Can one policy enforce in some namespaces and audit in others? Yes, with validationFailureActionOverrides keyed by namespace selectors.
Related
- Where Kubernetes Enforces Your Rules
- Admission Basics
- OPA Gatekeeper
- Policy Testing
- Admission Best Practices
Stack versions: This page was written for Kubernetes 1.36.2, Docker Engine 29.6.1 (BuildKit default), containerd (CRI runtime on nodes), Helm 3, Compose v2, Argo CD (latest - verify at build), and Gateway API (GA - verify controller support at build).