Pod Security Standards and admission control: privileged, baseline and restricted
In short: Pod Security Standards define three profiles for how much power a pod may have. The built-in Pod Security admission controller enforces them per namespace using labels, in enforce, audit or warn mode. Most application namespaces should run at restricted, with policy engines adding organisation-specific rules.
Why control pod settings
A pod specification can ask for dangerous things: privileged mode, the host network, host paths, running as root, extra Linux capabilities. Anyone allowed to create pods could use these to break out to the node. Admission control is the stage where the API server checks new objects against policy and rejects those that break the rules.
Older clusters used PodSecurityPolicy, which was removed in Kubernetes 1.25. Its replacement is the built-in Pod Security admission (PSA) controller, which enforces the Pod Security Standards.
The three standards
| Profile | Intended for | Examples of what it blocks |
|---|---|---|
| Privileged | Trusted system components such as CNI or storage drivers | Nothing |
| Baseline | Most workloads with minimal change | Privileged containers, host network, PID and IPC, hostPath volumes, adding dangerous capabilities |
| Restricted | Security-sensitive and general application workloads | Everything in baseline, plus running as root, privilege escalation, capabilities other than NET_BIND_SERVICE, missing seccomp profile |
Enforcing with namespace labels
PSA is configured by labelling namespaces. Each label sets a mode: enforce rejects violating pods, audit records violations in the audit log, and warn shows a warning to the user.
kubectl label namespace shop \
pod-security.kubernetes.io/enforce=restricted \
pod-security.kubernetes.io/enforce-version=latest \
pod-security.kubernetes.io/warn=restricted \
pod-security.kubernetes.io/audit=restricted
A pod that meets the restricted standard includes a security context like this:
securityContext:
runAsNonRoot: true
seccompProfile:
type: RuntimeDefault
containers:
- name: api
image: registry.example.com/shop/api@sha256:<digest>
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"]
(readOnlyRootFilesystem is not required by the restricted profile, but it is good practice.)
Rolling it out and going further
- Label every namespace with
warnandauditat restricted to see what would fail. - Fix workloads: add non-root users, drop capabilities, set seccomp.
- Switch application namespaces to
enforce=restricted; use baseline where a documented exception is needed. - Keep privileged only for system namespaces, and limit who can create pods there.
- Add a policy engine for rules PSA does not cover.
Policy engines such as Kyverno and OPA Gatekeeper, or the built-in ValidatingAdmissionPolicy using CEL expressions, can enforce organisation rules: images only from your registry, signed images, required labels, resource limits present, no latest tags.
Tip: remember that PSA checks pods, but pods are usually created by Deployments. Warnings appear when you apply the Deployment, while rejections happen when its ReplicaSet tries to create pods, so check events if replicas stay at zero.
Practice
Which Pod Security Standard would block a pod that runs as root but is otherwise harmless?
What is the difference between enforce, audit and warn modes?
A Deployment applies without error but no pods appear. What might PSA have done?
Key takeaways
- Admission control checks objects after RBAC and before storage.
- Pod Security Standards: privileged, baseline and restricted.
- Pod Security admission enforces them per namespace with labels.
- Use warn and audit first, then enforce restricted for apps.
- Policy engines add rules such as trusted registries and signatures.
Original content written by Mohamed Fayas for FM TecHub. © 2026 FM TecHub. You're welcome to share a link to this page; please don't copy the text elsewhere without permission.