Join our Newsletter — 33% off our NHI Course
Home› Guides› PodSecurityPolicy to Pod Security Admission: Replace PSP Without…
Guide Cloud Security

PodSecurityPolicy to Pod Security Admission: Replace PSP Without Losing Pod Guardrails

← All guides
By NHI Mgmt Group, edited by Lalit Choda Updated 8 November 2026 12 min read
On this page

PodSecurityPolicy no longer functions in Kubernetes v1.25 and later, so any cluster that relied on it either has a replacement in place or is admitting privileged pods with no pod-level guardrail at all. The replacement, Pod Security Admission, is simpler and built in, but it is not a like-for-like swap: it does not mutate pods, it offers only three fixed levels, and it is controlled by namespace labels that anyone with namespace write rights can change. This guide is for platform engineers and Kubernetes security owners who are still running PSP on older clusters, who upgraded and lost it, or who need to prove that the replacement actually holds. It covers the official timeline, how to find what PSP was doing for you, the choice between Pod Security Admission and a policy engine, a staged rollout with rollback, and the risks of a gap. The wider admission chain is in the Kubernetes Admission Control Guide; this page is the migration companion.

This is an independent guide from NHI Mgmt Group, based on the Kubernetes project's public documentation as of November 2026. It is not sponsored or reviewed by the Kubernetes project. Product features change, so confirm settings against the Kubernetes project's current documentation.

Key takeaways

  • PSP is gone from v1.25. The Kubernetes project deprecated PSP in v1.21 and states that it no longer functions in v1.25 and later; Pod Security Admission graduated to stable in the same release.
  • Mutation is the hidden dependency. PSP could set defaults such as capabilities, seccomp profiles and run-as users; Pod Security Admission only validates, so workloads that passed because PSP patched them will fail or run less safely.
  • Namespace write access becomes a security permission. Pod Security levels are namespace labels, so whoever can update a namespace can lower its level.
  • Audit and warn first, enforce last. Server-side dry run, audit and warn modes let you measure violations before anything is blocked, but existing-pod checks miss CronJobs and scaled-to-zero workloads.
  • Combine, do not choose blindly. Pod Security Admission covers the standard controls; a policy engine or ValidatingAdmissionPolicy covers what PSP did beyond the Pod Security Standards, such as host path allow-lists.

What is changing and why

PodSecurityPolicy was a cluster-scoped admission controller and API (policy/v1beta1) that validated and, in places, mutated pods according to policies authorised through RBAC "use" permissions on each policy. The Kubernetes project announced its deprecation on 6 April 2021, saying a replacement was being developed to cover key use cases more easily and sustainably. That replacement is the built-in PodSecurity admission controller, which enforces the three Pod Security Standards at namespace level.

AspectPodSecurityPolicyPod Security Admission
Policy definitionCustom policy objects with many fieldsThree fixed levels: privileged, baseline, restricted
BindingRBAC "use" on a policy, per user or service account, even within a namespaceNamespace labels pod-security.kubernetes.io/<MODE>: <LEVEL>
MutationYes, for defaults such as capabilities, seccomp, AppArmor, run-as user and groupsNone; validates only
ModesEnforce onlyenforce, audit, warn, each with its own level and optional version pin
ExemptionsThrough which policy a requester could useStatic list of usernames, runtime class names and namespaces in the admission configuration
Workload objectsEvaluated when pods were createdAudit and warn apply to workload resources such as Deployments; enforce applies to pods

Official timeline and current status

All versions and dates below are from the Kubernetes project's own documentation and blog, checked on 8 November 2026.

Version or dateEventSource
6 April 2021, v1.21PSP deprecation announced; PSP to remain functional for several more releasesKubernetes blog, PodSecurityPolicy Deprecation: Past, Present, and Future
v1.22Pod Security Admission released as alphaKubernetes docs, Enforce Pod Security Standards by Configuring the Built-in Admission Controller
v1.23Pod Security Admission available by default as betaSame page
23 August 2022, v1.25PSP removed; Pod Security Admission stableKubernetes blog, v1.25 release and Pod Security Admission Controller in Stable
v1.30ValidatingAdmissionPolicy (CEL rules in the API server) stableKubernetes docs, Validating Admission Policy

Current status: PSP has no supported form in any Kubernetes release from v1.25 onward. Clusters still on v1.24 or earlier are themselves outside upstream support, so the PSP question usually arrives together with an overdue upgrade. Managed services follow the upstream removal, so check your provider's version calendar for when older versions are retired.

