Lion Cipher Lab
Build a Kubernetes validating admission webhook from scratch (and fail closed)
- Cloud Security
- Advanced
- ~90 min
- Free · no account required
Why it matters
Every object that enters a Kubernetes cluster -- every Pod, every Deployment -- passes through ADMISSION CONTROL, a checkpoint inside the API server that can accept, reject, or mutate the request before it is ever written to storage. It is the single best place to enforce a security guardrail, because it stops a dangerous workload at creation time instead of hunting it down after it is running. Most teams rightly ADOPT a policy engine for this -- Kyverno, OPA Gatekeeper, or the built-in Pod Security Admission -- and you should know those cold. But if you have never written the thing…
What you'll learn
- what a Kubernetes admission controller is and where it sits in the API request path (authn -> authz -> admission -> etcd)
- reading the AdmissionReview request/response JSON: the request.uid you MUST echo, and the response allowed:true/false + status.message
- writing a tiny HTTPS validating webhook from scratch (Flask, ~50 lines) that enforces one clear Pod-security policy
- the policy itself: DENY any Pod that sets securityContext.privileged:true or omits runAsNonRoot:true
- minting a self-signed CA and a serving certificate with openssl, and wiring the CA into a webhook's caBundle so the API server trusts it
- authoring a ValidatingWebhookConfiguration: rules, clientConfig.caBundle, sideEffects:None, timeoutSeconds, admissionReviewVersions
- failurePolicy:Fail (fail CLOSED) vs Ignore (fail open), and why a namespaceSelector carve-out keeps you from bricking the cluster
- proving enforcement: a privileged pod is DENIED with your exact message; a compliant pod is ADMITTED
- the judgment of when to BUILD a webhook vs adopt Kyverno / OPA Gatekeeper / Pod Security Admission, and the modern in-tree ValidatingAdmissionPolicy (CEL)
Steps in this lab
- What admission control is, and where your webhook plugs in
- Stand up a free, local cluster with kind
- Read the contract: the AdmissionReview request and response
- Decide the policy: what counts as a dangerous Pod
- Write the webhook server from scratch (Flask, ~50 lines)
- Mint a self-signed CA and a serving certificate with openssl
- Deploy the webhook into the cluster with its cert
- Register the webhook -- and fail CLOSED without bricking the cluster
- Prove it: deny the privileged pod, admit the compliant one
- The judgment: build vs buy, fail-open vs fail-closed, and the modern answer