Build Daily

Tinley Park · October 29, 2026
toolKyverno maintainers (CNCF; created at Nirmata)applied

Kyverno

Kyverno is a CNCF-graduated policy engine for Kubernetes. It runs as a dynamic admission webhook plus background controllers, and it validates, mutates, generates and cleans up resources from policies written as Kubernetes YAML with CEL expressions, with no separate policy language to learn. Apache 2.0 and free. It fits clusters that need guardrails such as pod security, required labels and allowed image registries, with results recorded as PolicyReports.

Updated October 17, 2026

Kyverno is a policy engine for Kubernetes. It sits in the API server's admission path and checks or changes each object before the object is stored. A background scan applies the same policies to objects that already exist. Policies are Kubernetes resources, so they are written, reviewed and delivered with the same tools as the workloads they govern.

What it is

Kyverno ("govern" in Greek) is an Apache 2.0 project started at Nirmata. It joined the CNCF in November 2020, moved to Incubating in July 2022, and graduated in March 2026 after a third-party security audit and a governance review.

The current line is v1.19. v1.19.0 shipped on 20 August 2026 and v1.19.1 on 10 September 2026, and a v1.19.2 release candidate is in testing. The project gives about three months of community patch support per minor. The releases page lists Kubernetes v1.33 to v1.35 as the tested range for 1.19.

v1.19 is a transition release. The 1.19 announcement declares full feature parity between the new CEL-based policy types and the legacy types. It deprecates ClusterPolicy, Policy, CleanupPolicy, ClusterCleanupPolicy and the legacy kyverno.io PolicyException, with removal planned for v1.20 (estimated November 2026; a tracking issue shows the exact scope is still under discussion). The replacements are in the policies.kyverno.io group:

Legacy rule or type CEL-based replacement
validate rule ValidatingPolicy
mutate rule MutatingPolicy
generate rule GeneratingPolicy
verifyImages rule ImageValidatingPolicy
CleanupPolicy DeletingPolicy
kyverno.io PolicyException policies.kyverno.io PolicyException

Each new type also has a namespaced variant, for example NamespacedValidatingPolicy. The CEL types follow the shape of Kubernetes' own ValidatingAdmissionPolicy, so a team that learns one can read the other.

Related projects in the same family: the Kyverno CLI (kyverno apply, kyverno test) runs policies outside a cluster, the kyverno-policies chart ships the Pod Security Standards as ready-made policies, and the optional Reports Server moves report storage out of etcd.

How it works

A Helm install runs four Deployments in a dedicated kyverno namespace:

  • Admission controller (required). It receives AdmissionReview callbacks from the API server and runs the policy engine for validation, mutation and exceptions. Its webhook controller rewrites the webhook configurations so that the API server sends only the resource kinds that policies match. A cert renewer keeps the webhook's TLS certificate current.
  • Background controller. It handles generate rules and mutate-existing rules through intermediate UpdateRequest resources.
  • Reports controller. It turns admission reports and background scan reports into PolicyReport and ClusterPolicyReport objects.
  • Cleanup controller. It deletes resources that match cleanup (now deleting) policies on a schedule.

Webhooks default to failurePolicy: Fail with a 10-second timeout. If Kyverno cannot answer, the API server rejects the request instead of letting it through. The figure shows the two paths a policy result takes: one at admission time, one for objects that already exist.

How Kyverno checks an object

Step 1 of 6. A client creates a Pod. Authentication and authorization pass, and mutating webhooks run first.

Admission runs inline on every matching write; the background scan reports on objects that already exist.

Mutation happens in the same admission call, before validation, and generation runs asynchronously in the background controller. Policy exceptions are separate resources that exempt named objects from named policies, so a policy can stay strict while one known workload is excused in review.

When to use it

