OMNI52
Kyverno Cheatsheet OMNI52™ GmbH
Neu in Kyverno 1.191.19.1: fünf Security-Fixes, einer davon Critical · 1.19.1: globalContext in namespaced Policies gesperrt · ClusterPolicy und Policy offiziell deprecatedAlle Neuerungen →

Kyverno
auf einem Blatt.

Dichte Referenz für Senior Platform Engineers und SREs zur Kubernetes-Policy-Engine (CNCF Graduated). Controller-Architektur, CEL-Policy-Typen, Image-Verifikation mit Sigstore, PolicyReports, Abgrenzung zu ValidatingAdmissionPolicy/MutatingAdmissionPolicy, Webhook-Tuning und Anti-Patterns. Keine Einsteiger-Folien.

Vorschau (2 Seiten A4 quer + Brand-Rückseite)

Kyverno Cheatsheet Seite 1: Architektur, Policy-Typen, Validieren mit CEL, Mutieren und Generieren, Image-Verifikation, VAP/MAP-Abgrenzung
Kyverno Cheatsheet Seite 2: PolicyException und Autogen, PolicyReports, Webhook-Betrieb, Upgrade & Support mit Security-Mindestversion 1.19.1, Anti-Patterns

PDF herunterladen

Direkter Download, keine Mail-Adresse nötig. CC BY-SA 4.0: kopieren, drucken, weiterverteilen ist ausdrücklich erlaubt, solange die Quellenangabe sichtbar bleibt.

Kyverno Cheatsheet (PDF, ~100 KB)

Was drin steht

Architektur

Vier Controller (Admission, Background, Reports, Cleanup), dynamisch generierte Webhooks aus den Policy-Matches, Cert-Rotation, HA mit 3 Replicas.

Policy-Typen 1.19

CEL-Engine policies.kyverno.io/v1 (stable seit 1.17, Feature-Parität seit 1.19): ValidatingPolicy, MutatingPolicy, GeneratingPolicy, DeletingPolicy, ImageValidatingPolicy. ClusterPolicy deprecated, Removal mit 1.20 (geschätzt Nov 2026).

Validieren & Mutieren

validationActions Deny/Audit, Admission- vs. Background-Evaluation, JSON-Mode für CI-Pipelines, ApplyConfiguration/JSONPatch, mutateExisting.

Supply Chain

ImageValidatingPolicy mit Cosign (Key/Keyless) und Notary, SBOM- und in-toto-Attestations, mutateDigest und verifyDigest gegen mutable Tags.

VAP/MAP & Exceptions

Präzise Abgrenzung zu K8s-nativen CEL-Policies (VAP GA 1.30, MAP GA 1.36), native VAP-Generierung, PolicyException-Governance, Autogen für Pod-Controller.

Compliance & Betrieb

PolicyReports (wgpolicyk8s.io) als Audit-Evidenz, failurePolicy fail-closed vs. fail-open, Webhook-Timeout, resourceFilters, K8s-Matrix, 1.19-Upgrade, Security-Mindestversion 1.19.1, Anti-Patterns aus der Praxis.

Cheatsheet im Volltext

Derselbe Inhalt wie im PDF, zum Mitlesen, Durchsuchen und direkten Kopieren der YAML-Snippets. Stand: Kyverno v1.19 (Edition 2026.10).

Architektur

Vier Controller, eine Policy-Engine

Admission-Controller (Pflicht): nimmt die Webhook-Callbacks des API-Servers an, führt validate/mutate aus, prüft PolicyExceptions.

Background-Controller: generate- und mutate-existing-Regeln auf Bestandsressourcen (reconciled UpdateRequests). Reports-Controller: erzeugt und pflegt PolicyReports. Cleanup-Controller: löscht Ressourcen nach Zeitplan.

Kyverno gehört in einen dedizierten Namespace, nie nach kube-system. CNCF-Graduated-Projekt (seit März 2026).

Dynamische Webhooks

Kyverno generiert seine Validating-/MutatingWebhookConfigurations selbst aus den match-Blöcken der installierten Policies, nur gematchte Ressourcen erzeugen überhaupt Admission-Calls.

