Skip to main content

More Info:

Do not generally permit containers to be run as the root user.

Risk Level

Critical

Address

Security

Compliance Standards

  • APRA CPS 234 (Australia)
  • BSI C5 (Germany)
  • Brazil LGPD
  • CCPA / CPRA (California)
  • CIS Critical Security Controls v8
  • CIS EKS
  • CMMC 2.0
  • CSA Cloud Controls Matrix v4
  • DPDPA
  • Digital Operational Resilience Act (EU)
  • Essential 8
  • ISO/IEC 27017
  • ISO/IEC 27018
  • ISO/IEC 27701
  • KSA PDPL
  • MAS Technology Risk Management (Singapore)
  • MITRE ATT&CK (Cloud)
  • NIS2 Directive
  • NIST SP 800-171
  • NYDFS 23 NYCRR 500
  • SWIFT Customer Security Controls Framework
  • Sarbanes-Oxley IT General Controls
  • UK NCSC Cyber Assessment Framework

Triage and Remediation

Remediation

Manual Steps

  1. Identify where root is allowed today
    • On any machine with kubectl access:
    • Review any existing PodSecurityPolicies (if still in use) and RBAC bindings to see which subjects (users, groups, service accounts) are allowed to use PSPs or policies that let containers run as root.
  2. Review current admission / security posture per namespace
    • On any machine with kubectl access:
    • Use these outputs to map which namespaces are enforcing non-root (via PSP, Pod Security Admission labels, or other policies) and which are not.
  3. Identify workloads currently running as root or likely to run as root
    • On any machine with kubectl access:
    • Cross-check with image documentation or Dockerfiles for key workloads to determine whether they expect to run as root.
  4. Decide namespace policy: where to forbid root and where (if anywhere) to allow it
    • Using the evidence above, classify namespaces into:
      • Strict: must not allow root containers (most application namespaces).
      • Exception: temporarily or permanently require root (e.g., system add-ons, legacy apps, node-level agents).
    • For each exception namespace, document:
      • Business/technical justification for root.
      • Owner and review date.
      • Plan (if any) to migrate to non-root.
  5. Implement or tighten admission controls to enforce non-root
    • On any machine with kubectl access, for namespaces that should be strict, configure or adjust admission policy according to your environment:
      • If you still use PodSecurityPolicy, ensure PSPs used by those namespaces have:
        or:
      • Update RBAC so only appropriate subjects can use any PSP that permits root.
      • If using Pod Security Admission or a 3rd-party policy engine (OPA/Gatekeeper, Kyverno, etc.), configure equivalent policies that deny pods whose containers can run as UID 0, except in documented exception namespaces.
  6. Re-verify and monitor
    • On any machine with kubectl access, re-check that policies and workloads align with your decisions:
    • Attempt to deploy a test pod running as root into a strict namespace and confirm it is rejected by admission controls.

Using kubectl

Run these commands from any machine with kubectl access.

1. List namespaces and existing PodSecurityPolicies (if PSPs are enabled)

Problem indication:
  • No PodSecurityPolicies exist, or
  • There is no PSP clearly intended to restrict runAsUser away from root.

2. Inspect PodSecurityPolicies for root-user allowances

In the output, examine each PSP’s spec.runAsUser:You are looking for entries like:
or:
or any ranges that include 0.Problem indication:
  • rule: RunAsAny, or
  • rule: MustRunAs with any range that includes UID 0, or
  • runAsUser missing entirely (treated as allowing root, depending on other policies).
A compliant PSP for this control will have:
or:

3. Check which PSPs are actually usable in each namespace

First, list service accounts and their PSP-related bindings:
Then, for bindings that grant use on PSPs, get details:
Problem indication:
  • Workload service accounts (or system:serviceaccounts:<ns>) are bound to PSPs that:
    • have runAsUser.rule: RunAsAny, or
    • allow UID ranges including 0,
    • or there is no binding to any restrictive PSP, so only permissive/default PSPs apply.

4. Spot workloads currently configured to run as root (for human review)

This does not prove admission policy, but highlights where root may be in use.
Problem indication:
  • Pods or containers explicitly configured with runAsUser: 0.
  • Pods/containers without runAsNonRoot: true and no policy preventing root, combined with permissive PSPs from steps 2–3.

5. Verification after any policy changes

Re-run:
Confirm:
  • Every PSP intended for general workloads has .spec.runAsUser.rule set to MustRunAsNonRoot or MustRunAs with UID ranges that do not include 0.
  • RBAC bindings from step 3 ensure that regular workload service accounts are not able to use any PSP that allows RunAsAny or UID 0.
Human judgement is required:
  • Decide which namespaces/workloads, if any, are allowed to run as root.
  • Ensure that PSPs and RBAC bindings reflect that decision, and that unrestricted PSPs are not broadly bound.

Additional Reading: