Jeder Vergleich von OPA und Kyverno, den du findest, wurde für eine Welt geschrieben, die es nicht mehr gibt.
Die alte Erzählung ging so: Rego ist mächtig, aber du musst es lernen; Kyverno ist YAML und deshalb zugänglich; such dir dein Gift aus. Diese Erzählung ist gleich zweimal gestorben. Kubernetes hat angefangen, Policies selbst durchzusetzen, und Kyverno hat aufgehört, eine reine YAML-Engine zu sein.
Bevor man also zwischen zwei Controllern wählt, lautet die nützlichere Frage: Brauchst du überhaupt einen Controller?

Was sich geändert hat: Kubernetes hat seine eigene Policy-Engine bekommen
Zwei Funktionen haben den Boden verschoben.
ValidatingAdmissionPolicy ist seit Kubernetes 1.30 stabil. Sie ist die deklarative, im Prozess laufende Alternative zu validierenden Admission-Webhooks und nutzt die Common Expression Language.
MutatingAdmissionPolicy ist seit Kubernetes 1.36 stabil und standardmäßig aktiv. Dieselbe Idee, nur zum Verändern statt zum Ablehnen. Der Weg dorthin war lang — Alpha in 1.30, Beta in 1.34, GA in 1.36 — auf älteren Clustern also erst prüfen, bevor du damit planst.
Eine Policy besteht aus drei Teilen: der Policy selbst, einer optionalen Parameter-Ressource und einem Binding, das beides verknüpft und den Geltungsbereich festlegt. Mehr ist es nicht:
apiVersion: admissionregistration.k8s.io/v1kind: ValidatingAdmissionPolicymetadata: name: "demo-policy.example.com"spec: failurePolicy: Fail matchConstraints: resourceRules: - apiGroups: ["apps"] apiVersions: ["v1"] operations: ["CREATE", "UPDATE"] resources: ["deployments"] validations: - expression: "object.spec.replicas <= 5"Kein Controller. Kein Webhook. Kein TLS-Zertifikat zum Rotieren. Kein zusätzlicher Netzwerk-Hop bei jedem API-Aufruf.
Der letzte Punkt wiegt schwerer, als er klingt — dazu später mehr.
Die eingebauten Policies können auch mehr, als das Spielbeispiel vermuten lässt. Es gibt variables zum Zusammensetzen von Ausdrücken, matchConditions für feingranulares Filtern, messageExpression für brauchbare Ablehnungsmeldungen, auditAnnotations und Type Checking — der API-Server prüft deinen Ausdruck gegen das Schema und meldet Fehler in status.typeChecking, bevor sie dich treffen:
status: typeChecking: expressionWarnings: - fieldRef: spec.validations[0].expression warning: |- apps/v1, Kind=Deployment: ERROR: <input>:1:7: undefined field 'replicas'Und validationActions erlaubt es, eine Policy als Deny, Warn oder Audit laufen zu lassen — du kannst eine Regel also erst im Beobachtungsmodus ausrollen. Das ist dieselbe Disziplin, für die ich bei Runtime-Erkennung und Alarmflut argumentiert habe: erst schauen, dann erzwingen.
Das Zweite, was sich geändert hat: Kyverno spricht CEL
Das Argument „YAML gegen Rego“ unterstellte, Kyverno sei eine YAML-und-JMESPath-Engine. Das stimmt nicht mehr.
Kyverno hat CEL übernommen, und das Projekt sagt auch klar warum — Kubernetes hat stark in CEL investiert, deshalb senke dessen Nutzung „die kognitive Last für Plattformteams, weil es eine Sache weniger zu lernen gibt“.
Die praktische Folge: Ein CEL-Ausdruck in einer eingebauten ValidatingAdmissionPolicy und einer in einer Kyverno-ValidatingPolicy sind nahe Verwandte. Die Sprache ist nicht länger die Achse, die diese Werkzeuge trennt.
Damit kam auch ein kompletter API-Umbau. Die aktuellen Policy-Typen:
| Typ | Aufgabe | Status |
|---|---|---|
ValidatingPolicy |
Ressourcen oder JSON-Payloads validieren | Stabil (v1.18) |
MutatingPolicy |
Neue oder bestehende Ressourcen verändern | Stabil (v1.18) |
GeneratingPolicy |
Ressourcen aus Auslösern erzeugen oder klonen | Stabil (v1.18) |
DeletingPolicy |
Passende Ressourcen zeitgesteuert löschen | Stabil (v1.18) |
ImageValidatingPolicy |
Image-Signaturen und Attestierungen prüfen | Stabil (v1.18) |
ClusterPolicy |
Alter Allzweck-Typ | Deprecated (v1.18) |
CleanupPolicy |
Altes zeitgesteuertes Löschen | Deprecated (v1.18) |
Wer Kyverno heute betreibt, sollte die unteren Zeilen nicht als Randnotiz lesen — das ist eine Migration mit Termin. Dazu gleich mehr.
Kyverno hat außerdem am 16. März 2026 den CNCF-Graduated-Status erreicht, nach Aufnahme im November 2020 und Incubating seit Juli 2022.
Wofür brauchst du dann noch einen Controller?
Hier die ehrliche Liste. Eingebaute Policies erledigen Validierung und Mutation zur Admission-Zeit. Sie erledigen nicht:
| Fähigkeit | Eingebaut | Gatekeeper | Kyverno |
|---|---|---|---|
| Bei Admission validieren | ja | ja | ja |
| Bei Admission mutieren | ja (ab 1.36) | ja | ja |
| Ressourcen erzeugen / klonen | nein | nein | ja |
| Image-Signaturen prüfen | nein | nein | ja |
| Bestehende Objekte auditieren | nein | ja | ja |
| Policy-Reports | nein | ja | ja |
| Zeitgesteuertes Aufräumen | nein | nein | ja |
| Policies außerhalb von Kubernetes | nein | über OPA | ja (JSON, Terraform) |

