Where Kubernetes Enforces Your Rules
Summary
- Admission control is the stage in the Kubernetes API request path where the API server calls out to policy logic before an object is persisted to etcd.
- Insight: RBAC answers "may this identity touch this resource?"; admission answers "is this specific object allowed, and should it be changed first?"
- Key Concepts: mutating admission rewrites objects, validating admission accepts or rejects them, webhooks are the extensible plug-in points, and ValidatingAdmissionPolicy runs CEL in-process.
- When to Use: enforce org-wide guardrails (require limits, block
:latest, mandate labels) that no individual deployment author can bypass. - Limitations/Trade-offs: webhooks add latency and a failure mode to every write; a badly configured
failurePolicycan wedge the cluster. - Related Topics: Kyverno, OPA Gatekeeper, Pod Security Admission, and policy testing in CI.
Foundations
Every write to the Kubernetes API travels a fixed pipeline before it lands in etcd.
The order is: authentication, then authorization (RBAC), then mutating admission, then object schema validation, then validating admission, then persistence.
Admission control is the last programmable gate. Once an object passes it, the object is stored and controllers act on it.
Think of RBAC as the door lock and admission as the inspector standing just inside the door.
RBAC decides whether the caller is allowed to create a Pod at all. Admission decides whether this Pod, with these images and settings, is acceptable.
That distinction matters because RBAC cannot see inside the object. It cannot say "you may create Pods, but only non-root ones." Admission can.
Mechanics & Interactions
There are two kinds of admission logic: built-in controllers compiled into the API server, and external plug-ins you configure.
Built-in controllers include NamespaceLifecycle, LimitRanger, ResourceQuota, PodSecurity, and DefaultStorageClass. They ship with the API server and are toggled by the cluster operator.
The extensible surface is the two webhook objects: MutatingWebhookConfiguration and ValidatingWebhookConfiguration.
A webhook configuration tells the API server which resources and operations to intercept, and which HTTPS endpoint to call with an AdmissionReview request.
Mutating webhooks run first, in sequence. Each can patch the incoming object using a JSONPatch returned in the AdmissionReview response.
Validating webhooks run after mutation and after schema validation. They can only allow or deny; they cannot change the object.
Both phases run inside the API server request, synchronously, so the endpoint must respond within the configured timeoutSeconds (max 30, commonly set to 5-10).
The failurePolicy field decides what happens when the webhook is unreachable or times out. Fail rejects the request; Ignore lets it through.
For newer clusters, ValidatingAdmissionPolicy and MutatingAdmissionPolicy let you express rules in CEL that the API server evaluates in-process, with no external service.
CEL policies remove the network hop and the availability risk of an external webhook, at the cost of a more limited expression language than a full policy engine.
Policy engines like Kyverno and OPA Gatekeeper are themselves deployed as validating and mutating webhooks. They give you a higher-level authoring model on top of the raw webhook mechanism.
Advanced Considerations & Applications
Ordering is subtle. Mutating webhooks can conflict, and a later mutation can undo an earlier one, so keep mutating rules few and independent.
Reinvocation matters too. If any mutating webhook changes the object, the API server may re-run mutating webhooks marked reinvocationPolicy: IfNeeded so they see the final state.
Scope your webhooks tightly. Match only the apiGroups, resources, and operations you truly need, and use namespaceSelector or objectSelector to exclude system namespaces.
A webhook that matches everything with failurePolicy: Fail and no exclusions is the classic way to lock yourself out during an outage of the webhook Pod.
For control-plane safety, always exclude kube-system and the namespace hosting the policy engine itself, so the engine can be scheduled even when it is down.
Latency compounds. Every matching write pays the round trip, so a slow webhook shows up as sluggish kubectl apply and slow controller reconciliation.
Prefer CEL ValidatingAdmissionPolicy for simple, high-volume checks and reserve external engines for complex logic like cross-object lookups and generation of new resources.
Common Misconceptions
"Admission control replaces RBAC." No. RBAC gates identity and verbs; admission inspects object content. You need both, and RBAC runs first.
"Webhooks can retroactively fix existing objects." No. Admission only runs on writes going forward. Existing objects are unaffected until they are next modified. Use a background scan or kyverno background reports for those.
"A validating webhook can change the object." No. Only mutating webhooks patch objects. Validating webhooks strictly allow or deny.
"Docker Engine enforces this on the node." No. Admission is an API server concept. On nodes, containerd via the CRI runs the pods; Docker is not in the cluster runtime path.
"failurePolicy: Ignore is always safer." It is safer for availability but weaker for security, because writes slip through when the policy engine is down. Choose per rule.
FAQs
What is the difference between admission and Pod Security Admission? Pod Security Admission is a specific built-in validating admission controller that enforces the Pod Security Standards. It is one consumer of the admission mechanism.
Do webhooks see updates or only creates? Both, if you list UPDATE in the webhook's operations. You choose which verbs to intercept.
Can I mutate and validate in the same policy? With external engines, yes - Kyverno has mutate and validate rules. In the built-in CEL path they are separate objects: MutatingAdmissionPolicy and ValidatingAdmissionPolicy.
Where do I see admission rejections? In the API server response to the client (the kubectl error), and in API server audit logs. Engines also emit events and PolicyReport objects.
Is CEL admission GA? ValidatingAdmissionPolicy is GA in current releases; treat MutatingAdmissionPolicy as newer and verify its stability for your pinned minor.
Does admission slow down reads? No. Admission only runs on writes (create, update, delete, connect). Reads bypass it entirely.
Related
Stack versions: This page was written for Kubernetes 1.36.2, Docker Engine 29.6.1 (BuildKit default), containerd (CRI runtime on nodes), Helm 3, Compose v2, Argo CD (latest - verify at build), and Gateway API (GA - verify controller support at build).