Zertifikate: self-signed, automatische Rotation (CA 1 Jahr, TLS 150 Tage, Renewal ca. 15 Tage vor Ablauf). HA: 3 Replicas für den Admission-Controller; mehr Replicas bedeutet nicht bei jedem Controller mehr Durchsatz.

helm repo add kyverno https://kyverno.github.io/kyverno/
helm install kyverno kyverno/kyverno \
  -n kyverno --create-namespace
kubectl -n kyverno get deploy   # 4 Controller
kubectl get validatingwebhookconfigurations | grep kyverno

Policy-Typen (Stand 1.19)

CEL-Typen: policies.kyverno.io/v1

Seit 1.17 stable (v1): ValidatingPolicy, MutatingPolicy, GeneratingPolicy, DeletingPolicy, ImageValidatingPolicy, dazu PolicyException. Jeder Policy-Typ auch namespaced (NamespacedValidatingPolicy usw.). Ein CR pro Zweck, CEL statt JMESPath/Pattern; seit 1.19 Feature-Parität zu ClusterPolicy.

Storage-Version bleibt bis 1.19 v1beta1, mit 1.20 v1: danach gespeicherte Objekte per kyverno migrate umschreiben. v1alpha1 ist deprecated, Manifeste auf v1 heben.

Legacy: ClusterPolicy / Policy

kyverno.io/v1: validate-, mutate-, generate- und verifyImages-Regeln in einem CR. ClusterPolicy cluster-weit, Policy namespaced.

Deprecated: abgekündigt mit 1.17, offiziell seit 1.19 (Admission-Warnung beim Anlegen/Ändern). 1.19 ist das letzte Release mit vollem Support, Removal mit 1.20 (geschätzt Nov 2026), zusammen mit (Cluster)CleanupPolicy und der Legacy-PolicyException kyverno.io/v2. Bestand nach Migrations-Guide umziehen.

apiVersion: kyverno.io/v1
kind: ClusterPolicy
metadata: {name: require-ns-purpose-label}
spec:
  rules:
    - name: require-ns-purpose-label
      match:
        any:
        - resources: {kinds: [Namespace]}
      validate:
        failureAction: Enforce   # oder Audit
        message: "Label `purpose` ist Pflicht."
        pattern:
          metadata:
            labels:
              purpose: production

Validieren mit CEL

apiVersion: policies.kyverno.io/v1
kind: ValidatingPolicy
metadata: {name: check-labels}
spec:
  validationActions: [Deny]
  matchConstraints:
    resourceRules:
      - apiGroups: [""]
        apiVersions: [v1]
        operations: [CREATE, UPDATE]
        resources: [pods]
  validations:
    - message: label 'environment' ist Pflicht
      expression: >-
        'environment' in
        object.metadata.?labels.orValue([])

Enforcement & Modi

validationActions: Deny blockt, Audit protokolliert nur.

spec.evaluation: admission und background getrennt schaltbar; mode: JSON prüft beliebige JSON-/YAML-Payloads auch außerhalb des Clusters (CI-Pipeline). matchConstraints folgt der API der K8s ValidatingAdmissionPolicy.

Mutieren & Generieren

MutatingPolicy

patchType: ApplyConfiguration (Server-Side-Apply-Merge) oder JSONPatch.

Bestandsressourcen: spec.evaluation.mutateExisting.enabled: true, der Background-Controller mutiert dann bereits existierende Objekte. Trigger und Ziel trennen per targetMatchConstraints (seit 1.17 auch als CEL-expression); ein Trigger mutiert alle passenden Ziele.

apiVersion: policies.kyverno.io/v1
kind: MutatingPolicy
metadata: {name: add-label}
spec:
  matchConstraints:
    resourceRules:
      - apiGroups: [""]
        apiVersions: [v1]
        operations: [CREATE]
        resources: [pods]
  mutations:
    - patchType: ApplyConfiguration
      applyConfiguration:
        expression: >
          Object{metadata: Object.metadata{
            labels: Object.metadata.labels{
              team: "platform"}}}

GeneratingPolicy

