What Are Pod Security Standards in Kubernetes?

intermediate|securitydevopssreCKA
TL;DR

Pod Security Standards define three levels of security policies (Privileged, Baseline, Restricted) enforced by the built-in Pod Security Admission controller. They replace the deprecated PodSecurityPolicy and are applied at the namespace level using labels.

Detailed Answer

Overview of Pod Security Standards

Pod Security Standards (PSS) define three progressively restrictive security profiles:

1. Privileged

No restrictions. Allows all Pod configurations including privileged containers, host networking, and hostPath volumes. Used for system-level workloads like CNI plugins and monitoring agents.

2. Baseline

Prevents known privilege escalations. Blocks the most dangerous capabilities while remaining compatible with most applications. Key restrictions:

  • No privileged containers
  • No hostNetwork, hostPID, or hostIPC
  • No hostPath volumes
  • No dangerous capabilities (NET_RAW is allowed)
  • No running as root with privilege escalation

3. Restricted

Maximum security. Requires all security best practices:

  • Must run as non-root
  • Must drop ALL capabilities
  • Read-only root filesystem encouraged
  • Seccomp profile must be set to RuntimeDefault or Localhost
  • No privilege escalation allowed

Applying Pod Security Standards

PSS is enforced using labels on namespaces. No additional admission controllers or CRDs are needed.

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/audit: restricted
    pod-security.kubernetes.io/audit-version: latest
    pod-security.kubernetes.io/warn: restricted
    pod-security.kubernetes.io/warn-version: latest
# Apply labels to an existing namespace
kubectl label namespace production \
  pod-security.kubernetes.io/enforce=restricted \
  pod-security.kubernetes.io/audit=restricted \
  pod-security.kubernetes.io/warn=restricted

The Three Enforcement Modes

| Mode | Behavior | |---|---| | enforce | Rejects Pods that violate the policy | | audit | Logs violations in the API server audit log but allows the Pod | | warn | Sends a warning to the user but allows the Pod |

A common rollout strategy is to start with warn and audit to discover violations, then switch to enforce once all workloads are compliant:

# Phase 1: Discover violations
labels:
  pod-security.kubernetes.io/warn: restricted
  pod-security.kubernetes.io/audit: restricted

# Phase 2: Enforce after fixing violations
labels:
  pod-security.kubernetes.io/enforce: restricted
  pod-security.kubernetes.io/audit: restricted
  pod-security.kubernetes.io/warn: restricted

What Each Level Blocks

Baseline Restrictions

# These are BLOCKED at Baseline level:
spec:
  hostNetwork: true          # blocked
  hostPID: true              # blocked
  hostIPC: true              # blocked
  containers:
    - securityContext:
        privileged: true     # blocked
      volumeMounts: ...
  volumes:
    - hostPath:              # blocked
        path: /etc

Restricted Level Additional Requirements

# A Pod that PASSES the Restricted level:
apiVersion: v1
kind: Pod
metadata:
  name: secure-app
spec:
  securityContext:
    runAsNonRoot: true
    seccompProfile:
      type: RuntimeDefault
  containers:
    - name: app
      image: myapp:latest
      securityContext:
        allowPrivilegeEscalation: false
        readOnlyRootFilesystem: true
        runAsNonRoot: true
        capabilities:
          drop:
            - ALL
        seccompProfile:
          type: RuntimeDefault

Version Pinning

You can pin the PSS enforcement to a specific Kubernetes version to prevent unexpected breakage during upgrades:

labels:
  pod-security.kubernetes.io/enforce: restricted
  pod-security.kubernetes.io/enforce-version: v1.30

Using latest always applies the current version's rules. Pinning to a specific version ensures that new restrictions added in future Kubernetes versions do not break existing workloads.

Namespace Exemptions

The Pod Security Admission controller can be configured to exempt specific users, RuntimeClasses, or namespaces:

# Admission controller configuration (in API server flags)
apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
  - name: PodSecurity
    configuration:
      apiVersion: pod-security.admission.config.k8s.io/v1
      kind: PodSecurityConfiguration
      defaults:
        enforce: baseline
        enforce-version: latest
      exemptions:
        usernames:
          - system:serviceaccount:kube-system:replicaset-controller
        namespaces:
          - kube-system
        runtimeClasses:
          - untrusted

Migration from PodSecurityPolicy

PodSecurityPolicy was removed in Kubernetes 1.25. To migrate:

  1. Audit existing PSPs to understand what they enforce.
  2. Map each PSP to the closest PSS level (Privileged, Baseline, or Restricted).
  3. Label namespaces with the appropriate PSS level in warn/audit mode.
  4. Fix any non-compliant workloads.
  5. Switch to enforce mode.
  6. Remove the PSP admission controller and PSP objects.
# Check which Pods would violate a policy (dry-run)
kubectl label namespace default \
  pod-security.kubernetes.io/warn=restricted \
  --dry-run=server -o yaml

Best Practices

Apply restricted as the default for all application namespaces and only relax to baseline or privileged for infrastructure namespaces that genuinely need elevated access. Always use all three modes (enforce + audit + warn) to get comprehensive visibility and enforcement.

Why Interviewers Ask This

Interviewers want to see that you understand Kubernetes' built-in security enforcement mechanism and can apply appropriate restrictions to namespaces in production.

Common Follow-Up Questions

What replaced PodSecurityPolicy?
Pod Security Admission (PSA), which became stable in Kubernetes 1.25. It uses namespace labels to enforce Pod Security Standards.
What is the difference between enforce, audit, and warn modes?
Enforce blocks non-compliant Pods, audit logs violations to the audit log, and warn shows warnings to the user but allows the Pod.
Can different namespaces have different security levels?
Yes. Each namespace can have its own PSS level. For example, kube-system might use Privileged while application namespaces use Restricted.

Key Takeaways

  • Three levels: Privileged (unrestricted), Baseline (sensible defaults), Restricted (hardened)
  • Applied via namespace labels, not separate policy objects
  • Replaces the deprecated PodSecurityPolicy (removed in 1.25)