Pod Security Admission (PSA)
[!WARNING] PodSecurityPolicy (PSP) has been removed in Kubernetes v1.25+. If you are still using PSPs, you must migrate to Pod Security Admission (PSA) immediately.
Kubernetes is insecure by default. A standard Pod can mount the host filesystem, run as root, and access the host network. Pod Security Admission (PSA) is the built-in mechanism to restrict what Pods can do, based on clearly defined standards.
1. The 3 Security Standards
PSA defines three cumulative standards. You don’t write complex policies anymore; you just pick a level.
1. Privileged
Unrestricted.
- Can do anything (HostPath, HostNetwork, Capabilities).
- Use for: System agents (CNI, CSI), Node components.
2. Baseline
Minimally restrictive.
- Prevents known privilege escalations.
- Allows standard configurations.
- Use for: Legacy apps, non-critical services.
3. Restricted
Highly secure.
- Follows best practices.
- Requires: `runAsNonRoot`, dropping capabilities.
- Use for: Web apps, microservices (90% of workloads).
2. Interactive: Standard Checker
Which standard does your Pod Spec fall into? Toggle the settings to see.
Pod Configuration
Compliance Result
Excellent! This Pod follows all best practices and can run in the most secure namespaces.
3. Implementation: Namespace Labeling
You enforce these standards by simply labeling the Namespace. No extra YAML objects required.
1. The Modes
You can apply standards in three modes:
- enforce: Rejects pods that violate the policy.
- audit: Allows the pod, but adds an audit log annotation.
- warn: Allows the pod, but shows a warning to the user.
2. Example: Enforcing ‘Restricted’
# Label the namespace
kubectl label namespace dev \
pod-security.kubernetes.io/enforce=restricted \
pod-security.kubernetes.io/enforce-version=latest \
pod-security.kubernetes.io/warn=restricted \
pod-security.kubernetes.io/warn-version=latest
3. What happens if I violate it?
If you try to deploy a Pod running as root into a restricted namespace:
Error from server (Forbidden): error when creating "pod.yaml":
pods "my-pod" is forbidden: violates PodSecurity "restricted:latest":
allowPrivilegeEscalation != false (container "app" must set securityContext.allowPrivilegeEscalation=false),
runAsNonRoot != true (pod or container "app" must set securityContext.runAsNonRoot=true)
[!TIP] Always use audit and warn modes first before turning on enforce to avoid breaking existing applications.