Tools · Containers and Kubernetes security · 04 / 20
Pod Security Standards and Pod Security Admission: privileged, baseline, and restricted
Learn the three Pod Security Standards levels, apply them to namespaces with labels in enforce, audit, and warn modes, and roll out restricted without breaking deployments.
Three levels
Privileged applies no restrictions and is meant for trusted system workloads. Baseline blocks known privilege escalations: privileged containers, hostNetwork, hostPID, hostIPC, hostPath volumes, added dangerous capabilities, and host ports. Restricted adds hardening on top: containers must run as non-root, drop all capabilities, disallow privilege escalation, and use a RuntimeDefault or Localhost seccomp profile.
Pod Security Admission is the built-in controller that enforces these levels. It replaced PodSecurityPolicy, which was removed in Kubernetes 1.25.
Enforce, audit, warn
Each namespace can set a level per mode with labels. enforce rejects violating pods. audit records a violation annotation in the audit log. warn returns a warning to the client such as kubectl. A common rollout sets warn and audit to restricted while enforce stays at baseline, then raises enforce when warnings stop.
kubectl label ns shop \ pod-security.kubernetes.io/enforce=baseline \ pod-security.kubernetes.io/warn=restricted \ pod-security.kubernetes.io/audit=restricted
Lab: watch a pod get rejected
Label a test namespace with enforce=restricted and try to run a plain nginx pod. Read the error: it lists each failed check, such as allowPrivilegeEscalation, capabilities, runAsNonRoot, and seccompProfile. Use a server-side dry run against existing namespaces to preview the impact before labeling them.
kubectl create ns psa-lab kubectl label ns psa-lab pod-security.kubernetes.io/enforce=restricted kubectl -n psa-lab run web --image=nginx:1.27 kubectl label --dry-run=server --overwrite ns --all pod-security.kubernetes.io/enforce=baseline
Exceptions
System namespaces such as kube-system and some monitoring or CNI agents genuinely need privileged settings. Keep them in dedicated namespaces at the privileged level rather than weakening application namespaces. For finer-grained rules than the three levels, add a policy engine such as Kyverno or ValidatingAdmissionPolicy.
Diagram
What each level allows
Choose the strictest level the workload tolerates.
- Privileged
Anything. Only for trusted node agents.
- Baseline
Blocks privileged, host namespaces, hostPath, and dangerous capabilities.
- Restricted
Baseline plus non-root, drop ALL capabilities, no privilege escalation, seccomp required.
Check yourself
1. Which level requires containers to run as non-root and drop all capabilities?
2. Which mode returns a message to kubectl but still lets the pod run?
3. A pod mounts a hostPath volume. Which is the lowest level that rejects it?