Drei dieser Zeilen sind der übliche Grund, warum Teams doch etwas installieren.
Generierung. Wird ein Namespace angelegt, willst du eine Default-NetworkPolicy, ein kopiertes Pull-Secret, eine ResourceQuota, eine LimitRange. Admission Control kann nur ablehnen oder bearbeiten, was jemand eingereicht hat — nicht erzeugen, was jemand vergessen hat. Kyvernos GeneratingPolicy kann das und hält die erzeugte Kopie mit ihrer Quelle synchron.
Image-Prüfung. Zu prüfen, ob ein Image signiert ist und die erwarteten Attestierungen trägt, ist Lieferketten-Durchsetzung und braucht zur Admission-Zeit Zugriff auf Registry und Transparenz-Log. Das ist das Feld von ImageValidatingPolicy. Es ist auch die fehlende Durchsetzungshälfte meines Arguments, warum eine SBOM allein das nächste Log4j nicht stoppt — eine Attestierung, die niemand prüft, ist ein Dokument, keine Kontrolle.
Hintergrund-Scans. Admission sieht nur neue und geänderte Objekte. Alles, was schon lief, als du die Policy geschrieben hast, bleibt unsichtbar. Gatekeepers Audit und Kyvernos Reports beantworten beide „Was verstößt gerade dagegen?“ — die erste Frage, die bei jeder Einführung gestellt wird.
Wo OPA tatsächlich gewinnt
Wer nur Kubernetes-Vergleiche liest, hält OPA für die umständlichere Option: Rego schreiben, Gatekeeper betreiben, ConstraintTemplate und Constraint paarweise pflegen.
apiVersion: templates.gatekeeper.sh/v1kind: ConstraintTemplatemetadata: name: k8srequiredlabelsspec: crd: spec: names: kind: K8sRequiredLabels validation: openAPIV3Schema: type: object properties: labels: type: array items: type: string targets: - target: admission.k8s.gatekeeper.sh rego: | package k8srequiredlabels violation[{"msg": msg}] { required := input.parameters.labels[_] not input.review.object.metadata.labels[required] msg := sprintf("missing required label: %v", [required]) }Das ist mehr Zeremonie als ein CEL-Einzeiler. Der Gewinn liegt nicht im Cluster.
OPA ist kein Kubernetes-Werkzeug. Es ist eine universelle Policy-Engine — CNCF graduiert — und Rego ist eine Sprache, die du auf API-Autorisierung in Microservices, Terraform-Pläne in der CI, Datenfilterung und Admission Control richten kannst. Wenn deine Organisation OPA ohnehin für Service-Autorisierung betreibt, ist Cluster-Policy in derselben Engine echte Konsolidierung und kein zusätzliches Werkzeug.
Gatekeeper ergänzt die Kubernetes-nativen Teile: eine parametrisierte Policy-Bibliothek, Constraints als CRDs, Mutation über Assign, AssignMetadata, ModifySet und AssignImage, Audit und External Data.
Der Handel ist in beide Richtungen real. Eine Sprache überall — zum Preis einer Sprache, die am ersten Tag niemand kann.
Wie ich tatsächlich entscheiden würde
Vier Fragen, in dieser Reihenfolge.
1. Deckt die eingebaute Policy die Regel ab?
Wenn es „X ablehnen“ oder „Y als Standard setzen“ heißt, schreib eine ValidatingAdmissionPolicy oder MutatingAdmissionPolicy und hör auf. Du hast null Betriebsfläche hinzugefügt. Das sollte der Standard sein für Pflicht-Labels, verbotene Capabilities, Registry-Allowlists und Replica-Grenzen.
2. Soll der Cluster Dinge erzeugen statt nur beurteilen? Dann brauchst du Kyverno. Für Generierung gibt es weder ein eingebautes noch ein Gatekeeper-Äquivalent.
3. Brauchst du Lieferketten-Prüfung bei der Admission?
Kyvernos ImageValidatingPolicy oder ein spezialisiertes Werkzeug. Weder die eingebauten Policies noch Gatekeeper können das.
4. Müssen Policies außerhalb von Kubernetes gelten? Dann OPA — und akzeptiere Rego als Preis für eine Engine über Cluster, CI und Services hinweg.
Die meisten Teams landen bei: eingebaute Policies für die einfache Mehrheit, Kyverno für die Handvoll Regeln, die Generierung, Image-Prüfung und Reports brauchen. Diese Kombination ist langweilig, und sie funktioniert.

