Kubernetes Pod Security Admission: Audit, Warn, Enforce, and Migrate
Roll out Kubernetes Pod Security Standards by namespace and version, gather audit evidence first, manage exemptions explicitly, and avoid breaking controllers.
Pod Security Admission (PSA) is the built-in Kubernetes admission controller that applies the Pod Security Standards to Pods. It can reject noncompliant Pod requests, add audit annotations, and return warnings to clients. The policy levels are privileged, baseline, and restricted; the enforcement modes are enforce, audit, and warn. These are complementary controls, not three different standards: a namespace can, for example, enforce baseline while warning and auditing against restricted.
The lowest-risk rollout starts with observation. A cluster-wide switch directly to restricted enforcement can prevent Deployments, DaemonSets, Jobs, or system components from creating Pods that rely on host access, elevated privileges, or other disallowed settings. PSA evaluates the resulting Pod admission request. It does not evict already running Pods merely because a namespace’s enforcement label changes, so the first failure may appear only on a replacement, restart, reschedule, or new rollout.
Understand standards and modes
The privileged standard is intentionally unrestricted and is useful for workloads that require broad host access. Baseline prevents known privilege-escalation patterns while supporting common applications. Restricted applies stronger hardening requirements such as explicit security context controls. None of these levels is a full container isolation boundary or a substitute for Linux kernel hardening, node isolation, network policy, or runtime security.
enforce rejects a Pod that violates the selected level. warn allows it but returns a warning to the request client. audit allows it while adding audit annotations to the request record. Each mode has its own policy level and optional version. Pinning a version makes evaluation stable across Kubernetes upgrades; using latest tracks the current policy set but may change behavior when the cluster version changes.
Workload controllers create Pods from templates. Warnings and audit evaluation help identify violations early when teams submit a Deployment, Job, or other workload resource, but enforcement applies to the Pod objects produced by those controllers. A Deployment can therefore be accepted by the API while its ReplicaSet fails to create compliant Pods. Monitor both admission warnings and the resulting controller events.
Audit before enforcing
Start by labeling application namespaces with audit and warn at the intended future level and version. This gathers evidence without immediately rejecting Pod creation. Examine API audit events, pipeline output, controller events, and application ownership. Group violations by workload and control type, then fix manifests or document a justified exception. Do not blindly label system namespaces; managed control-plane and add-on behavior may be owned by the cluster provider.
apiVersion: v1
kind: Namespace
metadata:
name: payments
labels:
pod-security.kubernetes.io/enforce: baseline
pod-security.kubernetes.io/enforce-version: "v1.37"
pod-security.kubernetes.io/audit: restricted
pod-security.kubernetes.io/audit-version: "v1.37"
pod-security.kubernetes.io/warn: restricted
pod-security.kubernetes.io/warn-version: "v1.37"
This example enforces baseline but gives teams advance warning and audit evidence for restricted. The version value must match a policy version supported by the Kubernetes release you operate. The current docs may display the latest release version; pin to the version appropriate for the actual cluster, and revisit it during cluster upgrades. Do not copy the example version without checking the target cluster.
Use a server-side dry run to observe whether a proposed label change would reject a test Pod without persisting the namespace update. Dry run is a useful checkpoint but only tests the request sent; it is not a full workload inventory scan. An existing controller may create Pods with fields not represented by the sample. Use staging clusters and observe actual rollout behavior before enabling enforcement broadly.
Migrate workloads instead of expanding exemptions
For each violation, identify the container or init container that requires the setting and why. Remove unnecessary privilege, host namespaces, hostPath mounts, capabilities, or non-default seccomp settings. If a workload truly requires a privileged mode, isolate it in a dedicated namespace with owner, reason, network rules, node placement, and restricted RBAC. Keep an exception register with review dates rather than placing a broad exemption on a shared namespace.
Check all pod-producing controllers, not only Deployments. DaemonSets for networking and storage, Jobs, CronJobs, StatefulSets, operators, admission webhooks, and custom controllers may generate Pods. Test upgrades of chart dependencies and cluster add-ons because a vendor update can change security contexts. Workloads with hostNetwork, host PID/IPC, privileged containers, or hostPath access deserve deeper isolation review even when an exemption is legitimate.
PSA exemptions can be configured at the API server for usernames, runtime classes, and namespaces. They are explicit cluster-level configuration, not normal namespace labels. Exempt requests skip all PSA enforce, audit, and warn behavior, so broad exemptions erase the visibility you need. Managed Kubernetes services may not expose every API server configuration option; use the provider’s supported controls and do not assume you can edit a control-plane file.
Enforce in controlled stages
After warnings and audits show a workload is compliant, enforce the least strict level that meets the security policy. If the target is restricted, move a namespace through warning, audit, and enforcement in a planned change. Pin the policy version during a cluster upgrade if consistent policy behavior matters, then evaluate the newer version separately. That separates application remediation from policy changes caused by an upgrade.
Use a canary namespace or a subset of stateless workloads first. Before enforcement, verify that all current Pod templates are compliant and that the rollout strategy can replace Pods without violating service availability. Pay special attention to Deployment rollouts, node maintenance, autoscaling, and rescheduling: enforcement may reveal a latent manifest problem only when a new Pod is admitted. Monitor FailedCreate events, API warnings, audit annotations, and application availability after the policy change.
kubectl label --dry-run=server --overwrite namespace payments \
pod-security.kubernetes.io/enforce=restricted \
pod-security.kubernetes.io/enforce-version=v1.37
# After a reviewed policy change, inspect the namespace's effective labels.
kubectl get namespace payments --show-labels
The first command is a dry-run assessment and does not persist the new labels. The version is illustrative and must match the cluster’s chosen PSA policy version. The second command only shows labels; it does not prove every controller-generated Pod will be admitted. Apply the final label through the repository or approved change process after reviewing the dry-run output and staging evidence.
Diagnose rejected Pods and version drift
When a Pod is rejected, inspect the API error and the warning or audit record for the exact security-context field. Map the violation to the Pod Security Standard for the selected policy version. Look at the final Pod spec produced by the controller, not only the higher-level template, because mutating webhooks and admission defaults may alter fields. Check both application and init containers, ephemeral containers, and any injected sidecars.
If a workload object exists but no Pods are ready, inspect ReplicaSet or Job events and kubectl describe output for FailedCreate errors. A namespace enforcement label applies to future Pod admissions and can break replacement after a node drain even if old Pods remain healthy. That behavior makes proactive testing during the maintenance window important.
If warnings change after a Kubernetes upgrade, compare the pinned mode version and the cluster’s current policy version. A latest policy may become stricter. Avoid disabling enforcement as the first response; identify the changed control, determine whether the workload should be fixed or isolated, and make an explicit version decision. Keep the namespace’s warn and audit modes useful after enforcement so teams see violations against a future target level.
Combine PSA with identity and runtime controls
PSA controls Pod security attributes at admission. It does not decide which user can create a privileged namespace, which image is trustworthy, whether a process can reach the network, or whether a kernel vulnerability allows container escape. Protect namespace labels and RBAC so a user cannot weaken enforcement by changing the policy level. Combine PSA with image provenance, resource quotas, least-privilege service accounts, NetworkPolicy, seccomp, and runtime monitoring.
Workloads that need an exception should not receive an unrestricted namespace by default. Prefer a narrowly scoped service account and node pool, explicit admission and network controls, a documented owner, and monitoring that can detect unexpected changes. Keep exemptions separate from standard application namespaces, and review them whenever the workload or cluster runtime changes.
Pod Security Admission is most effective as a staged policy rollout: observe, remediate, enforce, and then version the policy deliberately. Warnings and audit annotations are useful migration evidence, but only a tested enforcement path proves that future Pods will be admitted safely without creating an avoidable outage.
Related:
- Kubernetes Admission Controllers and Policy Enforcement
- Kubernetes ValidatingAdmissionPolicy: CEL Policy Without a Webhook
Sources: