Skip to main content
This lab walks through creating and testing a sample mutating admission webhook that enforces non-root containers by default, and shows how validating admission checks interact with those mutations. You’ll:
  • Create a webhook namespace and TLS secret.
  • Deploy a webhook server and service.
  • Apply a MutatingWebhookConfiguration that injects runAsNonRoot: true and runAsUser: 1234 when a Pod has no security context.
  • Verify behavior across three Pod test cases: default (mutated), explicit override, and conflicting settings (rejected).
Keywords: Kubernetes admission controllers, mutating webhook, validating webhook, MutatingWebhookConfiguration, runAsNonRoot, TLS secret.
  1. Identify which admission controllers are mutating vs validating
  • NamespaceAutoProvision is a mutating admission controller (it creates or modifies resources, e.g., auto-creating a namespace).
  • namespace-exists (or similar) is a validating admission controller (it checks whether a namespace exists and rejects requests if validation fails).
Mutating webhooks are invoked first, and any changes they make are visible to subsequent validating webhooks. This ordering matters: a mutating webhook can add defaults that a validating webhook then evaluates.
Mutating admission webhooks run before validating admission webhooks. Any mutation applied by the mutating webhook is what validating webhooks will evaluate.
  1. Create the webhook namespace
Create the namespace webhook-demo:
Verify the new namespace:
  1. Create a TLS secret for the webhook server
A certificate and key were pre-generated. Create a TLS secret in webhook-demo using those files:
  1. Deploy the webhook server Deployment and Service
Apply the provided Deployment and Service manifests:
Confirm the repository manifests are present:
  1. Inspect and apply the provided MutatingWebhookConfiguration
The sample MutatingWebhookConfiguration targets pod CREATE operations and routes to the webhook-server service at /mutate. The important rule and clientConfig look like:
Apply the configuration:
The example manifest may use admissionregistration.k8s.io/v1beta1. On modern Kubernetes clusters, update your manifests to admissionregistration.k8s.io/v1 to avoid deprecation and compatibility issues. See the Kubernetes admission webhook docs for details.
  1. What the webhook does (behavior summary)
The demo mutating webhook enforces non-root defaults and applies validation rules:
  • If a Pod is created without securityContext settings (runAsNonRoot / runAsUser), the webhook mutates the Pod spec to set:
    • runAsNonRoot: true
    • runAsUser: 1234
  • If a Pod explicitly sets runAsNonRoot: false (allow root), the webhook respects that explicit setting and does not override it.
  • If a Pod has conflicting settings (e.g., runAsNonRoot: true and runAsUser: 0), the webhook rejects the request because the configuration is logically inconsistent.
  1. Test 1 — Pod with no securityContext (mutating webhook applies defaults)
Pod manifest pod-with-defaults.yaml (no securityContext):
Apply it:
Inspect the pod to see the mutation applied:
Expected effective values:
  • runAsNonRoot: true
  • runAsUser: 1234
  1. Test 2 — Pod with explicit override allowing root
Pod manifest pod-with-override.yaml explicitly allows root:
Apply it:
Because the Pod explicitly sets runAsNonRoot: false, the mutating webhook does not inject defaults—explicit configuration wins. Behavior is the same with or without the webhook for this case.
  1. Test 3 — Pod with conflicting settings (rejected by validation)
Pod manifest pod-with-conflict.yaml intentionally conflicts:
Apply it; the webhook should reject this because runAsNonRoot: true conflicts with runAsUser: 0:
The webhook correctly validated and denied the request due to conflicting security settings. Tests and expected outcomes Summary
  • Mutating admission webhooks can inject secure defaults (e.g., non-root UID and runAsNonRoot: true) to resources that omit them.
  • Validating admission webhooks (or validation logic within the webhook) detect and reject logically inconsistent or insecure configurations.
  • Always use admissionregistration.k8s.io/v1 for admission webhook configuration manifests on modern Kubernetes clusters to avoid deprecation issues.
Links and references
When developing or deploying admission webhooks, remember to:
  • Keep TLS certificates current and load the CA bundle into your webhook configuration.
  • Test webhook ordering: mutating first, validating second.
  • Use admissionregistration.k8s.io/v1 manifests for compatibility with recent Kubernetes versions.

Watch Video