Implement Kubernetes Pod Security Admission to enforce baseline and restricted security profiles at namespace level using built-in admission controller.
Implement Kubernetes Pod Security Admission to enforce baseline and restricted security profiles at namespace level using built-in admission controller.
Pod Security Admission (PSA) is a built-in Kubernetes admission controller (stable since v1.25) that enforces Pod Security Standards at the namespace level. It replaces the deprecated PodSecurityPolicy (PSP) and provides three security profiles: Privileged, Baseline, and Restricted, with three enforcement modes: enforce, audit, and warn.
Prerequisites
Kubernetes v1.25+ (PSA is stable/GA)
kubectl with cluster-admin access
No dependency on external tools - PSA is built into kube-apiserver
Pod Security Standards
Privileged Profile
Unrestricted - No restrictions applied
Use case: System-level pods (kube-system, monitoring)
Baseline Profile
Minimally restrictive - Prevents known privilege escalation
Heavily restricted - Follows security best practices
Requires: non-root, drop ALL capabilities, seccomp RuntimeDefault, read-only root filesystem considerations
Blocks: Everything in Baseline plus running as root, privilege escalation, non-approved volume types
Enforcement Modes
Mode
Behavior
Use Case
enforce
Reject pods violating policy
Production enforcement
audit
Log violations to audit log
Pre-enforcement assessment
warn
Show warnings to user
Developer feedback
Implementation
Apply to Namespace via Labels
# Restricted enforcement with audit and warnapiVersion:v1kind:Namespacemetadata:name:productionlabels:pod-security.kubernetes.io/enforce:restrictedpod-security.kubernetes.io/enforce-version:v1.28pod-security.kubernetes.io/audit:restrictedpod-security.kubernetes.io/audit-version:v1.28pod-security.kubernetes.io/warn:restrictedpod-security.kubernetes.io/warn-version:v1.28
# Baseline enforcement for stagingapiVersion:v1kind:Namespacemetadata:name:staginglabels:pod-security.kubernetes.io/enforce:baselinepod-security.kubernetes.io/enforce-version:v1.28pod-security.kubernetes.io/audit:restrictedpod-security.kubernetes.io/audit-version:v1.28pod-security.kubernetes.io/warn:restrictedpod-security.kubernetes.io/warn-version:v1.28
# Privileged for system namespacesapiVersion:v1kind:Namespacemetadata:name:kube-systemlabels:pod-security.kubernetes.io/enforce:privileged
Apply Labels with kubectl
# Set restricted enforcement
kubectl label namespace production \
pod-security.kubernetes.io/enforce=restricted \
pod-security.kubernetes.io/enforce-version=v1.28 \
pod-security.kubernetes.io/audit=restricted \
pod-security.kubernetes.io/warn=restricted
# Set baseline enforcement
kubectl label namespace staging \
pod-security.kubernetes.io/enforce=baseline \
pod-security.kubernetes.io/audit=restricted \
pod-security.kubernetes.io/warn=restricted
# Check current labels
kubectl get namespace production -o jsonpath='{.metadata.labels}' | jq .
Dry-Run Testing
# Test what would happen with restricted policy on a namespace
kubectl label --dry-run=server --overwrite namespace staging \
pod-security.kubernetes.io/enforce=restricted
# Output shows existing pods that would violate the policy# Warning: existing pods in namespace "staging" violate the new PodSecurity enforce level "restricted:latest"