Reach for it when:

  • You need guardrails on every cluster: Pod Security Standards, required labels, allowed image registries, no latest tags, resource limits present.
  • You want policies in plain Kubernetes YAML, reviewed in Git and synced with Argo CD like any other manifest.
  • You need mutation or generation as well as validation, for example default labels, or a NetworkPolicy and quota created for each new namespace.
  • You want image signature and attestation checks (Cosign or Notary) at admission time.
  • You want an audit view first: run policies in Audit mode, read the PolicyReports, then switch to Deny.

Skip it when:

  • The built-in Pod Security Admission labels cover the whole need. That adds no pods and no webhook.
  • A few simple validations are all that is required. Kubernetes' native ValidatingAdmissionPolicy runs inside the API server with no extra service.
  • The organization already standardizes on Rego and OPA across services, where Gatekeeper reuses that skill set.
  • The cluster cannot tolerate another fail-closed webhook in the write path and the team cannot run it in HA.

At a glance

Core concepts

  • Policy type — one CRD per job (ValidatingPolicy, MutatingPolicy, GeneratingPolicy, ImageValidatingPolicy, DeletingPolicy), cluster-wide or namespaced.
  • matchConstraints — which API groups, versions, operations and resources a policy applies to, in the same shape as Kubernetes admission policies.
  • validations — CEL expression plus message. messageExpression builds the message in CEL.
  • validationActions — Deny blocks, Audit records only, Warn returns a warning to the client.
  • evaluation — mode: Kubernetes (default) or mode: JSON for arbitrary payloads such as a Terraform plan, through the CLI; background.enabled turns on scans of existing objects.
  • PolicyException — exempts specific resources from specific policies.
  • PolicyReport — the standard report CRD (from the Kubernetes policy working group) holding results.

Key facts (v1.19)

Item Value
Licence Apache 2.0
Foundation status CNCF Graduated (2026)
Tested Kubernetes v1.33 to v1.35
Install Helm chart kyverno/kyverno, dedicated namespace
Controllers admission (required), background, reports, cleanup
HA guidance admission controller at least 2 replicas, 3 per controller for full HA
Webhook defaults failurePolicy: Fail, 10 s timeout (1 to 30 s allowed)
Default exclusions kyverno, kube-system, kube-public namespaces; Events and other system kinds
Patch support about 3 months per minor

Kyverno vs OPA Gatekeeper

Aspect Kyverno OPA Gatekeeper
Policy language YAML with CEL expressions Rego in ConstraintTemplates
Validate Yes Yes
Mutate Yes Yes (Assign, AssignMetadata)
Generate resources Yes No
Image verification Built in (Cosign, Notary) Through external data providers
Reports PolicyReport CRDs Audit results on constraint status
Outside Kubernetes CLI with JSON mode OPA itself runs anywhere

How to integrate

Install with Helm

helm repo add kyverno https://kyverno.github.io/kyverno/
helm repo update

# Production: HA replicas per controller
helm install kyverno kyverno/kyverno -n kyverno --create-namespace \
  --set admissionController.replicas=3 \
  --set backgroundController.replicas=2 \
  --set cleanupController.replicas=2 \
  --set reportsController.replicas=2

kubectl -n kyverno get deploy

From v1.19 the CRDs come from a kyverno-api chart dependency, still controlled by the crds.install value. Read the upgrade notes before a minor upgrade.

A first validating policy

Start in Audit, read the reports, then move to Deny:

apiVersion: policies.kyverno.io/v1
kind: ValidatingPolicy
metadata:
  name: require-environment-label
spec:
  validationActions:
    - Audit          # switch to Deny once reports are clean
  evaluation:
    background:
      enabled: true
  matchConstraints:
    resourceRules:
      - apiGroups: ['']
        apiVersions: [v1]
        operations: [CREATE, UPDATE]
        resources: [pods]
  validations:
    - message: "label 'environment' is required"
      expression: "'environment' in object.metadata.?labels.orValue({})"
kubectl get policyreports -A
kubectl get validatingpolicies

Test policies before they reach a cluster

# Apply a policy to local manifests
kyverno apply ./policies/ --resource ./manifests/

