More Info:
Containers running as root (UID 0) increase the impact of a container escape. Require workloads to run as non-root.Risk Level
HighAddress
SecurityCompliance Standards
- CIS Kubernetes
Triage and Remediation
- Remediation
Remediation
Manual Steps
Manual Steps
-
List all namespaces and identify those that should host only non-root workloads
- Run on: any machine with kubectl access
- Command:
- Decide which namespaces must be restricted (for example:
prod,staging, or all except explicitly “infra/ops” namespaces that may need privileged containers).
-
Review existing PodSecurity admission / security policies per target namespace
- Run on: any machine with kubectl access
- Commands (use what’s relevant to your cluster):
- For built-in Pod Security Admission labels:
Look for labels like
pod-security.kubernetes.io/enforce=restricted(which already forbids root in most cases). - For PodSecurityPolicy (legacy clusters):
Review
runAsUserfields; confirmrule: MustRunAsNonRootorrule: MustRunAswith allrangeshavingmin > 0. - For common policy engines (example: Gatekeeper):
Review any constraints controlling
runAsUser/runAsNonRoot.
- For built-in Pod Security Admission labels:
-
Inspect current pod specs to find workloads that run as root or allow root
- Run on: any machine with kubectl access
- Command (namespaced, repeat for each important namespace):
- Use this output to identify pods that are explicitly root or unconstrained (no non-root requirement and no non-root namespace default).
-
Design and apply namespace-level policy requiring non-root UIDs
- Decide whether you can adopt a strict policy (no root anywhere in that namespace) or need exceptions.
- For Pod Security Admission (recommended where available), raise the namespace to at least
restricted(which enforces non-root by default) or confirm it is already at that level: - For policy engines (e.g., Gatekeeper/Kyverno), create or update a policy in each target namespace so that containers must set
runAsNonRoot: trueorrunAsUserwith UID > 0, and exclude 0 from any allowed ranges (done via their CRDs and admission rules).
-
Refactor or exempt workloads that cannot yet run as non-root
- Using the pods discovered in step 3, update their deployment/statefulset/daemonset manifests to set non-root contexts:
- Example change in the pod template:
And, if needed, per-container overrides under
spec.template.spec.containers[].securityContext.
- Example change in the pod template:
- If some workloads absolutely require root, formally document them and either:
- move them into a separate, tightly controlled namespace without the non-root policy, or
- configure scoped policy exceptions (policy engine exemptions or narrower admission rules) only for those workloads.
- Using the pods discovered in step 3, update their deployment/statefulset/daemonset manifests to set non-root contexts:
-
Verify enforcement and absence of new root-running pods
- Run on: any machine with kubectl access
- Attempt to create a pod that runs as root in a restricted namespace; it should be rejected:
- Confirm that admission rejects this pod (error message from PSA or your policy engine).
- Re-run the inspection from step 3 to ensure no newly created pods are running as root or without a non-root requirement.
Using kubectl
Using kubectl
Using kubectl
Run these commands from any machine withkubectl access.1. List all namespaces to scope your review
2. Inspect PodSecurity admission / PodSecurityPolicy-like controls per namespace
2.1. Check for Pod Security standards labels (if PodSecurity admission is enabled)
pod-security.kubernetes.io/enforce=baselineorrestrictedpod-security.kubernetes.io/enforce-version=v1.30(version may differ)
- Namespaces with no
pod-security.kubernetes.io/enforcelabel. - Namespaces where
pod-security.kubernetes.io/enforce=privileged. - Namespaces intended to be restricted that have no PodSecurity labels at all.
2.2. If using Gatekeeper/Kyverno or similar, list policies related to runAsNonRoot
For Gatekeeper (OPA):- No constraint/policy objects that mention
runAsNonRoot,runAsUser, orsecurityContext. - Policies exist but are
auditorwarnonly (noenforcemode) where enforcement is desired.
MustRunAsNonRoot-style behavior.3. Examine existing policies (where present) for MustRunAs / MustRunAsNonRoot semantics
Adjust the kind to match what you use (Gatekeeper/Kyverno/PSP-like CRDs).Example for a Gatekeeper constraint enforcing non-root:runAsNonRoot: truerunAsUserstrategy usingMustRunAswithrule: MustRunAsandrangesexcluding UID 0- Or explicit deny rules if
runAsUser: 0is set.
- No mention of
runAsNonRootorrunAsUserin the policy. MustRunAsranges include0(for examplemin: 0).- Policies scoped only to a small subset of namespaces, leaving others unprotected.
4. Spot-check workloads’ securityContext to understand current behavior
This does not replace policy-based control, but helps assess risk.For a given namespace (replacemyns):- Pods with
runAsUser: 0. - Pods with no
runAsUserand norunAsNonRoot, combined with images that default to root (this needs human review of the images). - Absence of any namespace-level policy while such pods exist.
5. Verify absence or presence of PodSecurityPolicy (older clusters only)
If your cluster might still have PSP:runAsUser:rule: MustRunAsNonRootorrule: MustRunAswithrangeswhere allmin> 0.
runAsUser.ruleisRunAsAny.MustRunAsranges include UID 0.- No PSP bound via RBAC to the service accounts in the reviewed namespaces.
These commands only surface configuration; they do not decide or apply the correct policy. Use the outputs to determine where you must define or tighten policies so that namespaces have an enforced strategy equivalent to
MustRunAsNonRoot or MustRunAs with UID ranges that exclude 0.Automation
Automation
- Re-run the script on any machine with kubectl access.
- A healthy state is when:
- Namespaces have appropriate policy labels (or equivalent policy via another controller).
- Section
[2]returns:- No lines with
podRunAsUser=0orcRunAsUser=0. - As few as possible lines where
runAsNonRootis nottrue; any remaining should be documented exceptions.
- No lines with

