Kubernetes Admission Controllers
Authentication proves who sends a request, and authorization decides whether that person may perform the action. A third checkpoint exists after both: admission control. Admission controllers inspect, change, or reject requests that pass the first two checks, and they enforce rules that RBAC cannot express.
The Building Security Analogy
A visitor shows an ID at the front desk (authentication). The guard confirms the visitor holds an appointment (authorization). A final inspector checks the visitor's bag, adds a visitor sticker, and refuses anyone carrying forbidden items (admission). RBAC cannot say "no containers running as root". Admission can.
The Request Journey
kubectl apply
│
▼
┌────────────────┐
│ Authentication │ Who are you?
└───────┬────────┘
▼
┌────────────────┐
│ Authorization │ May you do this?
└───────┬────────┘
▼
┌────────────────┐
│ Mutating │ Modify the request (add defaults)
│ admission │
└───────┬────────┘
▼
┌────────────────┐
│ Schema │ Check object structure
│ validation │
└───────┬────────┘
▼
┌────────────────┐
│ Validating │ Approve or reject
│ admission │
└───────┬────────┘
▼
Saved in etcd
Mutating controllers run first, so validating controllers judge the final version of the object.
Two Types of Admission Controllers
- Mutating controllers change the object. Example: inject a sidecar container or add default labels.
- Validating controllers only accept or reject. Example: block pods that use the
latesttag.
Some built-in controllers do both jobs. A rejection from any controller stops the entire request.
Built-In Controllers
| Controller | Job |
|---|---|
| NamespaceLifecycle | Blocks new objects in a terminating or missing namespace |
| LimitRanger | Applies default requests and limits, and enforces minimum and maximum values |
| ResourceQuota | Rejects requests that exceed namespace quotas |
| ServiceAccount | Attaches the default service account to pods |
| DefaultStorageClass | Assigns a storage class to claims that omit one |
| PodSecurity | Enforces Pod Security Standards per namespace |
Cluster administrators enable or disable these through API server flags. Managed services handle the setup.
Admission Webhooks
Webhooks extend admission with your own code. The API server sends each matching request to a web service as an AdmissionReview. The service replies with allow, deny, or a patch.
API Server ──AdmissionReview──▶ Webhook service
◀──── allow / deny / patch ─────
Webhooks carry risk. A slow or offline webhook can block every deployment in the cluster when its failure policy is set to Fail. Teams run webhooks with several replicas and exclude system namespaces from them.
ValidatingAdmissionPolicy
Kubernetes includes a built-in policy engine that needs no webhook server. Rules use the Common Expression Language (CEL) and run inside the API server, which keeps them fast and reliable. The feature is stable in Kubernetes 1.30 and later.
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicy
metadata:
name: replica-limit
spec:
failurePolicy: Fail
matchConstraints:
resourceRules:
- apiGroups: ["apps"]
apiVersions: ["v1"]
operations: ["CREATE", "UPDATE"]
resources: ["deployments"]
validations:
- expression: "object.spec.replicas <= 5"
message: "Deployments may run at most 5 replicas."
A binding activates the policy and defines the action.
apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingAdmissionPolicyBinding
metadata:
name: replica-limit-binding
spec:
policyName: replica-limit
validationActions: ["Deny"]
matchResources:
namespaceSelector:
matchLabels:
env: dev
With this pair, a deployment in a namespace labeled env=dev that asks for ten replicas gets rejected with the message above.
Policy Engines
Policy engines package admission logic into readable rules so teams avoid writing webhook code.
| Tool | Policy language | Strength |
|---|---|---|
| Kyverno | YAML | Easy for Kubernetes users; supports mutate, validate, and generate |
| OPA Gatekeeper | Rego | Powerful, general-purpose policy language |
| ValidatingAdmissionPolicy | CEL | Built in, no extra software |
Common Policy Ideas
- Require resource requests and limits on every container.
- Block images from unapproved registries.
- Reject privileged containers and host networking.
- Require owner and cost-center labels on every namespace.
- Deny the
latestimage tag.
Rolling Out Policies Safely
- Begin in audit or warn mode. Violations appear in logs and warnings without blocking anyone.
- Review the findings with application teams and fix workloads.
- Switch to deny mode one namespace at a time.
- Exempt system namespaces such as
kube-system.
Key Points
- Admission runs after authentication and authorization.
- Mutating controllers change requests; validating controllers approve or reject them.
- ValidatingAdmissionPolicy, Kyverno, and Gatekeeper turn rules into automatic guardrails.
- Audit mode first prevents surprise outages.
