Validating Admission Policy (K8s 1.26+) — native validation without webhook (built-in).
Advantages: no sidecar, no network dependency, works even when control plane is down.
Example (require labels):
1apiVersion: admissionregistration.k8s.io/v12kind: ValidatingAdmissionPolicy3metadata:4 name: "require-team-label"5spec:6 failurePolicy: Fail7 matchConstraints:8 resourceRules:9 - apiGroups: ["apps"]10 apiVersions: ["v1"]11 operations: ["CREATE", "UPDATE"]12 resources: ["deployments", "statefulsets"]13 validations:14 - expression: "has(object.metadata.labels) && has(object.metadata.labels.team)"15 message: "Label team is required"
Namespace binding:
1apiVersion: admissionregistration.k8s.io/v12kind: ValidatingAdmissionPolicyBinding3metadata:4 name: "require-team-binding"5spec:6 policyName: "require-team-label"7 matchResources:8 namespaceSelector:9 matchLabels:10 pod-security.kubernetes.io/enforce: restricted
Complex rule (CEL):
1validations:2 - expression: "object.spec.replicas <= 10"3 message: "Maximum 10 replicas"4 - expression: |5 object.spec.template.spec.containers.all(c,6 c.image.startsWith("ghcr.io/myorg/")7 )8 message: "Only images from ghcr.io/myorg/"9 - expression: |10 object.spec.template.spec.containers.all(c,11 has(c.resources.limits) && has(c.resources.requests)12 )13 message: "resources.limits and resources.requests are required"
Validating Admission Policy vs OPA/Kyverno: