Unlabeled Namespaces Default to Privileged Pod Security Admission
An unlabeled Kubernetes namespace silently defaults to privileged Pod Security Admission, letting non-compliant pods through with no enforcement. Diagnose, label, validate and roll back safely.
Operational summary
At a glance
- Symptom
- A namespace that the platform team believes is protected by Kubernetes Pod Security Admission accepts a pod spec requesting privileged: true, hostNetwork: true and…
- Likely cause
- The affected namespace was created by a provisioning script that never set any pod-security.kubernetes.io/* label.
- Impact
- Workloads in the unlabeled namespace can request host namespaces, privileged containers, arbitrary Linux capabilities and root-writable host paths with no admission-time check.
- Verification signal
- Prove the namespace now blocks non-compliant pod specs before relying on it.
- Safe correction
- Apply an explicit enforce label so the control plane actually blocks non-compliant pod specs going forward.
- Rollback or recovery
- Remove the enforce label immediately if the change blocks a legitimate deployment.
Symptom
A namespace that the platform team believes is protected by Kubernetes Pod Security Admission accepts a pod spec requesting privileged: true, hostNetwork: true and a hostPath volume without any admission rejection. A later security scan flags the running workload as non-compliant, yet nothing blocked it at creation time even though the cluster runs a supported Kubernetes release with the built-in PodSecurity admission plugin available.
False Assumption
The team assumes that because Pod Security Admission is a built-in admission controller present in a supported Kubernetes release, every namespace is automatically restricted to a safe baseline. That is not how the controller works. Enforcement is scoped per namespace and depends entirely on an explicit pod-security.kubernetes.io/enforce label being present. A namespace with the plugin available but no enforce label is treated as unrestricted, and audit or warn labels, if present instead, only log or display a warning without blocking anything.
Root Cause
The affected namespace was created by a provisioning script that never set any pod-security.kubernetes.io/* label. With no enforce label, the effective policy level for that namespace is privileged, meaning no field-level restriction applies to pod specs submitted there. The organisation’s written security baseline calls for a restricted posture cluster-wide, but that intent was never encoded as a namespace label, so the control plane has nothing concrete to enforce.
Impact
Workloads in the unlabeled namespace can request host namespaces, privileged containers, arbitrary Linux capabilities and root-writable host paths with no admission-time check. This materially increases the blast radius of a compromised container: an attacker who gains code execution in a privileged pod can typically pivot toward the underlying node, other pods scheduled on that node, and cluster-wide credentials reachable from the host. Because the gap produces no error and no alert, it usually surfaces first in a post-hoc security scan or an incident rather than in change control.
Diagnosis
Confirm the gap with read-only checks before changing anything.
- List every namespace and its Pod Security labels with
kubectl get ns --show-labels. Any namespace missingpod-security.kubernetes.io/enforceis currently unrestricted. - Inspect running pods in the suspect namespace for privileged or host-access fields, for example
kubectl get pod -n <namespace> -o json | grep -E "privileged|hostNetwork|hostPath". - Confirm the PodSecurity admission plugin is actually enabled on the control plane by checking your managed-Kubernetes provider’s admission configuration documentation for the running control-plane version, or the kube-apiserver static configuration on self-managed clusters.
Correction
Apply an explicit enforce label so the control plane actually blocks non-compliant pod specs going forward. Start with audit and warn only, to surface the effect without breaking anything, using kubectl label namespace <namespace> pod-security.kubernetes.io/audit=restricted pod-security.kubernetes.io/warn=restricted --overwrite. Review the resulting kubectl warnings and audit log entries against existing workloads for a full deployment cycle. Once no legitimate workload depends on a restricted field, apply enforcement with kubectl label namespace <namespace> pod-security.kubernetes.io/enforce=restricted pod-security.kubernetes.io/enforce-version=latest --overwrite.
Validation
Prove the namespace now blocks non-compliant pod specs before relying on it. Submit a deliberately non-compliant manifest as a server-side dry run with kubectl apply --dry-run=server -f test-privileged-pod.yaml, where the manifest requests privileged: true and hostNetwork: true. The API server must return a non-zero exit and an admission error naming the violated restricted-policy fields, and the object must not be created. Separately confirm the label is present with the expected value using kubectl get ns <namespace> --show-labels.
Rollback
Remove the enforce label immediately if the change blocks a legitimate deployment. Run kubectl label namespace <namespace> pod-security.kubernetes.io/enforce- to delete the label and revert the namespace to its previous, unrestricted admission behaviour. After rollback, check the health of any deployment that failed during the enforcement window with kubectl rollout status deployment/<name> -n <namespace>, remediate the offending pod field, and only reapply enforcement once the workload is compliant.
Prevention
Treat Pod Security Admission labelling as a mandatory, automated step in namespace provisioning rather than a manual follow-up.
- Add enforce, audit and warn labels to the namespace template used by your provisioning tool, whether a Terraform module, GitOps chart or Cluster API manifest, so no namespace is created without them.
- Add a scheduled, read-only compliance check that runs
kubectl get ns --show-labelsand alerts whenever a namespace lacks an enforce label. - Record the intended policy level in the same change request that creates the namespace, so a missing label is a visible deviation rather than a silent default.
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
privileged: truehostNetwork: truehostPathVerify, roll back or escalate
Verify
Prove the namespace now blocks non-compliant pod specs before relying on it.
Rollback
Remove the enforce label immediately if the change blocks a legitimate deployment.
Escalate
Escalate when the blast radius is uncertain, the control cannot be tested safely, or remediation requires an outage or security exception.