Kyverno mutate, generate, and verifyImages
More than validate — fix and prove provenance.
In short. Kyverno is more than a validator. Mutate rules inject defaults (labels, resource limits, `runAsNonRoot`) so developers get guardrails without copying boilerplate.
Kyverno is more than a validator. Mutate rules inject defaults (labels, resource limits, runAsNonRoot) so developers get guardrails without copying boilerplate. Generate rules create companion resources (NetworkPolicies, ResourceQuotas) when a Namespace appears. verifyImages checks Sigstore/Cosign signatures so admission can demand provenance, not only registry prefixes.
Mutation at scale needs discipline: mutated fields should be idempotent, documented, and tested. Surprising mutators destroy trust in the platform.
Mutate and generate
apiVersion: kyverno.io/v1kind: ClusterPolicymetadata:name: add-default-labelsspec:rules:- name: label-podsmatch:any:- resources:kinds: [Pod]mutate:patchStrategicMerge:metadata:labels:+(managed-by): kyverno
kubectl apply -f mutate-labels.yamlkubectl run demo --image=ghcr.io/acme/app:1 --restart=Neverkubectl get pod demo --show-labels
demo … managed-by=kyverno
When not to mutate
Do not mutate away security context fields that developers set intentionally without a written standard. Prefer validate+deny for hard requirements and mutate for defaults. Generate NetworkPolicies carefully — a wrong default-deny can brick namespaces.
Going deeper
Policy reports give visibility into pass/fail without reading webhook logs. Export them. For generate rules, decide whether Kyverno owns the downstream object lifecycle fully — orphaned generated NetworkPolicies confuse everyone.
verifyImages needs key distribution and CI signing first. Roll out in audit mode, measure unsigned image rates, then enforce on platform namespaces before product namespaces.
Mutate + validate pairs work well: mutate injects defaults; validate denies if critical fields still wrong. Document the pair so developers know why a field changed after apply.
Version ClusterPolicies and keep PRs small. A mega-PR that mutates labels, generates NetworkPolicies, and verifies images is unreviewable. Split by concern and roll out independently.
Test mutations with kyverno apply against fixtures in CI so a bad patchStrategicMerge never reaches the fleet. Include a fixture that already has the field to prove idempotency.
Beware mutating fields owned by operators (istio sidecars, HPA). Coordinate with those teams or you will fight reconciliation loops. Prefer mutating only fields your platform standard owns.
Export policy reports to your observability stack and alert when mutation failures spike — silent mutate errors leave fleets half-standardized and hard to debug.
Try this
Apply a mutate-label policy in lab, create a Pod, confirm the label, then delete the policy and note that existing Pods keep labels (admission is not a continuous reconciler unless you design for it).
kubectl get clusterpolicy add-default-labels -o yaml | head -20
spec:rules:- name: label-pods…
Takeaway
Kyverno mutate/generate/verifyImages extend policy from "no" to "fix and prove." Use defaults for hygiene, signatures for provenance, and validate/deny for hard lines.
Next: policy lifecycle — versioning and rollout waves.