Who and what is affected

  • Clusters on v1.24 or earlier using PSP: after the upgrade to v1.25 pods keep being admitted, but nothing PSP enforced is enforced any more. The risk is silent loss of control, not an outage.
  • Clusters already on v1.25 or later without a replacement: any namespace with no Pod Security label falls back to the admission configuration defaults, which ship as privileged unless changed.
  • Workloads that depended on PSP mutation: pods that never set allowPrivilegeEscalation, a seccomp profile, dropped capabilities or a run-as user because PSP filled them in.
  • Per-identity policy designs: clusters that gave different PSPs to different service accounts in the same namespace. Pod Security Admission cannot express this; the migration guide calls the pattern not recommended and says a third-party webhook is needed if it must stay.
  • Infrastructure namespaces: CNI, CSI, logging and monitoring agents that legitimately need host access and must run at privileged level or be exempted.

Finding affected systems and identities

  1. List policies and who can use them. Export every PodSecurityPolicy and every Role or ClusterRole granting the "use" verb on podsecuritypolicies. A ClusterRole granting use on all policies is the first finding, because it lets any bound identity pick the most permissive one.
  2. Map pods to policies. Each admitted pod carries the kubernetes.io/psp annotation naming the policy that admitted it. Group running pods by namespace and annotation to see which namespaces run under which policy.
  3. Classify each policy field. Use the official PSP to Pod Security Standards mapping. Purely mutating fields (defaultAllowPrivilegeEscalation, defaultAddCapabilities, the default seccomp and AppArmor profile annotations, the default runtime class) and fields outside the standards (allowedHostPaths, allowedFlexVolumes, allowedCSIDrivers, forbiddenSysctls, runtimeClass) are where controls get lost.
  4. Diff pods against their templates. Compare running pods with the pod template of their controller. Differences in securityContext fields such as capabilities.drop, runAsNonRoot, runAsUser, seccompProfile or seLinuxOptions show what PSP was injecting.
  5. Find namespace writers. List identities that can create, update or patch Namespace objects. Under Pod Security Admission these identities can change a namespace's security level. Many are CI service accounts or GitOps controllers. See the Kubernetes RBAC Guide.
  6. Find workloads that are not running. CronJobs, Jobs, scaled-to-zero Deployments and Helm releases not yet rolled out do not show up in pod listings. Inventory them from manifests and Git.

Migration options

OptionStrengthsLimitsChoose it when
Pod Security Admission onlyBuilt in, no extra components, maintained standards, version pinning per namespaceThree levels; no mutation; no per-identity rules; no control of host path allow-lists or volume driversYour PSPs were close to baseline or restricted and workloads already set their own security context
Pod Security Admission plus ValidatingAdmissionPolicyAdds custom CEL validation inside the API server, stable since v1.30, no webhook to keep availableValidation only; policies to write and test yourselfYou need a few extra rules (for example allowed host paths) without running a policy engine
Pod Security Admission plus a policy engineMutation, custom rules, reporting; PSA remains a fallback if the webhook failsAnother component to operate; webhook failure policy decisionsYou relied on PSP mutation, need fine-grained or per-workload rules, or want policy reports

The Kubernetes Pod Security Standards page lists open source policy engines as alternatives. Projects are listed alphabetically; order is not a ranking.

  • Gatekeeper (Open Policy Agent): the gatekeeper-library has a pod-security-policy folder with constraint templates such as K8sPSPPrivilegedContainer, and folders for host namespaces, privilege escalation, capabilities and host file system. Constraints default to enforcementAction deny, with dryrun and warn available for testing. The library also includes example mutation policies that its maintainers say must be customised before use.
  • Kyverno: a validate rule can use a podSecurity block with a level (baseline or restricted), a version (latest or a pinned version) and an exclude list that exempts named controls, optionally for specific images. The rule's failureAction is Enforce to block or Audit to record violations in a policy report.

Choosing a level per namespace

The migration guide offers three ways: by the security requirement of the namespace, by mapping the existing PSP to a level, or by testing existing pods against baseline and restricted and choosing the least privileged level that works. Where a PSP sits between levels, decide deliberately whether to be at least as permissive (no breakage, possible gap) or at least as restrictive (closes gaps, needs workload fixes). Baseline blocks host namespaces, privileged containers, added capabilities beyond the default set, host path volumes and host ports; restricted adds non-root, no privilege escalation, a seccomp profile, dropping ALL capabilities and limited volume types.

