2.7 Pod Security Standards (PSS) & Admission Controllers

Key Takeaways

  • Admission controllers evaluate requests after authentication and authorization; Mutating controllers execute sequentially to modify objects, followed by Validating controllers running in parallel to accept or reject them.
  • Pod Security Standards (PSS) define three cumulative security profiles: Privileged (unrestricted), Baseline (prevents common escalations, default settings), and Restricted (hardened, non-root, drops all capabilities).
  • Pod Security Admission (PSA) applies PSS profiles at the namespace level across three distinct modes: 'enforce' (rejects violation), 'audit' (records in audit log), and 'warn' (returns visual terminal warning to user).
  • Configuring PSA on a namespace is performed via labels: 'pod-security.kubernetes.io/enforce: restricted' and 'pod-security.kubernetes.io/enforce-version: v1.35'.
  • The Restricted PSS profile requires setting 'runAsNonRoot: true', 'allowPrivilegeEscalation: false', dropping 'ALL' Linux capabilities, and using a 'RuntimeDefault' or 'Localhost' seccomp profile.
Last updated: August 2026

Pod Security Standards (PSS) & Admission Controllers

Securing a Kubernetes cluster requires preventing workloads from compromising node stability, escaping container boundaries, or accessing host system resources. Following the removal of legacy PodSecurityPolicy (PSP) in Kubernetes v1.25, the built-in Pod Security Standards (PSS) and Pod Security Admission (PSA) controller serve as the official mechanism for enforcing workload security constraints.


1. Admission Control Architecture: Mutating vs. Validating

+---------------------------------------------------------------------------------------------------------+
|                                 ADMISSION CONTROL CONTROLLER FLOW                                       |
|                                                                                                         |
|   [AUTHENTICATED & AUTHORIZED REQUEST]                                                                  |
|                  |                                                                                      |
|                  v                                                                                      |
|   +------------------------------------+                                                                |
|   | 1. MUTATING ADMISSION CONTROLLERS  | ---> Runs SEQUENTIALLY                                         |
|   |    - MutatingAdmissionWebhook      |      Can modify the incoming object manifest                   |
|   |    - DefaultStorageClass           |      (e.g., inject sidecar container, set default storage)      |
|   |    - ServiceAccount controller     |                                                                |
|   +-----------------+------------------+                                                                |
|                     | Modified Object Manifest                                                          |
|                     v                                                                                   |
|   +------------------------------------+                                                                |
|   | 2. OBJECT SCHEMA VALIDATION        | ---> Verifies field types, schemas, and OpenAPI specs          |
|   +-----------------+------------------+                                                                |
|                     | Valid Schema                                                                      |
|                     v                                                                                   |
|   +------------------------------------+                                                                |
|   | 3. VALIDATING ADMISSION CONTROLLERS| ---> Runs IN PARALLEL                                          |
|   |    - ValidatingAdmissionWebhook    |      Cannot modify object; evaluates ACCEPT or REJECT           |
|   |    - PodSecurity Controller (PSA)  |      (e.g., PSS compliance, ResourceQuota limits)               |
|   |    - NodeRestriction               |                                                                |
|   +-----------------+------------------+                                                                |
|                     | All Passed                                                                        |
|                     v                                                                                   |
|             [PERSIST TO ETCD]                                                                           |
+---------------------------------------------------------------------------------------------------------+

Key Admission Controller Types:

  • Mutating Phase: Runs first and may alter the submitted object. Matching webhooks are called serially, but their invocation order is not a stable contract. A call error rejects by default (failurePolicy: Fail) or is ignored when configured with failurePolicy: Ignore; an explicit allowed: false response rejects the request.
  • Validating Phase: Runs after schema validation. Evaluates whether the finalized object complies with cluster policies. Validating webhooks cannot mutate the object.

Core Built-in Admission Plugins:

  • NodeRestriction: Limits the Node identity to modifying its own Node and bound Pod objects and protects reserved label prefixes. Secret access restrictions are primarily enforced by the Node authorizer.
  • PodSecurity: Enforces Pod Security Standards based on namespace labels.
  • ResourceQuota & LimitRanger: Enforce resource consumption ceilings.
  • NamespaceLifecycle: Prevents creating objects in terminating namespaces or deleting system namespaces (default, kube-system).

2. Pod Security Standards (PSS) Profiles

PSS defines three progressive security profiles:

