Skip to main content

Find Privileged, Root and Host-Network Pods in Kubernetes

Four kubectl queries and one dry-run label show which workloads would fail the Pod Security Standards before you enforce them.

Privileged containers, containers running as root, Pods sharing the host network and Ingresses serving plain HTTP are the findings that turn a compromised container into a compromised node or a leaked credential. Kubernetes already defines where the lines are: the Pod Security Standards have three levels, privileged, baseline and restricted. Privileged containers and host namespaces are disallowed from baseline up; running as non-root is required at restricted. This guide finds the offenders with read-only queries, then uses Pod Security Admission in dry-run to preview what enforcement would reject.

Requirements

  • kubectl with get and list on Pods, Ingresses and Namespaces cluster-wide, and patch on Namespaces for step 5.
  • jq.
  • Works the same on EKS, GKE and AKS; nothing here is provider-specific.

1. Privileged containers

Terminal window
kubectl get pods -A -o json | jq -r '.items[]
| select(any(.spec.containers[], (.spec.initContainers // [])[];
.securityContext.privileged == true))
| "\(.metadata.namespace)/\(.metadata.name)"'

A privileged container disables most of the isolation the node gives it.

2. Host network, PID or IPC

Terminal window
kubectl get pods -A -o json | jq -r '.items[]
| select(.spec.hostNetwork == true or .spec.hostPID == true or .spec.hostIPC == true)
| "\(.metadata.namespace)/\(.metadata.name) net=\(.spec.hostNetwork) pid=\(.spec.hostPID) ipc=\(.spec.hostIPC)"'

3. Containers that may run as root

Terminal window
kubectl get pods -A -o json | jq -r '.items[] | . as $p
| .spec.containers[]
| select((.securityContext.runAsNonRoot // $p.spec.securityContext.runAsNonRoot // false) != true
or (.securityContext.runAsUser // $p.spec.securityContext.runAsUser) == 0)
| "\($p.metadata.namespace)/\($p.metadata.name) container=\(.name)"'

This lists containers where neither the container nor the Pod sets runAsNonRoot: true, or where runAsUser is 0. A hit means the spec does not prevent root. The image may still switch to a non-root user, but the Pod Security Standards judge the spec, and so should you.

4. Ingresses without TLS

Terminal window
kubectl get ingress -A -o json | jq -r '.items[]
| select((.spec.tls // []) | length == 0)
| "\(.metadata.namespace)/\(.metadata.name) hosts=\([.spec.rules[]?.host] | join(","))"'

TLS can also be terminated in front of the cluster, for example at a cloud load balancer, so confirm how traffic reaches the Ingress before treating a hit as exposure.

5. Preview enforcement with a dry run

Pod Security Admission reads namespace labels of the form pod-security.kubernetes.io/MODE: LEVEL, where the mode is enforce, audit or warn. When you add or change an enforce label, the admission plugin tests each existing Pod in the namespace against the new level and returns violations as warnings. With --dry-run=server nothing is changed:

Terminal window
kubectl label --dry-run=server --overwrite ns --all \
pod-security.kubernetes.io/enforce=baseline

Every warning names a namespace and the Pods that would be rejected at that level. Fix or exempt those, then roll out in stages: warn and audit first, enforce once the warnings stop.

Terminal window
kubectl label --overwrite ns shop \
pod-security.kubernetes.io/warn=restricted \
pod-security.kubernetes.io/audit=restricted \
pod-security.kubernetes.io/enforce=baseline

Check your progress

Re-run queries 1 to 4 after each fix and keep the output in the change record. A namespace is ready for enforce=restricted when the dry-run in step 5, run with restricted, returns no warnings for it.

Where ZopNight helps

ZopNight’s Kubernetes workload rules cover the same ground continuously on connected EKS, GKE and AKS clusters: privileged containers, root users, host network and missing TLS appear under the security category of its recommendations, alongside reliability rules such as missing requests and single replicas. Before any change is applied through a remediation, the blast radius view shows the connected resources it would touch and a risk score. What a privileged container can do and the Kubernetes workload rules go deeper on each finding.

Stop watching the waste.
Start cutting it.

See. Find. Fix. Automatic.

Connect your first cloud account in under 5 minutes. See your first remediation in under 7. No credit card required.

CDCR connect detect classify remediate
full audit every action traceable
read-only default access
Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console· Multi-cloud automation· Production-ready in 30 min· SOC 2 · ISO 27001· 20–60% off the bill, first month· 4 platforms · 1 console·