Skip to content
advanced Phase 7 · Security

Admission Controllers

Build custom admission controllers and webhooks for policy enforcement.

1h
0 problems
Topic Progress 0%

The Request Pipeline Stage

The Request Pipeline Stage

Admission runs after authentication and authorization, inside the API server, in two passes:

  1. Mutating admission — webhooks and built-ins may alter the object (defaults, rewrites, injection).
  2. Validating admission — webhooks and built-ins accept or reject; rejection returns a 4xx to the caller.

Built-ins already cover a lot: NamespaceLifecycle, ServiceAccount, ResourceQuota, PodSecurity, and LimitRanger (per-namespace default limits and requests). The active set comes from the API server's --enable-admission-plugins configuration.

Mutating webhooks can be reinvoked (reinvocationPolicy: IfNeeded) when a later webhook changes the object again — the mechanism behind sidecar injection ordering.

A Validating Webhook

A Validating Webhook

apiVersion: admissionregistration.k8s.io/v1
kind: ValidatingWebhookConfiguration
metadata: { name: require-limits }
webhooks:
- name: limits.example.com
  clientConfig:
    service: { name: policy-svc, namespace: policy, path: /validate }
    caBundle: <base64 CA>
  rules:
  - apiGroups: [""]
    apiVersions: ["v1"]
    resources: ["pods"]
    operations: [CREATE, UPDATE]
  failurePolicy: Fail
  sideEffects: None
  admissionReviewVersions: ["v1"]
  namespaceSelector:
    matchExpressions:
    - { key: policy, operator: NotIn, values: [skip] }

failurePolicy: Fail blocks the API call when your webhook is down — right for critical policy, wrong for anything nonessential. namespaceSelector scopes which namespaces are subject to the rule, and sideEffects: None must be honest, including during dry-run requests.

Pitfalls and Interview Angles

Pitfalls and Interview Angles

Pitfall 1 — deleting your own escape hatch. A Fail-policy webhook guarding its own namespace deadlocks the cluster when the controller breaks. Exclude the policy namespace with a selector and keep a break-glass path (a kubeconfig with admission bypass for emergencies).

Pitfall 2 — timeouts under load. The default timeout is 10 seconds; a slow webhook under API load produces sporadic request failures across the cluster. Cache decisions, keep the webhook fast, and monitor latency.

Interview-ready: walk auth → mutation → validation, name two built-in plugins, then reason through design choices — failurePolicy versus availability, selector-based scoping during rollout, and how mutating webhooks implement injection with possible reinvocation.

Quiz

1. In what order do admission phases run?

Question 1 options

2. What happens when a failurePolicy: Fail webhook is unreachable?

Question 2 options

3. Which built-in plugin applies per-namespace default resource limits?

Question 3 options

Flashcards

Question

Mutating vs validating admission

Answer

Mutating may rewrite the object; validating accepts or rejects the final form.

Question

failurePolicy choice

Answer

Fail = deny when webhook is down (critical policy); Ignore = allow (nonessential checks).

Question

reinvocationPolicy: IfNeeded

Answer

Lets a mutating webhook re-run after later mutations — used for injection ordering.

Question

Lockout prevention

Answer

namespaceSelector excluding the policy namespace + a break-glass kubeconfig path.

Revision Notes

Key Takeaways

  • 1. Admission sits between authorization and persistence, in mutate-then-validate order
  • 2. failurePolicy is an availability decision as much as a security one
  • 3. Scope webhooks with selectors and keep timeouts tight

Interview Tips

  • • Name two built-in admission plugins and what they enforce
  • • For custom policy, discuss failurePolicy, timeouts, and dry-run side effects

Cheat Sheet

Pipeline: auth → RBAC → mutate → validate → etcd. Webhooks: failurePolicy Fail/Ignore, sideEffects, namespaceSelector, 10s timeout; exclude your own namespace.

Continue Learning