Kubernetes admission webhook operations
Admission webhooks let you intercept requests to the Kubernetes API server after authentication and authorization but before persistence. A MutatingWebhookConfiguration can change objects; a ValidatingWebhookConfiguration can only allow or deny them. Both are configured through a shared set of fields — rules, failurePolicy, sideEffects, namespaceSelector, timeoutSeconds, and more. This reference explains each field and its allowed values.
Filter the fields below to find the right key and what its values mean.
How it works
When a request arrives, the API server evaluates each configured webhook whose rules (operations, apiGroups, apiVersions, resources) and selectors match. Mutating webhooks run first, in an order that may re-invoke them per reinvocationPolicy; each returns an admission response that may include a base64-encoded JSONPatch. After all mutations, validating webhooks run against the final object and can only return allowed true/false.
The webhook is reached over TLS at the clientConfig (a service reference or a url), and the server trusts it via the caBundle. If the call fails, failurePolicy decides between rejecting (Fail) or admitting (Ignore) the request. sideEffects governs dry-run behavior, timeoutSeconds (1–30) bounds the call, and matchPolicy (Exact or Equivalent) controls how aliased API versions are matched. admissionReviewVersions lists the AdmissionReview API versions the webhook understands.
Tips and examples
A minimal validating webhook rule:
webhooks:
- name: policy.example.com
rules:
- operations: ["CREATE", "UPDATE"]
apiGroups: ["apps"]
apiVersions: ["v1"]
resources: ["deployments"]
failurePolicy: Fail
sideEffects: None
matchPolicy: Equivalent
admissionReviewVersions: ["v1"]
timeoutSeconds: 5
Always exclude the kube-system namespace and the webhook’s own namespace via namespaceSelector to avoid a deadlock where the webhook blocks the pods that serve it. Use failurePolicy: Ignore plus a short timeoutSeconds for non-critical webhooks so an outage cannot freeze the control plane, and make mutating webhooks idempotent when reinvocationPolicy is IfNeeded.
Key fields and their trade-offs
failurePolicy
Fail (fail closed) is the right choice for security-enforcing webhooks: if the webhook cannot be reached, the request is denied. This prevents objects that violate policy from slipping in during a webhook outage, but it also means a webhook crash can block the control plane. Use it for mutation or validation that is correctness-critical.
Ignore (fail open) is appropriate for non-critical webhooks — adding default labels, injecting sidecars for optional observability, or annotating objects with metadata. An outage silently skips the webhook rather than blocking operations. Pair it with a very short timeoutSeconds (2–3 seconds) to minimize the added latency on every API call when the webhook is slow.
sideEffects
Kubernetes distinguishes between webhooks that only read the object being admitted (None) and those that mutate external state (Some or Unknown). Dry-run requests are only forwarded to webhooks marked None or NoneOnDryRun, because an external write during a dry run would be incorrect. Set sideEffects: None for any webhook that only inspects or patches the in-flight object and does not call external APIs or write to a database.
namespaceSelector and objectSelector
namespaceSelector uses label selectors to restrict which namespaces trigger the webhook. The standard safety pattern is to label your webhook’s own namespace and the kube-system namespace with a skip label, then add a NotIn expression to namespaceSelector so the webhook never intercepts requests in namespaces that host the webhook server itself. Without this, a crash in the webhook’s namespace can prevent the pods from restarting, causing an unrecoverable deadlock.
objectSelector (Kubernetes 1.15+) filters on the object’s own labels, which is more efficient than checking everything and returning early in the webhook handler.
reinvocationPolicy (mutating only)
IfNeeded allows the API server to call your mutating webhook a second time if a later webhook in the same chain modifies the object. This lets your webhook react to changes made by others, but your webhook must be idempotent: running it twice on the same object must produce the same result as running it once. Never (the default) calls each mutating webhook at most once per admission.
Common operational mistakes
Not watching your webhook’s own TLS certificate. Admission webhooks require TLS, and if the serving certificate expires the webhook stops responding. Depending on failurePolicy, this either starts blocking all matching API calls or starts silently skipping them. Use cert-manager or another rotation mechanism and set alerts on certificate expiry.
Using a url clientConfig in production. The url form sends requests directly to an external endpoint, bypassing the cluster network. The service form routes through the cluster DNS and is the standard approach for webhooks running inside the cluster.
Too broad a rules match. Intercepting * operations on * resources in * apiGroups adds latency to every API call in the cluster. Scope rules precisely to the operations and resource types your webhook actually needs to examine.