Pod Security Standards (CKS)
Privileged, baseline, restricted: enforce a floor for every pod in a namespace.
An interactive Kubernetes lesson: 20 steps, about 30 minutes, on a live simulation in your browser.
Jane is a developer. RBAC gives her team edit in the namespace prod, where the shop's web runs. That lets her create pods, which sounds harmless.
Her laptop is stolen with a valid kubeconfig on it. The thief applies one manifest: a pod that is privileged, shares the host's process namespace, and mounts the node's root filesystem at /host.
What you will learn
Any pod you like
- "Create pods" means root on a node: RBAC decides who may create a pod. It says nothing about what is in the pod. Without a second check, create pods is root on a node.
- Three levels, chosen by a label: Three fixed levels: privileged allows all, baseline blocks known escapes, restricted also demands hardening. A namespace label picks one.
- Enforce baseline: Pod Security Admission judges requests, not running pods. Whatever was already there stays until something recreates it.
What restricted demands
- A plain pod under restricted: Baseline is a list of things you must not set. Restricted adds a list of things you must set.
- Fix it one violation at a time
- Two more, and it is admitted: Restricted in four fields: allowPrivilegeEscalation false, drop ALL, runAsNonRoot true, seccompProfile RuntimeDefault.
- Break it: admitted, not running: Admission checks what the manifest says. The kubelet checks what the image does. runAsNonRoot is a promise the image has to keep.
- Drill: enforce a level
Deployments fail quietly
- A Deployment with no pods: Enforce rejects Pods, not Deployments. The Deployment is accepted and its ReplicaSet is refused each pod.
- The reason is in the ReplicaSet: 0 pods and no error: describe the ReplicaSet. FailedCreate events hold the admission message.
- Break it: the pod that cannot come back: Enforcing on a namespace with old workloads breaks nothing today. It breaks each pod the next time it is replaced.
Rolling it out safely
- Warn and audit before you enforce: enforce rejects, warn tells the user, audit tells the log. Run warn and audit at the level you want next, and read what they say.
- Preview the enforce label: kubectl label --dry-run=server with an enforce label lists the existing pods that would fail, and changes nothing.
- Pin the version: Pin enforce-version to a release you tested. Keep warn and audit on latest, so an upgrade warns before it rejects.
- Drill: preview before you enforce
Exemptions and limits
- Some pods must be privileged: Separate privileged system pods by namespace and label that namespace privileged. Everything else gets baseline or restricted.
- What the standards cannot say: Pod Security Standards are three fixed answers to one question: how privileged is this pod. Any other rule needs a policy engine.
- Where policy engines start: Use Pod Security Standards for privilege. Use ValidatingAdmissionPolicy, Kyverno or Gatekeeper for rules that are yours: registries, labels, limits.
Recap & playground
- Cheat sheet
- Playground