Every mature Kubernetes platform ends up with guardrails: containers must not run as root, images must come from approved registries, every workload needs an owner label, and some defaults should be injected automatically. For years the standard way to enforce them was admission webhooks, separate services the API server calls on every relevant request. They work, but they're more infrastructure to run, they add latency, and a failing webhook can block deployments across a cluster.
Built-in policies, in CEL
ValidatingAdmissionPolicy reached general availability in Kubernetes 1.30. It lets you express validation rules declaratively in Common Expression Language (CEL), evaluated inside the API server, as an alternative to validating webhooks12. The GA announcement walks through replacing a webhook that enforces least-privilege security context settings with an equivalent policy1.
MutatingAdmissionPolicy does the same for changes. The documentation describes it as a declarative, in-process alternative to mutating webhooks, with mutations defined as an apply configuration merged using server-side apply rules, or as a JSON patch3. The feature gate list shows it moving through alpha and beta to stable in v1.364.
A policy is made of a policy resource, a binding that scopes where it applies, and optional parameters, so one policy can be reused with different settings per namespace or environment23.
Webhooks, built-in policies, or a policy engine
| Built-in CEL policies | Webhooks or policy engines | |
|---|---|---|
| Runs where | Inside the API server | Separate services the API server calls |
| Failure mode | No extra service to go down | Webhook outages can block or slow admission |
| Logic | CEL expressions over the request and parameters | Arbitrary code or rich policy languages |
| External calls | Not designed for them | Possible, for example image signature checks |
| Reporting | Basic | Often richer reports and policy libraries |
My rule of thumb: simple, high-volume guardrails move to built-in policies; checks that need external data or rich reporting stay in a policy engine.
The migration playbook
- Inventory webhooks and policies across clusters, including those installed by vendor charts, with their failure policies and timeouts.
- Classify each rule: expressible in CEL, needs external data, or needs complex logic.
- Write CEL equivalents for the first group, with test cases for allowed and rejected objects, kept in version control alongside your platform code.
- Roll out in audit or warn mode first, comparing results with the existing webhook before switching to deny.
- Use parameters and bindings to vary settings per environment instead of copying policies.
- Remove the old webhook only after the policy has matched its decisions in production for a period.
Every webhook you retire is one less service that can take down deployments at 2am. That operational simplicity is the main benefit, more than any feature.
Guardrails worth having on AI clusters
- GPU workloads must declare an owner, cost centre and priority class, so costs and preemption are traceable, supporting AI cost allocation.
- Model-serving pods must not run privileged and must come from approved registries.
- Namespaces holding regulated data must carry labels that other controls depend on, such as region or data class, as in UAE health data localisation.
- Training jobs must use the queueing and scheduling setup in Kubernetes gang scheduling rather than bypassing it.
How I can help
I design Kubernetes platforms with guardrails that are simple to operate, and review cluster security in technical due diligence. As a fractional CTO I can own the platform roadmap. Or analyse your challenge and bring the result to a call.
- 1Kubernetes 1.30: Validating Admission Policy is generally availableKubernetes blog · 24 Apr 2024
- 2Validating Admission PolicyKubernetes documentation
- 3Mutating Admission PolicyKubernetes documentation
- 4Feature gatesKubernetes documentation
- 5Common Expression Language in KubernetesKubernetes documentation