Erzeugt oder klont Ressourcen auf Trigger, Klassiker: Default-NetworkPolicy oder ResourceQuota bei jedem neuen Namespace. Seit 1.19 auch als YAML: generate[].template.value, mit interpolate: cel für (( ... ))-Platzhalter, und useServerSideApply: true für SSA. Läuft über UpdateRequests des Background-Controllers.

Image-Verifikation (Supply Chain)

ImageValidatingPolicy: Sigstore & Notary

Attestors: Cosign (Public Key, Keyless via OIDC issuer/subject, Transparency Log, TUF) und Notary (X.509-Zertifikate, optional TSA).

Attestations: SBOM- und in-toto-Predicates prüfen via verifyAttestationSignatures() und extractPayload().

validationConfigurations: mutateDigest (Tag wird Digest), verifyDigest, required, alle Default true. verifyDigest wird seit 1.19 durchgesetzt: mit mutateDigest: false fallen Images ohne Digest durch.

apiVersion: policies.kyverno.io/v1
kind: ImageValidatingPolicy
metadata: {name: verify-images}
spec:
  matchConstraints:
    resourceRules:
      - apiGroups: [""]
        apiVersions: [v1]
        operations: [CREATE]
        resources: [pods]
  matchImageReferences:
    - glob: "registry.example.com/*"
  attestors:
    - name: cosign
      cosign:
        key:
          data: |
            -----BEGIN PUBLIC KEY-----
            ...
            -----END PUBLIC KEY-----
  validations:
    - expression: >-
        images.containers.map(image,
        verifyImageSignatures(image,
        [attestors.cosign])).all(e, e > 0)
      message: "Signatur-Check fehlgeschlagen"

Abgrenzung: K8s-native CEL-Policies

Was der API-Server selbst kann

ValidatingAdmissionPolicy: GA seit K8s 1.30. MutatingAdmissionPolicy: GA seit K8s 1.36.

CEL läuft in-process im kube-apiserver: keine Webhooks, keine Zertifikate, keine Verfügbarkeits-Abhängigkeit von einem Policy-Deployment.

Was Kyverno darüber legt

Background-Scans auf Bestandsressourcen, PolicyReports, PolicyExceptions, generate/cleanup, Image-Signatur-Verifikation, JSON-Mode, Autogen.

ValidatingPolicy ist ein Superset der VAP und generiert via spec.autogen.validatingAdmissionPolicy.enabled: true eine native VAP, die im API-Server läuft (Flag generateValidatingAdmissionPolicy, Default an). MutatingPolicy analog per spec.autogen.mutatingAdmissionPolicy.enabled, Flag generateMutatingAdmissionPolicy (Default aus), MAP v1 ab K8s 1.36 seit Kyverno 1.19 (K8s 1.36 liegt außerhalb der offiziellen Testmatrix). Kyverno als Management-Layer, Enforcement ohne Webhook-Hop.

PolicyException & Autogen

PolicyException

Gezielte Ausnahme statt aufgeweichter Policy. CEL: policies.kyverno.io/v1, policyRefs (Name + Kind) plus CEL-matchConditions; images/allowedValues reicht die Exception als exceptions.allowedImages/exceptions.allowedValues in die CEL-Auswertung, expiresAt seit 1.19. Legacy kyverno.io/v2 (Policy + Regeln, Wildcard *): deprecated, Removal mit 1.20.

Default: deaktiviert (Helm features.policyExceptions.enabled). Aktivierung per --enablePolicyException + --exceptionNamespace. Leer wirkt je nach Engine anders: Legacy-Exceptions greifen dann gar nicht, CEL-Exceptions aus allen Namespaces (wie *). Also immer genau einen Namespace setzen, Erstellung per RBAC und GitOps kontrollieren.

ImageValidatingPolicy vor 1.19.1: eine passende Exception ignoriert images/allowedValues und schaltet die Signaturprüfung für die ganze Ressource ab (GHSA-5cjf-wwfg-pj4c). Mindestversion siehe Box „Security: mindestens 1.19.1“.

Autogen für Pod-Controller

Pod-Regeln werden automatisch auf die Pod-Controller ausgeweitet. CEL: Deployment, DaemonSet, StatefulSet, ReplicaSet, Job, CronJob, Auswahl über spec.autogen.podControllers.controllers; seit 1.19.1 auch Workload-CRDs (JobSet, RayJob …) als <resource>.<version>.<group>. Legacy zusätzlich ReplicationController, Annotation pod-policies.kyverno.io/autogen-controllers (none schaltet ab).

Achtung: greift Pod-Controller-Autogen (bei Pod-Policies Default, auch ohne podControllers), erzeugt Kyverno keine native VAP bzw. MAP (Grund im Policy-Status).

PolicyReports (Compliance)

Audit-Evidenz im Cluster

wgpolicyk8s.io/v1alpha2: PolicyReport (namespaced) und ClusterPolicyReport, offenes Format der Kubernetes Policy WG, nicht Kyverno-proprietär. Alternative seit 1.15 (Alpha): openreports.io/v1alpha1 per --openreportsEnabled (Helm openreports.enabled, Default aus), soll wgpolicyk8s langfristig ablösen.

Results: pass / fail / warn / error / skip. Gefüttert aus Admission-Requests und Background-Scans (Default: stündlich), deckt auch Bestandsressourcen ab, die nie durch Admission liefen.

kubectl get policyreport -A       # namespaced
kubectl get clusterpolicyreport   # cluster-scoped
kubectl get polr -o wide          # Kurzform
kubectl get polr <name> -o jsonpath=\
'{.results[?(@.result=="fail")]}'

Webhook-Betrieb

failurePolicy: bewusst entscheiden

Default Fail (fail-closed): ist Kyverno down, lehnt der API-Server alle gematchten Requests ab. Sicher, aber ein Verfügbarkeits-Risiko, HA-Replicas und PDB einplanen.

Fail-open global per --forceFailurePolicyIgnore, besser pro Policy abwägen: Security-Gates Fail, Komfort-Mutationen Ignore.

Neustart-Deadlock: --excludeBootstrapResources (seit 1.19, Default aus) nimmt Node und CSR aus den Fail-Webhooks, damit ein Cluster ohne laufende Kyverno-Pods wieder hochkommt. Policies auf diese Kinds greifen dann nicht.

Performance-Tuning

Webhook-Timeout: Default 10s (1–30s), knapp halten, hängende Admission bremst jedes Deployment.

Namespace-Filter: webhooks.namespaceSelector in der Kyverno-ConfigMap; kube-system und kyverno sind default ausgenommen. resourceFilters [Kind,Namespace,Name]: letzte Verteidigungslinie hinter dem Webhook. Background-Reports ignorieren sie per Default (--skipResourceFilters=true), CEL-generate und -mutateExisting beachten sie seit 1.19.

Match-Blöcke eng schneiden: was nicht matcht, erzeugt keinen Admission-Call.

Egress aus Policies: CEL http.Get/Post und apiCall.service laufen gegen --httpBlocklist (Default: Cloud-Metadaten 169.254.169.254, metadata.google.internal, Loopback; ein eigener Wert ersetzt die Defaults, also mitführen) und optional --httpAllowlist (URL-Präfixe). In Namespaced-Policies ist HTTP per Default aus (--allowHTTPInNamespacedPolicies=false). Für Legacy-apiCall und GlobalContextEntry gilt die Blocklist erst ab 1.19.1.

Upgrade & Support

Security: mindestens 1.19.1

Fünf Advisories vom 10.09.2026, gefixt nur in 1.19.1, kein Fix für 1.18:

GHSA-5qq8-67g6-4h2w (Critical, 9.9): Tenant mit Create-Recht auf namespaced Policy (kyverno.io/v1) schreibt per apiCall method: POST und %2e%2e im urlPath als Kyverno-SA in beliebige Namespaces, bis Cluster-Admin.

Dazu High: %2e%2e-Bypass der Namespace-Isolation bei apiCall (GHSA-c5qq-7g2q-cpqp), SSRF/SA-Token über Legacy-apiCall.service und GlobalContextEntry (GHSA-q825-p383-r9v5), namespace-übergreifendes Lesen von globalContext aus Namespaced-CEL-Policies (GHSA-59v6-2x73-wfg4), Exception-Bypass bei ImageValidatingPolicy (GHSA-5cjf-wwfg-pj4c).

Vor dem Upgrade auf 1.19

