Cyber Security 8 MIN READ

Kubernetes Pod Security Policy Removal Changes Your Defense

Kubernetes removed Pod Security Policy entirely in version 1.25. The deprecation started back in version 1.21, giving teams roughly two years to prepare. Many didn't use that runway, and now they're s

Fortress wall with defensive gate removed, replaced by open archway revealing vulnerable interior space beyond.
FIG. 01  /  Cyber Security
In this piece

Kubernetes removed Pod Security Policy entirely in version 1.25. The deprecation started back in version 1.21, giving teams roughly two years to prepare. Many didn't use that runway, and now they're scrambling to find a Kubernetes Pod Security Policy replacement before an upgrade breaks their cluster's security enforcement.

The official replacement is not a single tool. It's a combination of Pod Security Standards, which define what "secure" means, and Pod Security Admission, which enforces those definitions at runtime. Together they form a simpler model than PSP ever offered, but simpler doesn't always mean easier to migrate to.

This piece walks through what changed, how to map old policies to new ones, and how to avoid the traps that turn a routine upgrade into a production incident.

The Enforcement Cliff: Why 1.25 Forces Your Hand

If a cluster runs Kubernetes 1.25 or later and previously relied on PSP, one of two things is true. Either the migration already happened, or a webhook shim is standing in as a stopgap, according to CodingProtocols.

Neither situation is optional to address. PSP's API objects simply don't exist anymore in 1.25+. There's no flag to re-enable them, no legacy mode, no grace period.

Clusters that skip several versions during an upgrade cycle sometimes discover this the hard way. A jump from 1.20 to 1.26 in one maintenance window can silently drop all pod security enforcement, because the PSP admission controller disappears and nothing replaces it automatically.

That's the cliff. It's not a slow slope where policies degrade gracefully. It's a hard stop where enforcement either transferred successfully to the new system or it didn't.

Beyond Deprecation: What PSA Actually Changes

The shift from PSP to Pod Security Admission is not a like-for-like swap. PSP was a flexible, rule-based system where administrators wrote granular policies covering dozens of possible pod configurations.

Pod Security Admission works differently. It checks pods against three predefined Pod Security Standards: Privileged, Baseline, and Restricted, according to Groundcover.

There's no custom rule authoring in the PSA model itself. You pick a standard, apply it to a namespace, and pods are evaluated against that standard's fixed criteria.

This is a deliberate trade-off. PSP's flexibility came at a cost: it was notoriously hard to reason about, and misconfigured policies were a common source of either broken deployments or security gaps. According to Kubernetes documentation, Pod Security Admission is built directly into the API server, which means there's no separate plugin to deploy, version, or maintain.

That built-in nature matters more than it sounds. Teams previously running third-party admission controllers as PSP alternatives now have a first-party option that ships with every cluster, with no extra installation step required.

Three Levels, Infinite Complexity: Mapping Old Rules to New Standards

The three Pod Security Standards levels are:

  • Privileged: Unrestricted, equivalent to having no policy at all.
  • Baseline: Blocks known privilege escalations while staying compatible with most common workloads.
  • Restricted: Enforces current pod hardening best practices, including dropped capabilities and non-root execution.

Most PSP configurations don't map cleanly onto one of these three buckets. A typical enterprise PSP setup might allow specific host paths for one team, restrict capabilities differently for another, and permit privileged containers only for a monitoring namespace.

That granularity has to be re-thought, not directly translated. The practical approach is to treat each namespace as its own security domain and ask which of the three standards its workloads can realistically meet.

A Simple Mapping Exercise

Start by listing every PSP currently active and what it permits. For each one, check whether its allowed configurations fit inside Baseline or Restricted, or whether they require Privileged.

Namespaces that only need Privileged access should be small and well-monitored, since that tier offers no meaningful pod-level protection. Everything else should aim for Restricted where possible.

A Simple Mapping Exercise
PSP BehaviorClosest PSS Level
No restrictions*, host access allowedPrivileged
Blocks privilege escalation*, allows most workloadsBaseline
Enforces non-root*, drops all capabilitiesRestricted

This shows a rough starting point for translating common PSP configurations into the three Pod Security Standards tiers.

Workloads that don't fit any single tier cleanly are usually a sign of over-permissioned PSP rules that should be tightened anyway, rather than a genuine need for custom policy logic.

The Audit-First Strategy: Warn and Dry-Run Before You Enforce

Jumping straight to enforcement mode is the single most common way migrations go wrong. Kubernetes supports a much safer path using dry-run mode combined with audit and warn modes, according to Kubernetes documentation.

Pod Security Admission supports three modes per namespace, and they can run simultaneously:

  • enforce: Blocks pods that violate the standard.
  • audit: Logs violations without blocking anything.
  • warn: Returns a warning to the user submitting the pod, but still allows it.

A practical migration sequence looks like this:

yaml
apiVersion: v1
kind: Namespace
metadata:
  name: example-namespace
  labels:
    pod-security.kubernetes.io/enforce: privileged
    pod-security.kubernetes.io/audit: restricted
    pod-security.kubernetes.io/warn: restricted

This configuration keeps the namespace fully open while quietly recording every pod that would fail the Restricted standard. Run this for a week or two, review the audit logs, and fix any workloads that would break under stricter enforcement.

Only after the warnings stop appearing should the enforce label be tightened to match. This staged approach turns a risky cutover into a gradual, observable process.

bash
kubectl get events -n example-namespace --field-selector reason=FailedCreate

Checking events like this regularly during the audit phase catches issues before they become outages.

