Generate, test, audit, debug, and migrate Kyverno policies using the new CEL-based policy types (ValidatingPolicy, MutatingPolicy, GeneratingPolicy, ImageValidatingPolicy — all apiVersion policies.kyverno.io/v1). Covers matchConstraints, matchConditions, CEL validations/mutations, generator.Apply(), Audit→Deny promotion, PolicyException, kyverno-cli testing, and migration from legacy ClusterPolicy or PodSecurityPolicy. Use when asked to "write a Kyverno policy", "test a ValidatingPolicy", "audit my cluster for violations", "why is my policy not firing", or "migrate from ClusterPolicy".
92%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
Passed
No findings from the security scan
The canonical home for this skill is kyverno in nitinjain999/platform-skills
Write, test, audit, debug, and migrate Kyverno policies using the new CEL-based policy types.
All new policies use apiVersion: policies.kyverno.io/v1. Legacy ClusterPolicy (kyverno.io/v1) still works but is deprecated in v1.17 and planned for removal in v1.20.
When invoked with no arguments, ask before proceeding:
Q1 — Mode?
What do you need?
1. generate — write a new production-ready Kyverno policy
2. test — write kyverno-test.yaml fixtures and run kyverno-cli
3. audit — analyse PolicyReport data from a running cluster
4. debug — diagnose why a policy is not behaving as expected
5. migrate — convert a legacy ClusterPolicy or PodSecurityPolicy
Score a cluster or manifests against NSA/CIS/SOC2 before choosing policies → /platform-skills:kubescape
No Kyverno and none planned (Kubernetes ≥ 1.30): Kubescape's ready-made CEL
ValidatingAdmissionPolicies → /platform-skills:kubescape vap
Enter 1–5 or mode name:Q2 — Context (after mode selected, one at a time):
Describe the policy — what should it validate, mutate, or enforce? (e.g. "require app.kubernetes.io/team label on all Deployments"):Paste or describe the policy to test:Paste the PolicyReport JSON or run: kubectl get policyreport -A -o json | jq '[.items[].results[] | select(.result == "fail")]'Describe the symptom — is the policy not blocking, not mutating, or not appearing in PolicyReport?Paste the existing ClusterPolicy or PodSecurityPolicy YAML to migrate:Then proceed into the relevant mode below.
Write a production-ready Kyverno policy from a description.
Steps:
validationActions: [Audit] unless the user explicitly requests Deny — blocking admission with an untested policy is high blast radiusapiVersion: policies.kyverno.io/v1annotations block: policies.kyverno.io/title, category, severity, descriptionmatchConstraints.resourceRules targeting only the required kinds and operationsmatchConditions to exclude system namespaces (kube-system, kube-public, and platform tooling namespaces) — this replaces the old exclude blockValidatingPolicy: validations with CEL boolean expressions; use messageExpression for dynamic messages that include the resource nameMutatingPolicy: mutations with patchType: ApplyConfiguration (prefer for adds/merges) or patchType: JSONPatch (for precise path operations); use jsonpatch.escapeKey() for special characters in pathsGeneratingPolicy: variables with dyn() for inline resource definitions; generate with generator.Apply(namespace, [resources]); set evaluation.synchronize.enabled: trueImageValidatingPolicy: matchImageReferences with glob or CEL; attestors with cosign keyless or key-based; validations using verifyImageSignatures() CEL functionkyverno apply <policy.yaml> --resource <manifest.yaml> --detailed-resultsReference: references/kyverno.md → ValidatingPolicy, MutatingPolicy, GeneratingPolicy, ImageValidatingPolicy
Write a kyverno-test.yaml manifest and companion resource fixtures.
Steps:
matchConstraints resource rules, matchConditions, and what each validation expression approves vs deniesmatchConditions exclude a namespace, a resource in an excluded namespace (result: skip)kyverno-test.yaml:
name: <policy-name>-test
policies:
- <policy-file>.yaml
resources:
- resources/<passing-manifest>.yaml
- resources/<failing-manifest>.yaml
results:
- policy: <policy-name>
rule: <validation-name-or-autogen>
resource: <passing-resource-name>
kind: <Kind>
result: pass
- policy: <policy-name>
rule: <validation-name-or-autogen>
resource: <failing-resource-name>
kind: <Kind>
result: failkyverno test . — all results must matchresource.Get() / resource.List() (used in GeneratingPolicy) are not available in CLI tests — those require cluster-side testingReference: references/kyverno.md → kyverno-cli Testing
Analyse PolicyReport data from a running cluster and produce an actionable violation summary.
Steps:
kubectl get policyreport -A -o json \
| jq '[.items[].results[] | select(.result == "fail")]'
kubectl get clusterpolicyreport -o json \
| jq '[.items[].results[] | select(.result == "fail")]'validationActionskubectl patch validatingpolicy <name> \
--type merge \
-p '{"spec":{"validationActions":["Deny"]}}'[Deny] mode with active PolicyReport violations — indicates a suppressed PolicyException that needs reviewReference: references/kyverno.md → Audit → Enforce Promotion, PolicyReport
Diagnose why a Kyverno policy is not behaving as expected.
Steps:
kubectl get validatingpolicy <name> -o yamlkubectl get <kind> <name> -n <ns> -o yamlkubectl describe <kind> <name> -n <ns>kubectl logs -n kyverno -l app.kubernetes.io/component=admission-controller --tail=100kubectl logs -n kyverno -l app.kubernetes.io/component=background-controller --tail=100kubectl get policyreport -n <ns> -o yamlkubectl get validatingwebhookconfigurations — if missing, Kyverno is not running or failed to registerspec.matchConstraints.resourceRules kinds, apiGroups, and operations against the actual resourcematchConditions expression against the resource manually with kyverno applyevaluation.background.enabled: trueevaluation.mutateExisting.enabled: truekyverno apply CLIkubectl get policyexception -A — check if an exception covers this resource and policykyverno apply <policy.yaml> --resource <manifest.yaml> --detailed-resultsReference: references/kyverno.md → Troubleshooting
Migrate from legacy ClusterPolicy (kyverno.io/v1) or PodSecurityPolicy to the new policy types.
Map each rule type to the new kind:
| Legacy rule type | New kind |
|---|---|
validate rule | ValidatingPolicy |
mutate rule | MutatingPolicy |
generate rule | GeneratingPolicy |
verifyImages rule | ImageValidatingPolicy |
Key syntax changes:
spec.rules[].match.any[].resources → spec.matchConstraints.resourceRules[]spec.rules[].exclude → spec.matchConditions with CEL negationvalidate.pattern (JMESPath anchors) → validations[].expression (CEL boolean)validate.deny.conditions → validations[].expression with inverted CELmutate.patchStrategicMerge → mutations[].patchType: ApplyConfiguration with Object{...} CELmutate.patchesJSON6902 → mutations[].patchType: JSONPatch with [JSONPatch{...}] CELgenerate.data / generate.clone → generate[].expression using generator.Apply() and resource.Get()verifyImages[].attestors → attestors[] + validations[].expression using verifyImageSignatures()validationFailureAction: Enforce → validationActions: [Deny]validationFailureAction: Audit → validationActions: [Audit]Migration workflow:
[Audit] mode[Deny]Map each PSP field to a ValidatingPolicy:
| PSP field | ValidatingPolicy CEL expression |
|---|---|
privileged: false | object.spec.containers.all(c, !has(c.securityContext) || !c.securityContext.?privileged.orValue(false)) |
hostNetwork: false | !has(object.spec.hostNetwork) || object.spec.hostNetwork == false |
runAsNonRoot: true | object.spec.containers.all(c, has(c.securityContext) && c.securityContext.runAsNonRoot == true) |
readOnlyRootFilesystem: true | object.spec.containers.all(c, has(c.securityContext) && c.securityContext.readOnlyRootFilesystem == true) |
Deploy all new policies in [Audit] mode first, fix workloads, then switch to [Deny] before removing PSPs.
Reference: references/kyverno.md → Common Policy Patterns
nitinjain999/platform-skills
c2e75b7
Canonical home
since Oct 12, 2026
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.