K8s-Matrix: Kyverno 1.18.x/1.19.x auf K8s 1.33 bis 1.35, andere Versionen ungetestet.

Support: offiziell nur 1.19 (bis 1.20, geschätzt Nov 2026), Patches nur für kritische Bugs und Critical/High-CVEs.

CRDs: die policies.kyverno.io-Typen kommen aus der Chart-Abhängigkeit kyverno-api (seit Chart 3.7), der Rest aus dem Subchart crds, beide über crds.install; wer CRDs separat ausrollt, prüft beide Quellen vorher.

kyverno-policies 3.9 tauscht die PSS-Policies beim Helm-Upgrade gegen ValidatingPolicy (policyType); bestehende Legacy-Exceptions kyverno.io/v2 auf diese Policies greifen dann nicht mehr, vorher als policies.kyverno.io/v1-Exception neu anlegen oder policyType: ClusterPolicy pinnen.

1.19.1 ändert Verhalten: globalContext ist in Namespaced-Policies gesperrt (Fix GHSA-59v6-2x73-wfg4); solche Policies vor dem Patch-Update prüfen.

Legacy-Bestand finden: Admission-Warnungen, Metrik kyverno_deprecated_api_requests_total und --warnings-as-errors für kyverno test und kyverno apply in CI (beide ab 1.19.1).

Anti-Patterns

Was du nicht tun solltest

Neue Policies als ClusterPolicy: offiziell deprecated seit 1.19, fällt mit 1.20 weg, Neues gehört in die CEL-Typen.

Enforce ohne Audit-Phase: neue Policies erst im Audit-Modus fahren, PolicyReports lesen, dann auf Deny/Enforce drehen.

Pauschal fail-open: Ignore überall hebelt Security-Policies bei jedem Kyverno-Ausfall aus.

Wildcard-Matches: jede Admission geht durch den Webhook, Latenz auf jedem API-Call, maximaler Blast-Radius bei Ausfall.

Exceptions ohne Governance: wer PolicyExceptions erstellen darf, hebelt Policies aus, exceptionNamespace + RBAC + Review-Pflicht.

Namespaced Policies als Tenant-Self-Service: apiCall, generate und mutateExisting aus Policy und Namespaced*Policy laufen mit den Rechten der Kyverno-ServiceAccounts. 2026 gab es dafür zwei Critical-Advisories (CVE-2026-54523, GHSA-5qq8-67g6-4h2w). Create-Rechte nur für das Plattform-Team bzw. per GitOps-Review.

Kyverno neben andere Workloads: dedizierter Namespace ist Vorgabe der Doku, nie nach kube-system deployen.

Verwandte Cheatsheets

Ebenfalls von OMNI52:
kubernetes-cheatsheet.de, Kubernetes Core
rke2-cheatsheet.de, RKE2-Distribution
rancher-cheatsheet.de, Rancher-Management
istio-cheatsheet.de, Service-Mesh-Layer (Istio in der Tiefe)

Lizenz & Weiterverteilung

CC BY-SA 4.0. Du darfst dieses Cheatsheet kopieren, weiterverteilen, ausdrucken und in eigenen Materialien zitieren. Bedingung: Quellenangabe „Kyverno Cheatsheet, OMNI52 GmbH, kyverno-cheatsheet.de“ bleibt sichtbar, und abgeleitete Werke stehen unter der gleichen Lizenz (Share-Alike).

Nicht erlaubt: Logo, Marken oder den Eindruck zu vermitteln, dass der Inhalt von dir/euch stammt oder dass OMNI52 GmbH die Weiterverwendung sponsort.

Volltext der Lizenz: creativecommons.org/licenses/by-sa/4.0/deed.de.

Kyverno is a trademark of The Linux Foundation; Kyverno is a Cloud Native Computing Foundation (CNCF) Graduated project. Kubernetes is a registered trademark of The Linux Foundation. OMNI52™ is a trademark of OMNI52 GmbH (filed, not yet registered). This website is operated by OMNI52 GmbH and is not affiliated with, endorsed by, or sponsored by The Linux Foundation, the CNCF, or the Kyverno project. “Kyverno” is used in a nominative / descriptive sense to indicate the technology this cheatsheet documents.