Introduction#
Pod Security Standards (PSS) are a concise, builtin framework in Kubernetes that let operators enforce least-privilege for pods at the namespace level. They provide three graded policies—Privileged, Baseline, and Restricted—so teams can progressively lock down workloads without heavy custom admission logic. Use PSS to reduce privilege escalation, host access, and unsafe syscalls.
The three levels and when to use them#
- Privileged: nearly no restrictions. Intended only for trusted system workloads that require node-level access (e.g., node exporters or CNI plugins). Use sparingly.
- Baseline: sensible defaults for general application workloads. It prevents obvious misconfigurations (privileged containers, hostPath abuse, host namespace sharing) while remaining compatible with most apps.
- Restricted: strict hardening for untrusted or security-critical workloads. It requires non-root containers, drops capabilities, enforces seccomp/AppArmor, and forbids host access patterns.
Recommendation: start with Baseline for most app namespaces, migrate offending pods to fix compatibility issues, then adopt Restricted for sensitive namespaces.
How Pod Security Admission (PSA) works#
PSA is the upstream admission controller that enforces PSS using namespace labels. Each namespace can be configured with three modes:
- warn: allow pods but emit warnings (useful to discover violations).
- audit: accept pods but record violations in audit logs.
- enforce: deny pod creation that violates the selected level.
A practical rollout pattern:
- Label namespaces with warn to discover violations.
- Fix violations (securityContext, capabilities, seccomp, runAsNonRoot).
- Move to audit for monitoring.
- Flip to enforce when the namespace is compliant.
Example namespace label to set Baseline in warn mode:
kubectl label --overwrite ns my-namespace \
pod-security.kubernetes.io/enforce=baseline \
pod-security.kubernetes.io/enforce-version=latest \
pod-security.kubernetes.io/warn=baseline \
pod-security.kubernetes.io/warn-version=latestCommon checks and fixes#
PSS focuses on fields in pod and container specs. Frequent violations and straightforward remediations:
- runAsNonRoot / runAsUser: ensure containers run as non-root. Fix: set USER in Dockerfile and add runAsNonRoot/runAsUser in Pod spec.
- allowPrivilegeEscalation: set to false to prevent setuid/setgid escalation.
- capabilities: drop ALL and only add what’s strictly necessary (prefer none).
- seccomp profile: require non-Unconfined seccomp; use RuntimeDefault.
- hostPath, hostNetwork, hostPID, hostPorts: remove or replace with secure alternatives (CSI volumes, ClusterIP services).
- readOnlyRootFilesystem: enable for immutable workloads and write data to volumes.
Operational tips#
- Integrate PSA checks into CI: run
kubectl apply --dry-run=serveror use admission-webhook test steps in PR pipelines. - Monitor metrics and audit logs (kube-apiserver exposes PSA metrics).
- Use tools like OPA/Gatekeeper, kube-bench, or kubescape to augment PSS with custom policies and compliance checks.
- Maintain an explicit exemption registry for components that must run privileged (documented and reviewed).
Conclusion#
Pod Security Standards give a pragmatic, Kubernetes-native path to least-privilege. Adopt Baseline widely, remediate violations iteratively, and enforce Restricted for high-risk workloads. Start by labeling a dev namespace with warn, fix the common violations (non-root, capability drops, seccomp), and graduate to enforce—this minimizes disruption while raising your cluster’s security posture.
Co-authored by Vishwakarma, Deeps 2nd Brain