# Run the test suite; fail the CI job on deprecation warnings
kyverno test ./policies/ --warnings-as-errors

The --warnings-as-errors flag is the simple way to find legacy ClusterPolicy objects before v1.20 removes them.

In the GL stack

Kyverno v1.19.1 runs on the beta and prod clusters, two of the three K3s clusters behind builddaily.io, paiddaily.io and the other products.

  • What it enforces. Admission and background policies cover pod security, required labels and image registry rules. Admission stops a non-compliant object at write time, and the background scan reports on objects that were already in the cluster.
  • Rancher's webhook. Both clusters are imported into Rancher, and Rancher's own admission webhook guards the namespace Pod Security Admission labels. A change to a pod-security.kubernetes.io label needs Rancher's updatepsa permission, so that part of pod security sits with Rancher and the workload-level rules sit with Kyverno.
  • Neighbours. Falco watches runtime behaviour on the same two clusters, and Trivy Operator scans running images and configs on beta. Kyverno is the gate at admission time, before either of them sees the workload.

Gotchas

  • Legacy types end at v1.19. ClusterPolicy and Policy still work but return an admission warning, and the kyverno_deprecated_api_requests_total counter records each request that uses them. The kyverno_legacy_policies_total gauge counts legacy policies still stored in the cluster. Migrate with the CEL migration guide before v1.20. podSecurity subrules have no direct equivalent: each Pod Security control becomes one entry in spec.validations.
  • Storage version moves in v1.20. The policies.kyverno.io types store as v1beta1 in 1.19 and move to v1 in 1.20. After the upgrade, kyverno migrate rewrites stored objects.
  • Fail-closed by default. With failurePolicy: Fail, a crashed or unreachable admission controller blocks every write that a policy matches. Run at least two admission replicas and keep the kyverno namespace excluded so Kyverno can always restart itself.
  • Kubernetes version range. 1.19 is tested on Kubernetes v1.33 to v1.35. Newer clusters "may work, but are not tested," so test a cluster minor upgrade on a non-production cluster first.
  • Report volume. PolicyReports are stored in the cluster datastore. Many policies times many objects means many large objects. The optional Reports Server moves them out.
  • 1.19.1 tightens exceptions. It validates CEL match conditions on PolicyException, denies globalContext in namespaced policies, and fixes an exception scope bypass for image verification (GHSA-5cjf-wwfg-pj4c). Exceptions that loaded before may be rejected after the upgrade.
  • Rancher PSA labels. On Rancher-managed clusters, a Kyverno policy that mutates namespace pod-security.kubernetes.io labels is rejected by Rancher's webhook unless the Kyverno service account has updatepsa. Granting that verb lets Kyverno set privileged PSA levels, which Rancher's docs flag as a risk.

Risks

  • Write-path dependency. Kyverno is in the API path for every matched resource. A slow policy or a bad deploy of Kyverno affects every team on the cluster.
  • Migration churn. The move from the legacy types to the CEL types is a rewrite for any large policy library, and the removal date is an estimate.
  • Project health. CNCF graduation came with a third-party audit and a governance review, and the project releases roughly every quarter. Nirmata offers commercial support but does not own the project.
  • Lock-in. Low. The CEL types are close to Kubernetes' native admission policies, and PolicyReport is a shared format. Generate and image-verify rules have no native equivalent.
  • Privilege. The background controller needs write access to every resource kind that it generates or mutates. Review its ClusterRoles when adding generate policies.

Alternatives

  • OPA Gatekeeper — choose it when Rego and OPA are already the standard for policy across services.
  • ValidatingAdmissionPolicy (built in) — choose it for a few CEL validations with no extra service in the cluster.
  • Pod Security Admission (built in) — choose it when namespace-level Pod Security Standards are the only requirement.
  • Kubewarden — choose it for policies compiled to WebAssembly from general-purpose languages, a CNCF project started at SUSE that installs from Rancher.

Related