Process: Run workloads, then Fix workloads, then Switch enforceFIGURE 1 / PROCESSSafe PSA Migration SequenceRun workloadsCollect audit logs forone to two weeksAudit violationsFix workloadsAddress violationsflagged by warningsReview findingsSwitch enforceTighten enforce labelto match target standard
A four-step sequence moving from audit-only to full enforcement reduces migration risk

Namespace-Level Thinking: A Genuine Shift in Control

PSP applied policy at the cluster level through RoleBindings that determined which service accounts could use which policies. It was powerful but genuinely confusing to trace, since a pod's effective policy depended on a chain of bindings that were easy to get wrong.

PSA flips this model. Enforcement now happens through labels applied directly to namespaces, according to Groundcover. There's no binding chain to trace. A namespace's labels are its policy, full stop.

This is a meaningful simplification for troubleshooting. When a pod gets rejected, checking the namespace's three labels tells you immediately what standard is being enforced and why.

The trade-off is less fine-grained control. Teams that relied on PSP to give different service accounts different permissions within the same namespace will need to split those workloads into separate namespaces instead, since PSA doesn't support per-service-account policy within a single namespace.

For most organizations this is a reasonable adjustment, since namespace boundaries were already a common way to separate teams or applications.

The Webhook Shim Trap

Some clusters running 1.25+ are still relying on webhook shims that reimplement PSP behavior as a workaround, according to CodingProtocols. These shims exist for a real reason: they buy time when a full migration can't happen before an upgrade deadline.

The problem is that "temporary" workarounds have a way of becoming permanent. A webhook shim adds an external dependency, additional latency on every pod admission request, and a maintenance burden that the built-in PSA system was specifically designed to eliminate.

Common advice across migration guides is consistent on this point: avoid treating webhook shims as a long-term solution. Set a hard deadline for full PSA migration, and track it the same way you'd track any other technical debt with a security dimension.

Compliance Verification: Matching PSS to Regulatory Requirements

Organizations working under frameworks like PCI-DSS, HIPAA, or SOC 2 need pod security controls that satisfy specific technical requirements, not just general best practices. The three Pod Security Standards levels don't map one-to-one onto any single compliance framework, so this step requires manual verification.

A reasonable approach is to treat Restricted as the default baseline for any namespace handling regulated data, since it enforces non-root execution and drops unnecessary capabilities. That covers a meaningful chunk of typical container-hardening requirements found in security frameworks.

Where a specific control isn't covered by Restricted alone, pair PSA with complementary container runtime security controls, such as seccomp profiles, read-only root filesystems, or a runtime security tool that watches for anomalous behavior after admission. PSA controls what gets admitted; it doesn't monitor what a running container actually does.

Post-Migration Observability

Migrating to PSA isn't a one-time event that ends when enforce labels go live. Ongoing monitoring should track:

  • Rejected pod counts per namespace, to catch new violations introduced by future deployments.
  • Audit log volume in namespaces still running audit-only mode, to measure migration progress over time.
  • Namespace label drift, since a label accidentally removed or downgraded silently weakens enforcement.

Setting up alerts on FailedCreate events tied to Pod Security Admission gives an early warning when a new deployment doesn't match its namespace's standard, before it becomes a blocked release that surprises a team at the worst possible time.

Frequently Asked Questions

Q: What happens to existing PSP rules when a cluster upgrades to Kubernetes 1.25 or later?

A: The PSP API objects and admission controller are removed entirely. Any enforcement they provided disappears unless it has already been replaced by Pod Security Admission or an external policy tool.

Q: Can PSA run in warn-only mode indefinitely?

A: Technically yes, but it provides no actual blocking protection. Warn mode is meant as a transitional tool, and leaving it as the permanent state defeats the purpose of Pod Security Standards migration.

Q: How do Pod Security Standards handle custom requirements the three levels don't cover?

A: PSA doesn't support custom rules on its own. For requirements outside the three standards, pair PSA with additional container runtime security controls or a policy-as-code tool like OPA Gatekeeper or Kyverno.

Q: Does Pod Security Admission support gradual rollout across namespaces?

A: Yes. Because enforcement is set per namespace, teams can migrate one namespace at a time, starting with lower-risk workloads before touching production-critical ones.

Takeaways

Kubernetes Pod Security Policy replacement isn't optional for anyone still upgrading toward 1.25 or beyond. The practical path forward:

  • Inventory every active PSP rule and map it against the three Pod Security Standards levels.
  • Use audit and warn modes for at least a week or two before switching any namespace to enforce.
  • Move away from webhook shims on a firm timeline rather than treating them as permanent.
  • Verify that chosen PSS levels actually satisfy any compliance frameworks in play.
  • Set up ongoing monitoring for rejected pods and label drift after migration completes.

The underlying shift, from cluster-wide flexible rules to namespace-level fixed standards, is a genuine simplification of Kubernetes security. It just requires treating the migration as a project with real planning, not a checkbox to clear before an upgrade.

Sources

Researched from the following. Figures and claims were current when this piece was written and may have moved since.

  1. Pod Security Policies (PSP) were deprecated in Kubernetes 1.21 and removed in 1.25oneuptime.com
  2. Pod Security Standards (PSS) combined with Pod Security Admission (PSA), is simpler to understand, easier to implement, and built into every modern Kubernetes clusteroneuptime.com
  3. Pod Security Admission and Pod Security Standards, which apply simpler, namespace-level security profiles (Privileged, Baseline, Restricted)groundcover.com
  4. This can be done effectively using a combination of dry-run and audit and warn modeskubernetes.io
  5. If your cluster is running 1.25 or later and you relied on PSP, you've either migrated already or you're using a webhook shim to keep it workingcodingprotocols.com
  6. Pod Security Admission a 3rd party admission plugin, that you deploy and configure yourselfkubernetes.io