Die Betriebsfalle, die selten zuerst genannt wird
Ein Webhook ist kein Feature, das man einschaltet. Er ist Infrastruktur im Anfragepfad.
Setz failurePolicy: Fail, und ein nicht erreichbarer Policy-Controller blockiert jede Operation, auf die er passt. Der klassische Ausfall sieht so aus: Der Controller ist weg, die Regel passt auf Pod-Erstellung, und jetzt kannst du keine Pods mehr planen — genau in dem Vorfall, aus dem du dich herausskalieren wolltest.
Setz stattdessen Ignore, und du hast die Durchsetzung still abgeschaltet. Deine Policies existieren weiter, sehen in Git grün aus und erzwingen nichts.
Es gibt keine dritte Option, die diese Wahl vermeidet. Was hilft:
- Namespaces ausschließen, die nie blockiert werden dürfen — mindestens
kube-systemund der Namespace des Policy-Controllers selbst. Ein Controller, dessen Webhook seine eigene Neuerstellung blockieren kann, beschert dir einen ernsthaft schlechten Nachmittag. matchConstraintseng fassen. Eine Policy aufresources: ["*"]setzt deinen Controller in den Pfad von allem, inklusive Leases und Events. Die Doku zeigt genau dieses Muster mitmatchConditions, die Leases, Node-Nutzer und RBAC-Anfragen ausnehmen.- Neue Regeln zuerst als
WarnoderAuditlaufen lassen und dann bewusst aufDenyheben. - Mutation läuft vor Validierung, und Mutationen können erneute Auswertung auslösen.
reinvocationPolicy: IfNeededexistiert, weil eine Mutation die Annahmen einer anderen ungültig machen kann.
Das ist das stärkste praktische Argument für die eingebauten Policies: Was im API-Server ausgewertet wird, kann nicht getrennt vom API-Server ausfallen. Eine ganze Ausfallklasse verschwindet.

