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 latest tag.

Some built-in controllers do both jobs. A rejection from any controller stops the entire request.

Built-In Controllers

ControllerJob
NamespaceLifecycleBlocks new objects in a terminating or missing namespace
LimitRangerApplies default requests and limits, and enforces minimum and maximum values
ResourceQuotaRejects requests that exceed namespace quotas
ServiceAccountAttaches the default service account to pods
DefaultStorageClassAssigns a storage class to claims that omit one
PodSecurityEnforces 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.

ToolPolicy languageStrength
KyvernoYAMLEasy for Kubernetes users; supports mutate, validate, and generate
OPA GatekeeperRegoPowerful, general-purpose policy language
ValidatingAdmissionPolicyCELBuilt 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 latest image tag.

Rolling Out Policies Safely

  1. Begin in audit or warn mode. Violations appear in logs and warnings without blocking anyone.
  2. Review the findings with application teams and fix workloads.
  3. Switch to deny mode one namespace at a time.
  4. 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.