+-----------------------------------------------------------------------------------------+
|                            POD SECURITY STANDARDS (PSS) TIERS                           |
|                                                                                         |
|   [PRIVILEGED]                                                                          |
|   - Completely open / unrestricted                                                      |
|   - Allows: privileged containers, hostPID, hostNetwork, hostPath volumes, root user    |
|   - Use case: CNI network plugins, storage drivers, system daemons                      |
|         |                                                                               |
|         v (Hardening Step 1)                                                            |
|   [BASELINE]                                                                            |
|   - Prevents known privilege escalations with minimal friction                          |
|   - Prohibits: privileged containers, host namespaces, forbidden volume types           |
|   - Allows: running as root (UID 0), default Linux capabilities                         |
|   - Use case: Standard general-purpose microservices                                    |
|         |                                                                               |
|         v (Hardening Step 2)                                                            |
|   [RESTRICTED]                                                                          |
|   - Heavily hardened; enforces cloud-native security best practices                     |
|   - Requires: runAsNonRoot, no privilege escalation, seccomp, and dropping ALL capabilities     |
|   - Prohibits: privilege escalation, root execution                                     |
|   - Use case: Multi-tenant clusters, public-facing services, financial workloads        |
+-----------------------------------------------------------------------------------------+

[!NOTE] readOnlyRootFilesystem: true is valuable defense in depth and is used in the hardened example below, but it is not a required Restricted Pod Security Standard control.

Detailed PSS Profile Matrix

Security ControlPrivilegedBaselineRestricted
Privileged Containers (securityContext.privileged)AllowedProhibitedProhibited
Host Namespaces (hostPID, hostIPC, hostNetwork)AllowedProhibitedProhibited
Host Ports (hostPort)AllowedProhibitedProhibited
HostPath Volumes (volumes.hostPath)AllowedProhibitedProhibited
Running as Root User (runAsUser: 0)AllowedAllowedProhibited (runAsNonRoot: true)
Privilege Escalation (allowPrivilegeEscalation)AllowedAllowedProhibited (allowPrivilegeEscalation: false)
Linux CapabilitiesAnyDefault setMust drop ALL (can only add NET_BIND_SERVICE)
Seccomp ProfileAnyAnyMust be RuntimeDefault or Localhost

3. Pod Security Admission (PSA) Modes & Labeling

PSA enforces PSS profiles using three independent modes configured as labels on namespaces:

  1. enforce: Any pod creation or update that violates the policy is rejected immediately with an HTTP 403 error.
  2. audit: Violations are allowed, but an audit annotation is logged to the Kubernetes audit log.
  3. warn: Violations are allowed, but an immediate warning message is returned to the user in their CLI output.

Namespace Labeling Syntax:

pod-security.kubernetes.io/<mode>: <profile> pod-security.kubernetes.io/<mode>-version: <version> (e.g., v1.35 or latest)

Applying PSA Labels via kubectl

# 1. Enforce Baseline, while warning and auditing on Restricted
kubectl label namespace staging \
  pod-security.kubernetes.io/enforce=baseline \
  pod-security.kubernetes.io/enforce-version=latest \
  pod-security.kubernetes.io/warn=restricted \
  pod-security.kubernetes.io/warn-version=latest \
  pod-security.kubernetes.io/audit=restricted \
  pod-security.kubernetes.io/audit-version=latest \
  --overwrite

# 2. Strict Restricted enforcement for production
kubectl label namespace production \
  pod-security.kubernetes.io/enforce=restricted \
  pod-security.kubernetes.io/enforce-version=latest \
  --overwrite

# 3. Check labels on a namespace
kubectl get ns staging --show-labels

4. Hardening Workloads for the Restricted Profile

To run successfully in a namespace with pod-security.kubernetes.io/enforce=restricted, a Pod manifest must include explicit securityContext settings at both the pod and container levels.

Compliant Restricted Pod Specification

apiVersion: v1
kind: Pod
metadata:
  name: secure-app
  namespace: production
spec:
  # Pod-level Security Context
  securityContext:
    runAsNonRoot: true
    runAsUser: 10001
    runAsGroup: 10001
    fsGroup: 10001
    seccompProfile:
      type: RuntimeDefault
  containers:
  - name: web
    image: nginx:1.27
    # Container-level Security Context
    securityContext:
      allowPrivilegeEscalation: false
      readOnlyRootFilesystem: true
      capabilities:
        drop:
        - ALL
        add:
        - NET_BIND_SERVICE # Allowed exception for binding low ports
    volumeMounts:
    - name: cache-volume
      mountPath: /var/cache/nginx
    - name: run-volume
      mountPath: /var/run
  volumes:
  - name: cache-volume
    emptyDir: {}
  - name: run-volume
    emptyDir: {}
Loading diagram...
Admission Controller Execution Pipeline & Pod Security Standards (PSS) Tiers
Test Your Knowledge

Which Pod Security Standards (PSS) profile requires containers to drop ALL Linux capabilities, prevent privilege escalation, and enforce 'runAsNonRoot: true'?

A
B
C
D
Test Your Knowledge

An administrator wants to begin testing the 'restricted' Pod Security Standard in the 'qa' namespace so developers receive visual warnings during 'kubectl apply', but workloads that violate the policy are NOT blocked. Which command accomplishes this?

A
B
C
D
Test Your Knowledge

In the Kubernetes API server admission control pipeline, which statement correctly describes the relationship between Mutating and Validating admission webhooks?

A
B
C
D