Introduction
Securing Kubernetes workloads is critical to prevent security breaches and container escapes. Kubernetes Pod Security Standards (PSS) provide a framework for defining and enforcing security settings for Pods at different levels—Privileged, Baseline, and Restricted.
In this guide, you’ll learn how to implement Pod Security Standards in a Kubernetes cluster while ensuring your applications run smoothly.Understanding Pod Security Standards (PSS)
Kubernetes defines three security levels for Pods:
- Privileged – No restrictions; full host access (Not recommended).
- Baseline – Reasonable defaults for running common applications.
- Restricted – Strictest policies for maximum security.
Goal: Implement Restricted policies where possible while ensuring apps run without breaking.
Step 1: Enabling Pod Security Admission (PSA)
Starting from Kubernetes v1.23, Pod Security Admission (PSA) replaces PodSecurityPolicies (PSP) to enforce PSS.
Check if PSA is Enabled
kubectl get ns --show-labels
If namespaces are not labeled with PSS, you must label them manually.
Step 2: Apply Pod Security Labels to Namespaces
Namespaces must be labeled to enforce a Pod Security Standard.
Baseline Policy (For Standard Applications)
kubectl label namespace default pod-security.kubernetes.io/enforce=baseline
Restricted Policy (For Maximum Security)
kubectl label namespace secure-apps pod-security.kubernetes.io/enforce=restricted
Verify Labels
kubectl get ns --show-labels
Step 3: Deploy Applications with Pod Security Standards
Example 1: Non-Root Container (Restricted Mode)
A properly secured Pod must not run as root. Here’s a compliant example:
apiVersion: v1
kind: Pod
metadata:
name: secure-app
namespace: secure-apps
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1001
fsGroup: 1001
containers:
- name: app
image: nginx:latest
securityContext:
allowPrivilegeEscalation: false
capabilities:
drop:
- ALL
readOnlyRootFilesystem: true
volumeMounts:
- mountPath: /data
name: app-storage
volumes:
- name: app-storage
emptyDir: {}
Why This Pod Is Secure?
- Runs as a non-root user (runAsNonRoot: true)
- No privilege escalation (allowPrivilegeEscalation: false)
- All unnecessary Linux capabilities are dropped (capabilities.drop: ALL)
- Uses a read-only root filesystem (readOnlyRootFilesystem: true)
Step 4: Prevent Non-Compliant Pods from Running
Test deploying a privileged Pod in the secure-apps namespace:
apiVersion: v1
kind: Pod
metadata:
name: privileged-app
namespace: secure-apps
spec:
containers:
- name: app
image: nginx:latest
securityContext:
privileged: true
Expected Output
Error: pods "privileged-app" is forbidden: violates PodSecurity "restricted:latest"
Kubernetes blocks the Pod due to the privileged: true setting.Step 5: Audit and Warn Non-Compliant Pods (Optional)
Instead of enforcing policies immediately, you can audit violations first.
Audit Only:
kubectl label namespace dev-team pod-security.kubernetes.io/audit=restricted
Warn Before Deployment:
kubectl label namespace dev-team pod-security.kubernetes.io/warn=restricted
Now, users get warnings instead of immediate rejections.Step 6: Verify Security Policies
Check PSA Enforcement Logs
kubectl describe pod secure-app -n secure-apps
Test Pod Security Admission
kubectl run test-pod --image=nginx --namespace=secure-apps
If the Pod violates security rules, Kubernetes will block it.
Conclusion
You implemented Kubernetes Pod Security Standards
Pods now run with minimal privileges
Security policies are enforced while maintaining functionality
How do you implement PSS? Let’s discuss best practices in the comments!