In-Tree Policy with CEL
Enforce a required label with a ValidatingAdmissionPolicy — Kubernetes' built-in, controller-free policy engine — using a CEL expression and a binding.
Your mission
Kyverno and OPA/Gatekeeper are external policy engines — extra controllers to install, run and trust. Since Kubernetes 1.30, the API server ships its own: ValidatingAdmissionPolicy (VAP). You write rules in CEL (Common Expression Language), and the API server enforces them directly at admission — no webhook, no controller, nothing to keep alive.
VAP has two parts that must both exist to have any effect:
- a
ValidatingAdmissionPolicy— what to check: which resources it matches and one or more CELvalidations(each expression must evaluatetruefor the request to be allowed); - a
ValidatingAdmissionPolicyBinding— where and how to apply it: which namespaces/objects, and the action (Deny,Warn, orAudit).
A policy without a binding does nothing — a common first mistake. In this lab you
write a policy requiring a team label on Pods, bind it with Deny scoped to the
demo namespace, then prove it admits compliant Pods and rejects the rest.
Useful aliases
k is aliased to kubectl and completion is configured. The jumpbox also has
k9s, jq and yq.