Testing and rollback

  1. Remove PSP mutation first. Following the official guide, clone each mutating PSP offline with a name that sorts before the original, strip purely mutating fields, roll it out alongside the original, and verify with the kubernetes.io/psp annotation that recreated pods now use the clone. Fix pod templates where workloads lose configuration.
  2. Dry run each namespace. Apply the proposed enforce label with a server-side dry run; the API server returns warnings for existing pods that would violate the level without changing anything.
  3. Audit and warn for a soak period. Set pod-security.kubernetes.io/audit and /warn to the target level. Audit adds annotations to audit log events; warn returns messages to the deployer, including when they apply Deployments and other workload objects.
  4. Enforce namespace by namespace. Set the enforce label, pin enforce-version to the current minor version if you want upgrades not to tighten rules unexpectedly, and keep audit and warn at latest to see upcoming changes.
  5. Bypass PSP per namespace. Bind the fully privileged, non-mutating PSP to all service accounts in the namespace. Rollback is deleting that RoleBinding, provided the original PSPs are still in place.
  6. Set safe defaults and disable PSP. Configure the admission controller defaults so unlabelled namespaces are not privileged, update namespace creation processes, then remove PodSecurityPolicy from the API server admission plugins. The API server's startup log lists loaded plugins: PodSecurity should appear among validating controllers and PodSecurityPolicy should not.
  7. Clean up after soak. Delete PSP objects and their Roles and bindings, checking they grant nothing else.

Detection and measurement

  • API server metrics: pod_security_evaluations_total, pod_security_exemptions_total and pod_security_errors_total show evaluation volume, exemption use and evaluation failures.
  • Audit log annotations: violations recorded by audit mode; changes to pod-security.kubernetes.io labels on Namespace objects; creation of pods with hostPID, hostNetwork or privileged set. See the Kubernetes Audit Log Detection Guide.
  • KPIs: percentage of namespaces with an explicit enforce label (target 100); percentage at baseline or restricted; number of exempted usernames, runtime classes and namespaces, each with an owner; audit violations per week trending down; time from a namespace label downgrade to alert.

Risks of doing nothing

  • Privileged pods by default: without labels or configured defaults, new namespaces admit privileged containers, host namespaces and host path mounts, the building blocks of MITRE ATT&CK T1611 Escape to Host.
  • Malicious workloads go unchecked: a stolen deployer credential can start a privileged container (T1610 Deploy Container) with nothing at admission to stop it.
  • Label tampering: a CI identity or user with namespace patch rights can quietly downgrade a namespace from restricted to privileged.
  • Stuck on unsupported versions: teams that delay the PSP work often delay the upgrade, which leaves the control plane without security fixes.
  • Over-broad exemptions: exempting controller service accounts such as the ReplicaSet controller implicitly exempts every user who can create the matching workload, which the Kubernetes documentation warns against.

Framework mapping

FrameworkReferenceRelevance
NIST SP 800-53 Rev. 5CM-6 Configuration Settings; CM-7 Least FunctionalityPod Security levels as enforced configuration baselines
NIST SP 800-53 Rev. 5AC-6 Least PrivilegeRestricted level; limiting who can change namespace labels
NIST SP 800-53 Rev. 5SA-22 Unsupported System ComponentsRemoving a removed API and upgrading off unsupported versions
NIST CSF 2.0PR.PS-01Configuration management practices established and applied
MITRE ATT&CKT1610 Deploy Container; T1611 Escape to HostTechniques the guardrail is meant to block

Practitioner checklist

  • Inventory every PSP, every "use" grant and the kubernetes.io/psp annotation on running pods.
  • Remove PSP mutation before switching, and fix pod templates to set their own security context.
  • Restrict create, update and patch on Namespace objects to trusted identities.
  • Choose a level per namespace and record why; prefer restricted for application namespaces.
  • Run dry run, then audit and warn, before enforce; include CronJobs and scaled-to-zero workloads.
  • Configure admission defaults so unlabelled namespaces are not privileged.
  • Cover PSP controls outside the standards with ValidatingAdmissionPolicy or a policy engine.
  • Keep exemptions minimal, owned and reviewed; never exempt controller service accounts.
  • Alert on Pod Security label changes and track the pod_security metrics.

Standards and references

Related NHI Mgmt Group resources: Kubernetes Admission Control Guide · Kubernetes Security Guide · Kubernetes RBAC Guide · Container Runtime Security Guide

Free weekly newsletter

Subscribe to the NHI & AI Identity Journal

The latest on NHI and Agentic AI security – articles, research, breaches, news and events every week.

Bonus 33% off our NHI Course when you subscribe.

NHIMG Editorial Note
Researched and written by the NHI Mgmt Group editorial team using AI tools, under the editorial direction of Lalit Choda. Facts are drawn from the sources listed on this page and checked by our automated quality process. Last updated 8 November 2026. Spotted an error? Use our contact page.
NHI Mgmt Group, the independent authority on Non-Human Identity, IAM and Agentic AI security. nhimg.org