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.
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 withfailurePolicy: Ignore; an explicitallowed: falseresponse 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: trueis 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 Control | Privileged | Baseline | Restricted |
|---|---|---|---|
Privileged Containers (securityContext.privileged) | Allowed | Prohibited | Prohibited |
Host Namespaces (hostPID, hostIPC, hostNetwork) | Allowed | Prohibited | Prohibited |
Host Ports (hostPort) | Allowed | Prohibited | Prohibited |
HostPath Volumes (volumes.hostPath) | Allowed | Prohibited | Prohibited |
Running as Root User (runAsUser: 0) | Allowed | Allowed | Prohibited (runAsNonRoot: true) |
Privilege Escalation (allowPrivilegeEscalation) | Allowed | Allowed | Prohibited (allowPrivilegeEscalation: false) |
| Linux Capabilities | Any | Default set | Must drop ALL (can only add NET_BIND_SERVICE) |
| Seccomp Profile | Any | Any | Must be RuntimeDefault or Localhost |
3. Pod Security Admission (PSA) Modes & Labeling
PSA enforces PSS profiles using three independent modes configured as labels on namespaces:
enforce: Any pod creation or update that violates the policy is rejected immediately with an HTTP 403 error.audit: Violations are allowed, but an audit annotation is logged to the Kubernetes audit log.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: {}
Which Pod Security Standards (PSS) profile requires containers to drop ALL Linux capabilities, prevent privilege escalation, and enforce 'runAsNonRoot: true'?
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?
In the Kubernetes API server admission control pipeline, which statement correctly describes the relationship between Mutating and Validating admission webhooks?