Admission Chain
Before any object reaches storage, what gets a say in whether it is allowed and how it looks? Each request runs a gauntlet inside the API: authenticated, authorized, optionally rewritten, checked against the schema, and validated one last time before the write commits. The mutating and validating steps are where Kyverno, OPA Gatekeeper or a sidecar injector plugs in. A slow webhook stalls every write it matches, and failurePolicy decides whether it then fails.
Play the animation 5 steps, animated, best on a wide screen
Admission Chain, step by step
-
Already done, and not admission at all. Admission runs after authentication, so every caller has an identity, even system:anonymous. Authorizers run in configured order, commonly Node then RBAC, and the first to allow or to deny ends it, so no later one runs. Nothing allowing it means 403.
Play from step 1 -
Pluggable plus built-in. Always-on mutating plugins like ServiceAccount, LimitRanger and DefaultTolerationSeconds rewrite the Pod here, MutatingAdmissionPolicy runs CEL mutations in process, and MutatingWebhookConfiguration adds external policy webhooks (Kyverno, OPA Gatekeeper, sidecar injectors) on top, all before validation. Their failurePolicy decides whether a timeout blocks the write.
Play from step 2 -
Built-in. The API validates the mutated object for its kind, so a missing required field or a value outside its allowed range fails here, before any validating webhook runs.
Play from step 3 -
Pluggable plus built-in. LimitRanger is back to check min and max, ValidatingAdmissionPolicy runs in process, validating webhooks call out over HTTPS, and ResourceQuota runs after all of them. None may mutate, and any deny aborts the request. See the ResourceQuota and LimitRange card.
Play from step 4 -
Built-in. The API writes the final object to ETCD via Raft. Once ETCD commits, the API returns HTTP 201 Created to the client and every watch that matches the new Pod receives an ADDED event so informers can update their caches.
Play from step 5