Die Migration, von der du vielleicht nichts weißt
Wer Kyverno vor 2025 eingeführt hat, betreibt seine Policies fast sicher als ClusterPolicy. Das Projekt hat den Fahrplan veröffentlicht:
| Version | Datum | Status |
|---|---|---|
| v1.17 | Jan 2026 | Als deprecated markiert |
| v1.18 | Apr 2026 | Nur kritische Fixes |
| v1.19 | Jul 2026 | Nur kritische Fixes |
| v1.20 | Okt 2026 | Entfernung geplant |
Die CEL-basierten Typen kamen in v1.14 (April 2025) und v1.15 (Juli 2025) und sind seit v1.18 stabil, veröffentlicht am 29. April 2026. Es ist also keine Überraschung — aber echte Arbeit, die auf eine Roadmap gehört und nicht in ein Notfall-Upgrade.
Ein Detail, das man vor jeder Planung prüfen sollte: Kyvernos Support-Matrix hinkt Kubernetes hinterher. v1.18 nennt als unterstützte Kubernetes-Versionen v1.33 bis v1.35 — also nicht 1.36, das Release, in dem MutatingAdmissionPolicy GA wurde. Andere Versionen „können funktionieren, sind aber nicht getestet“. Hinzu kommen rund drei Monate Patch-Support pro Minor-Release; die Upgrade-Taktung ist damit schneller, als viele Teams annehmen.
Der Vorteil: Die Migration bringt dich zu CEL, derselben Sprache wie in den eingebauten Policies. Bei manchem, was du migrierst, wirst du feststellen, dass du es ersatzlos löschen und nativ ausdrücken kannst.
Wie „gut“ aussieht
- Einfache Admission-Regeln liegen in eingebauten
ValidatingAdmissionPolicy-Objekten, ganz ohne Controller - Jede neue Regel startet als
WarnoderAuditund wird bewusst hochgestuft - Genau ein Policy-Controller ist installiert, und zwar für benannte Fähigkeiten, die du begründen kannst — Generierung, Image-Prüfung, Reports
kube-systemund der Namespace des Controllers sind von blockierenden Webhooks ausgenommen- Jemand kann „Was verstößt gerade gegen diese Policy?“ beantworten, ohne ein Skript zu schreiben
- Policies liegen in Git und laufen durch denselben Review-Pfad wie alles andere — das Platform-Engineering-Argument, angewandt auf Leitplanken
Das Fazit
Der interessante Vergleich lautet 2026 nicht OPA gegen Kyverno. Er lautet eingebaute Policies gegen alles andere.
Kubernetes validiert und mutiert inzwischen nativ, im Prozess, in CEL, mit Type Checking und Beobachtungsmodus — und das deckt den Großteil dessen ab, was die meisten Cluster erzwingen, ohne einen Webhook in den Anfragepfad zu setzen.
Was übrig bleibt, ist eine echte, aber engere Frage. Kyverno, wenn der Cluster Ressourcen erzeugen, Image-Signaturen prüfen oder berichten soll, was bereits kaputt ist. OPA, wenn Policies über Kubernetes hinausreichen müssen und eine Sprache überall den Aufwand für Rego wert ist.
Fang mit dem an, was ohnehin im Cluster steckt. Ergänze einen Controller, wenn du die Fähigkeit benennen kannst, für die du ihn holst — und wenn die Antwort nicht lautet: „Weil wir das immer so installiert haben.“
Dasselbe Prinzip zieht sich durch Secure-by-default-GKE: Die Kontrolle, die funktioniert, ist die mit der geringsten Mechanik zwischen Regel und Durchsetzung.




Aus der Community
Diskussion im Fediverse
Antworten von Mastodon und Bluesky — direkt aus dem offenen Netz, ohne Tracking.
Antworten werden geladen …
Noch keine Antworten. Starte die Diskussion:
Antworten konnten gerade nicht geladen werden.