Kyverno Pod Security Templates¶
Pod security policies prevent privilege escalation, restrict dangerous capabilities, and enforce security boundaries for containerized workloads.
Pod Security Standards Replace PSP
PodSecurityPolicy was deprecated in Kubernetes 1.21 and removed in 1.25. Use Pod Security Standards (PSS) via admission controllers or Kyverno policies instead.
Why Pod Security Matters¶
Containers inherit privileges from their configuration. Without enforcement, workloads can:
- Run as root with unrestricted filesystem access
- Mount host paths to access node secrets or modify system files
- Escalate privileges using dangerous Linux capabilities
- Break out of container isolation through privileged mode
Available Templates¶
Pod Security Standards¶
Enforce Kubernetes Pod Security Standards (Baseline, Restricted):
- Block privileged containers and hostPath volumes
- Require non-root execution and read-only root filesystems
- Enforce seccomp, AppArmor, and SELinux profiles
Apply a policy:
Privilege Restrictions¶
Prevent privilege escalation and dangerous execution modes:
- Block
privileged: truecontainers - Prevent
allowPrivilegeEscalation: true - Restrict host namespaces (PID, IPC, Network)
- Block host port bindings
Apply a policy:
Security Profiles¶
Enforce security profiles and runtime restrictions:
- Require seccomp profiles (RuntimeDefault or custom)
- Mandate AppArmor annotations for workloads
- Enforce SELinux contexts for pod isolation
- Block containers running as UID 0 (root)
Apply a policy:
Pod Security Standards Levels¶
Kubernetes defines three PSS levels. Choose based on risk tolerance.
Privileged (Unrestricted)¶
No restrictions. Only use for trusted system components.
- Use cases: CNI plugins, storage drivers, monitoring agents with node access
- Risk: Full cluster compromise if container is exploited
- Recommendation: Avoid. Use Restricted where possible.
Baseline (Minimize Known Privilege Escalations)¶
Prevents known privilege escalation vectors:
- No privileged containers
- No host namespace sharing
- No host path mounts
- Limited capabilities (drops
ALL, allows safe subset)
Use for: Most production workloads without special requirements.
Restricted (Hardened for High-Security Environments)¶
Enforces current security best practices:
- Non-root execution (
runAsNonRoot: true) - Read-only root filesystem
- Seccomp profile required
- Drops all capabilities
- No privilege escalation
Use for: Internet-facing services, multi-tenant clusters, compliance requirements.
Common Enforcement Scenarios¶
Scenario 1: Block All Privileged Containers¶
Prevent privileged mode across the cluster:
# Enforced by: privileges.yaml
# Result: No containers can run with privileged: true
# Impact: Eliminates most container breakout vectors
Scenario 2: Require Non-Root Execution¶
Force all containers to run as non-root users:
# Enforced by: profiles.yaml
# Result: Containers must define runAsNonRoot: true
# Impact: Prevents root-level filesystem access and privilege escalation
Scenario 3: Enforce Seccomp Profiles¶
Mandate seccomp profiles for syscall filtering:
# Enforced by: standards.yaml
# Result: Pods must define securityContext.seccompProfile
# Impact: Reduces kernel attack surface by blocking dangerous syscalls
Testing Pod Security Policies¶
Validate enforcement without disrupting production:
# Test privileged container block (should fail)
kubectl run privileged-test --image=nginx --privileged=true
# Expected: Blocked by privilege restriction policy
# Test root user block (should fail)
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: root-test
spec:
containers:
- name: nginx
image: nginx
securityContext:
runAsUser: 0
EOF
# Expected: Blocked by non-root requirement policy
# Test hostPath mount block (should fail)
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: hostpath-test
spec:
containers:
- name: nginx
image: nginx
volumeMounts:
- name: host
mountPath: /host
volumes:
- name: host
hostPath:
path: /
EOF
# Expected: Blocked by Pod Security Standards policy
# Test compliant pod (should succeed)
cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Pod
metadata:
name: compliant-test
spec:
securityContext:
runAsNonRoot: true
runAsUser: 1000
seccompProfile:
type: RuntimeDefault
containers:
- name: nginx
image: nginx
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
capabilities:
drop:
- ALL
EOF
# Expected: Allowed by all policies
Migration from PodSecurityPolicy¶
Replace deprecated PSPs with Kyverno policies:
- Audit current PSP usage:
kubectl get psp
kubectl get pods --all-namespaces -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.metadata.annotations.kubernetes\.io/psp}{"\n"}{end}'
- Map PSP rules to Kyverno policies:
privileged: false→ Useprivileges.yamlallowPrivilegeEscalation: false→ Useprivileges.yamlrunAsUserrules → Useprofiles.yaml-
volumesrestrictions → Usestandards.yaml -
Deploy Kyverno policies in audit mode:
- Review policy reports for violations:
- Switch to enforce mode after validation:
Update
validationFailureAction: Enforcein policies.