Skip to main content
cd ../config-traps
risk/register/static-pod-security-admission-exemptions-override-namespace-enforce-labels.html
Kubernetes Pod Securityhigh severityKubernetes

Pod Security Admission Exemptions Override Namespace Enforce Labels

Severity
high
Reviewed
7 Aug 2026
Remediation
~20 minutes
Overview

A namespace shows a correct PodSecurity enforce label while a cluster-wide static exemption silently bypasses it for one identity, with no denial or warning recorded.

Operational summary

At a glance

Symptom
A namespace enforcing the restricted Pod Security Admission (PSA) profile keeps admitting privileged pods from one specific service account or namespace, even though kubectl…
Likely cause
Kubernetes Pod Security Admission supports a second, cluster-wide control surface that sits outside namespace labels entirely: static exemptions configured in the AdmissionConfiguration file loaded…
Impact
The immediate impact is a silent security boundary failure: a service account, automation identity or legacy namespace that was exempted during an earlier migration continues to run privileged…
Verification signal
Confirm the fix by testing the previously exempt identity, not just the namespace label.
Safe correction
Correct the gap by removing the specific exemption entry rather than only re-checking or re-applying namespace labels, which will have no effect on an exempt identity.
Rollback or recovery
If kube-apiserver fails to reach Ready after the edit, restore the timestamped backup file to the exact original path immediately and confirm kubelet recreates a healthy static pod…

Symptom

A namespace enforcing the restricted Pod Security Admission (PSA) profile keeps admitting privileged pods from one specific service account or namespace, even though kubectl get namespace --show-labels confirms the correct pod-security.kubernetes.io/enforce=restricted label is present and every other workload in the same namespace is correctly blocked.

False Assumption

Platform teams commonly assume that the three PSA namespace labels — enforce, audit and warn — are the complete and only control surface for Pod Security Admission. The working assumption is that once a namespace carries the correct enforce label, every pod creation request in that namespace is evaluated against the named policy level with no other override path.

Root Cause

Kubernetes Pod Security Admission supports a second, cluster-wide control surface that sits outside namespace labels entirely: static exemptions configured in the AdmissionConfiguration file loaded by kube-apiserver through the --admission-control-config-file flag. That file can list specific usernames, namespaces or RuntimeClass names that are exempt from PodSecurity evaluation. Requests matching an exemption bypass enforcement regardless of what the namespace label says, and by design they do not generate a denial, a warning annotation or an audit event describing the bypass. The namespace label continues to display the intended policy correctly; it simply no longer describes what actually happens to the exempt identity’s pods.

This is consistent with the documented Kubernetes security model, in which policy controls span multiple control-plane mechanisms rather than a single namespace-level setting.

This trap assumes a self-managed control plane where operators have file-level access to the AdmissionConfiguration; many managed Kubernetes services do not expose this surface to customers, in which case the exemptions are provider-controlled and enforcement guarantees must be confirmed with the vendor directly.

Impact

The immediate impact is a silent security boundary failure: a service account, automation identity or legacy namespace that was exempted during an earlier migration continues to run privileged or host-namespace-sharing pods inside a namespace that every dashboard, label query and policy report shows as fully enforced. Because no denial event or warning is recorded for the exempt path, the gap is invisible to normal namespace-label audits and to log-based alerting built only around PodSecurity admission denials.

This is particularly likely wherever exemptions were added during a Pod Security Policy migration to grant temporary breathing room for legacy workloads, then never removed once namespace labels were tightened to restricted; the exemption quietly outlives the migration it was created for.

Diagnosis

Namespace labels cannot confirm actual enforcement on their own. Two additional checks are required.

First, confirm whether the control plane loads a static admission configuration file at all; this only applies to self-managed control planes such as kubeadm clusters, not to most managed Kubernetes offerings where the flag is not exposed to cluster operators.

ps -ef | grep kube-apiserver | grep -- --admission-control-config-file

Second, if the flag is present, read the referenced file and locate the PodSecurity plugin’s exemptions block:

apiVersion: apiserver.config.k8s.io/v1
kind: AdmissionConfiguration
plugins:
- name: PodSecurity
  configuration:
    apiVersion: pod-security.admission.config.k8s.io/v1
    kind: PodSecurityConfiguration
    exemptions:
      usernames: []
      namespaces: []
      runtimeClasses: []

Any identity listed under namespaces, usernames or runtimeClasses bypasses PodSecurity evaluation entirely for matching requests, independent of the namespace’s enforce label.

Correction

Correct the gap by removing the specific exemption entry rather than only re-checking or re-applying namespace labels, which will have no effect on an exempt identity. Take a timestamped backup of the file first, since a syntax error in this file can prevent kube-apiserver from starting.

cp /path/to/admission-control-config.yaml /path/to/admission-control-config.yaml.bak-$(date +%Y%m%d%H%M)

Edit the backed-up file to remove the exempt namespace, username or runtimeClass entry, save it at the exact path referenced by the kube-apiserver flag, and allow kubelet to recreate the static kube-apiserver pod. On managed Kubernetes offerings where this flag is not exposed, the correction is not available to cluster operators directly; escalate to the platform provider’s support channel instead of attempting a workaround.

Validation

Confirm the fix by testing the previously exempt identity, not just the namespace label. Attempt to create a privileged test pod using the identity that was formerly exempt and confirm it is now rejected with a PodSecurity admission denial rather than silently admitted. Re-check the namespace enforce label to confirm it is unchanged, and confirm every kube-apiserver replica returns to a Ready state after the configuration reload with no CrashLoopBackOff.

Rollback

If kube-apiserver fails to reach Ready after the edit, restore the timestamped backup file to the exact original path immediately and confirm kubelet recreates a healthy static pod before taking any further action. If a legitimate exemption is removed in error and a currently trusted automation identity is unexpectedly blocked, restore that specific exemption entry from the backup and revalidate the intended workload before pursuing a scoped exemption removal.

Prevention

Treat PodSecurity static exemptions as a separate, cluster-scoped inventory that must be reviewed alongside namespace labels, not assumed away by them. Maintain a documented list of every exempt username, namespace and runtimeClass together with the reason for the exemption and a review date, and confirm during any Pod Security audit that the exemptions list, not only the namespace labels, matches the intended enforcement boundary for the cluster version in use.

Where possible, prefer scoped, time-bound exemptions tied to a tracked ticket over indefinite entries, and add a periodic diff check that compares the live exemptions block against the last reviewed baseline so an untracked addition or leftover entry is flagged before the next enforcement audit.

03

Apply the safer control

Before you change production

Confirm the affected scope, export the current configuration, and test the replacement control in a non-production environment first.

Fix commands and configuration

restricted
kubectl get namespace --show-labels
pod-security.kubernetes.io/enforce=restricted
04

Verify, roll back or escalate

Verify

Confirm the fix by testing the previously exempt identity, not just the namespace label.

Rollback

If kube-apiserver fails to reach Ready after the edit, restore the timestamped backup file to the exact original path immediately and confirm kubelet recreates a healthy static pod before taking any further action.

Escalate

Escalate when the blast radius is uncertain, the control cannot be tested safely, or remediation requires an outage or security exception.

After remediation

Further reading stays below the corrective workflow and is selected by platform, category and shared technical keywords.

Discover more

Connected KBY resources