Tools · Containers and Kubernetes security · 18 / 20
Kubernetes policy as code with Kyverno: validate, mutate, and audit mode
Write Kyverno policies that require labels, disallow latest tags, and enforce resource limits, start in Audit mode, and read policy reports.
Beyond Pod Security
Pod Security Admission covers a fixed set of pod controls. Organizations usually need more: approved registries, no latest tags, required ownership labels, limits on every container. Kyverno is a policy engine that runs as an admission webhook and expresses rules as Kubernetes resources. The built-in ValidatingAdmissionPolicy with CEL expressions and OPA Gatekeeper with Rego are alternatives.
A validate policy
validationFailureAction Audit records violations in PolicyReports without blocking. Enforce rejects. Start every new policy in Audit, review the reports, then switch to Enforce.
apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata:
name: disallow-latest-and-require-limits
spec:
validationFailureAction: Audit
background: true
rules:
- name: no-latest-tag
match: { any: [ { resources: { kinds: [Pod] } } ] }
validate:
message: Use a pinned image tag, not latest.
pattern:
spec:
containers:
- image: '!*:latest & *:*'
- name: require-memory-limit
match: { any: [ { resources: { kinds: [Pod] } } ] }
validate:
message: Memory limits are required.
pattern:
spec:
containers:
- resources: { limits: { memory: '?*' } }Lab: audit, then enforce
Install Kyverno with Helm in a lab cluster, apply the policy in Audit mode, and create a pod using nginx:latest without limits. The pod runs, but kubectl get policyreport shows failures. Change the action to Enforce and try again: the API server returns the policy message and rejects the pod. Use the kyverno CLI to test manifests in CI before they reach the cluster.
helm install kyverno kyverno/kyverno -n kyverno --create-namespace kubectl apply -f policy.yaml kubectl run bad --image=nginx:latest kubectl get policyreport -A kyverno apply policy.yaml --resource pod.yaml
Mutation and generation
Kyverno can also mutate objects, for example adding a default securityContext, and generate objects, such as a default-deny NetworkPolicy in every new namespace. Use mutation sparingly and keep it visible, so teams are not surprised by changes they did not write.
Diagram
Audit versus Enforce
Roll out in two steps.
Violating pod. Admitted
Record. PolicyReport entry
Use. Measure impact before blocking
Violating pod. Rejected with message
Record. Admission error and event
Use. After reports are clean
Check yourself
1. Which Kyverno validation action records violations but still admits the resource?
2. Where do you read Kyverno audit results?
3. Which is a built-in Kubernetes alternative for custom validation rules?