πŸ“šBook Signing at KubeCon EU 2026Meet us at Booking.com HQ (Mon 18:30-21:00) & vCluster booth #521 (Tue 24 Mar, 12:30-1:30pm) β€” free book giveaway!RSVP Booking.com Event
Security intermediate ⏱ 15 minutes K8s 1.28+

Kubernetes Pod Security Standards Guide

Implement Pod Security Standards with Pod Security Admission. Privileged, baseline, and restricted profiles, namespace labels.

By Luca Berton β€’ β€’ πŸ“– 5 min read

πŸ’‘ Quick Answer: Label namespaces with pod-security.kubernetes.io/enforce: restricted to enforce Pod Security Standards. Start with warn mode to audit violations, then switch to enforce when clean.

The Problem

PodSecurityPolicy was removed in K8s 1.25. Its replacement, Pod Security Admission (PSA), uses namespace labels to enforce three security levels: privileged (no restrictions), baseline (prevents known escalations), and restricted (hardened). Teams need a migration path.

The Solution

Security Levels

LevelDescriptionUse Case
privilegedNo restrictionsSystem components, CNI, CSI
baselinePrevents known escalationsGeneral workloads
restrictedHardened security postureMulti-tenant, regulated environments

Namespace Labels

apiVersion: v1
kind: Namespace
metadata:
  name: production
  labels:
    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
---
apiVersion: v1
kind: Namespace
metadata:
  name: monitoring
  labels:
    pod-security.kubernetes.io/enforce: baseline
    pod-security.kubernetes.io/warn: restricted

Restricted-Compliant Pod

apiVersion: v1
kind: Pod
metadata:
  name: secure-app
  namespace: production
spec:
  securityContext:
    runAsNonRoot: true
    seccompProfile:
      type: RuntimeDefault
  containers:
    - name: app
      image: registry.example.com/app:1.0
      securityContext:
        allowPrivilegeEscalation: false
        capabilities:
          drop: ["ALL"]
        readOnlyRootFilesystem: true
        runAsUser: 1000
graph TD
    NS[Namespace Label<br/>enforce: restricted] -->|Pod Create| PSA[Pod Security Admission]
    PSA -->|Check against profile| CHECK{Compliant?}
    CHECK -->|Yes| ALLOW[βœ… Pod created]
    CHECK -->|No| DENY[❌ Rejected<br/>Forbidden: violates restricted]

Common Issues

β€œviolates PodSecurity restricted” β€” pods rejected

Common violations: missing runAsNonRoot, seccompProfile not set, capabilities not dropped. Check warning messages for specific fields.

System namespaces need privileged

Label kube-system, kube-node-lease, and operator namespaces as privileged. Don’t enforce restricted on system components.

Best Practices

  • Start with warn mode β€” see violations without blocking
  • Enforce restricted on all application namespaces β€” most apps can comply
  • baseline for monitoring/logging β€” Prometheus/Fluentd may need host access
  • privileged only for system namespaces β€” kube-system, CNI, CSI operators
  • Pin enforce-version to prevent surprise failures on K8s upgrades

Key Takeaways

  • PSA replaces PodSecurityPolicy with namespace-level enforcement
  • Three levels: privileged (none), baseline (sane defaults), restricted (hardened)
  • Use warn + audit labels to discover violations before enforcing
  • Restricted-compliant pods need: runAsNonRoot, drop ALL caps, seccomp RuntimeDefault, no privilege escalation
  • System namespaces must remain privileged β€” don’t lock out cluster components
#pod-security #psa #standards #restricted
Luca Berton
Written by Luca Berton

Principal Solutions Architect specializing in Kubernetes, AI/GPU infrastructure, and cloud-native platforms. Author of Kubernetes Recipes and creator of CopyPasteLearn courses.

Kubernetes Recipes book cover

Want More Kubernetes Recipes?

This recipe is from Kubernetes Recipes, our 750-page practical guide with hundreds of production-ready patterns.

Luca Berton Ansible Pilot Ansible by Example Open Empower K8s Recipes Terraform Pilot CopyPasteLearn ProteinLens