Mutating admission webhooks run first and can change an object. After modifications are done and the API server has validated the object, validating webhooks run and can reject it. If your check needs to see the final object, make it a validating webhook, because objects can change after a mutating webhook has seen them.
Where admission sits
A request to the Kubernetes API passes TLS, then authentication, then authorization, then admission control, then validation and storage. Admission controllers act on requests that create, modify, delete or connect to an object. They do not act on plain reads.
The docs add one rule that matters for security: unlike authentication and authorization modules, if any admission controller rejects, the request is rejected immediately.
Mutating webhooks
Mutating webhooks can modify objects, for example to enforce custom defaults. A typical use is injecting a sidecar or setting a default field.
Security consequence: anything a mutating webhook adds or changes is not guaranteed to have been checked by a validating rule that ran earlier, because there is no earlier validating pass. That is why ordering matters.
Validating webhooks
Validating webhooks run after all mutation and schema validation. They can accept or reject, and they do not change the object. This is where rules like "no privileged containers" and "images must come from our registry" should live, since they then see the final form.
A common mistake
Putting a policy check in a mutating webhook because it also needs to default a field. The check may run before another mutating webhook changes the same field. Split it: let the mutator set defaults, and let a separate validator enforce the rule.
What this means for your design
- Enforce security rules in validating webhooks or validating admission policies.
- Keep mutating webhooks few and well understood, and list what each one changes.
- Remember that webhooks are part of the control plane. The docs say they should be written and deployed with great caution.
- Protect who can edit the webhook configurations. The RBAC good practices page says users who control validatingwebhookconfigurations or mutatingwebhookconfigurations control webhooks that can read any object admitted to the cluster, and mutating ones can also change admitted objects.
A related option
For simple rules, a declarative validating policy written in CEL avoids running a webhook server at all. Our post on rolling out admission policy with Warn and Audit first shows the staged approach.
Safeguard checks manifests earlier, in pull requests and pipelines, through policies and gates, so many problems never reach admission. It does not run admission webhooks for your cluster.
Testing the order
Create a test object that the mutator should change, and one that the validator should reject, then try the combination. If the mutator fixes the thing the validator would have rejected, you now know the rule only checks the final shape. If that is not what you want, tighten the validator.
Quick check
Should my image policy be a mutating webhook?
Usually no. Put enforcement in a validating webhook or policy so that it sees the object after all mutation.
Sources
- Dynamic Admission Control, Kubernetes docs
- Controlling Access to the Kubernetes API, Kubernetes docs
- Role Based Access Control Good Practices, Kubernetes docs
Last reviewed: 19 October 2026.