Enforce Pod Security Standard Baseline Profile Or Stricter
More Info:
Pod Security Admission should enforce at least the Baseline profile on every namespace containing user workloads to block privileged and unsafe pod configurations. Namespaces without an enforce label are unprotected.
Risk Level
Critical
Address
Security
Compliance Standards
- CIS GKE
Triage and Remediation
- Remediation
Remediation
Manual Steps
-
On any machine with kubectl access, list all namespaces and see which already have an enforce label (and what level it is set to):
kubectl get ns --show-labelsFocus on the
pod-security.kubernetes.io/enforcelabel; note any namespaces withprivileged,baseline,restricted, or no value. -
Identify namespaces that currently enforce a profile weaker than Baseline or have no enforce label:
kubectl get ns -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.metadata.labels.pod-security\.kubernetes\.io/enforce}{"\n"}' \| sortFrom this list, mark:
- Namespaces with empty (no label) or missing value.
- Namespaces with
privileged(weaker than Baseline). - Exclude known system/control-plane namespaces if your policy allows different treatment there (e.g.
kube-system,kube-public,kube-node-lease, provider-specific system namespaces).
-
For each remaining (non-system) namespace, determine whether it hosts user workloads:
for ns in $(kubectl get ns -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}'); doecho "### $ns"kubectl get pods -n "$ns" --no-headers 2>/dev/null | headechodoneAlternatively, check selectively for any candidate namespace from step 2:
kubectl get pods -n <namespace> -o wideTreat any namespace running business applications, batch jobs, or user-facing services as a “user workload” namespace.
-
For each namespace that both (a) contains user workloads and (b) lacks an adequate enforce label (none/privileged), decide the target profile:
- Minimum:
baseline(per remediation). - Prefer
restrictedif workloads are known to be hardened and compatible.
Before changing, confirm with application owners whether their workloads depend on privileged containers, hostPath volumes, host networking, or other disallowed settings under Baseline/Restricted.
- Minimum:
-
Apply or adjust the enforce label using kubectl on each chosen namespace (any machine with kubectl access):
- To enforce Baseline (minimum required):
kubectl label namespace <namespace> pod-security.kubernetes.io/enforce=baseline --overwrite
- To enforce a stricter Restricted profile (if suitable):
kubectl label namespace <namespace> pod-security.kubernetes.io/enforce=restricted --overwrite
Be aware: once set, new non-compliant Pods in that namespace will be rejected. Existing Pods keep running but may fail on restart if non-compliant.
- To enforce Baseline (minimum required):
-
Verify that all user-workload namespaces now enforce at least Baseline:
kubectl get ns -o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.metadata.labels.pod-security\.kubernetes\.io/enforce}{"\n"}' \| sortOptionally, rerun the original audit to confirm the delta between Baseline-enforced namespaces and all namespaces, then manually confirm that any remaining unlabelled namespaces indeed do not contain user workloads or are intentionally exempt:
diff \<(kubectl get namespace -l pod-security.kubernetes.io/enforce=baseline -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}') \<(kubectl get namespace -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}')
Using kubectl
# 1) List all namespaces and show their Pod Security enforce level
# Run on: any machine with kubectl access
kubectl get ns \
-o custom-columns='NAME:.metadata.name,ENFORCE:.metadata.labels.pod-security\.kubernetes\.io/enforce' \
--sort-by=.metadata.name
- Problem indication: Any namespace that runs or may run user workloads where
ENFORCEis empty/<none>or weaker than your policy (e.g.,privilegedwhen you requirebaselineorrestricted).
# 2) Show only namespaces that currently have NO enforce label
# Run on: any machine with kubectl access
kubectl get ns \
-o jsonpath='{range .items[?(!@.metadata.labels.pod-security\.kubernetes\.io/enforce)]}{.metadata.name}{"\n"}{end}'
- Problem indication: Any listed namespace that hosts user workloads (applications, jobs, CI workloads, etc.) needs human review; if they should be protected, they are currently unprotected by Pod Security Admission.
# 3) Compare enforced-baseline namespaces vs all namespaces (audit-equivalent)
# Run on: any machine with kubectl access
diff \
<(kubectl get ns -l pod-security.kubernetes.io/enforce=baseline -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}') \
<(kubectl get ns -o jsonpath='{range .items[*]}{.metadata.name}{"\n"}')
- Problem indication: Any lines starting with
>are namespaces that do not havepod-security.kubernetes.io/enforce=baseline. For each of those, a human must decide:- Does this namespace contain or will it contain user workloads?
- If yes, should it enforce
baselineor a stricter profile (restricted), or be exempt for a clear reason?
# 4) Inspect workload types in a specific namespace (replace with a candidate from above)
# Run on: any machine with kubectl access
NAMESPACE=example-namespace
kubectl get deploy,statefulset,daemonset,job,cronjob,pod -n "$NAMESPACE" \
-o custom-columns='KIND:.kind,NAME:.metadata.name' 2>/dev/null
- Problem indication: If this shows user workloads and the namespace lacks an appropriate
pod-security.kubernetes.io/enforcelabel (or is weaker than your policy), that namespace is in scope for remediation.
Automation
#!/usr/bin/env bash
# Purpose: Report namespaces that do NOT have Pod Security Admission enforce label
# Scope: Run on any machine with kubectl access and correct context
set -euo pipefail
echo "=== Pod Security Admission enforce label report (baseline or stricter) ==="
echo
echo "Kubernetes context:"
kubectl config current-context
echo
echo "All namespaces and their enforce labels:"
kubectl get ns -o custom-columns='NAME:.metadata.name,ENFORCE:.metadata.labels.pod-security\.kubernetes\.io/enforce' | sort
echo
echo "Namespaces missing an enforce label (UNPROTECTED):"
kubectl get ns \
-o jsonpath='{range .items[?(!@.metadata.labels.pod-security\.kubernetes\.io/enforce)]}{.metadata.name}{"\n"}{end}' \
| sort || true
echo
echo "Namespaces with enforce=baseline (MEETS MINIMUM):"
kubectl get ns -l pod-security.kubernetes.io/enforce=baseline \
-o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' \
| sort || true
echo
echo "Namespaces with enforce=strict (EXCEEDS MINIMUM):"
kubectl get ns -l pod-security.kubernetes.io/enforce=strict \
-o jsonpath='{range .items[*]}{.metadata.name}{"\n"}{end}' \
| sort || true
echo
cat <<'EOF'
How to interpret this report:
- Any namespace listed under "Namespaces missing an enforce label (UNPROTECTED)"
does NOT have Pod Security Admission enforce policy set and should be reviewed.
- For namespaces that contain user workloads:
- They should NOT appear as UNPROTECTED.
- They should appear under either:
- "Namespaces with enforce=baseline (MEETS MINIMUM)", or
- "Namespaces with enforce=strict (EXCEEDS MINIMUM)".
This check is MANUAL:
- You must decide, per namespace, whether it hosts user workloads and whether
applying an enforce label is safe for existing pods and controllers.
- To remediate a chosen namespace (example: my-namespace), run:
kubectl label namespace my-namespace pod-security.kubernetes.io/enforce=baseline --overwrite
EOF