Privileged Containers: Risk, Detection and Exceptions
One boolean in a security context removes most of the isolation between a container and the node it runs on.
A privileged container is a container whose security context sets privileged: true. The Kubernetes Pod Security Standards describe privileged pods as ones that disable most security mechanisms, and ZopNight’s rule for this check states the practical consequence: a privileged container has effectively the same access as root on the node. A compromise inside it is a compromise of the node and of every other pod scheduled there.
Where it sits in Pod Security Standards
Kubernetes defines three Pod Security Standards levels:
- Privileged: an unrestricted policy providing the widest possible level of permissions, which allows known privilege escalations.
- Baseline: minimally restrictive, preventing known privilege escalations while allowing the default pod configuration. It requires
securityContext.privilegedto be unset or false on containers, init containers, and ephemeral containers, disallows sharing the host network, PID, and IPC namespaces, and limits added Linux capabilities to a short allowed list. - Restricted: current hardening practice, which additionally requires running as non-root and dropping all capabilities except
NET_BIND_SERVICE.
So privileged containers fail even the least strict non-privileged level. Running as root, by contrast, is allowed at Baseline and blocked only at Restricted.
Enforcing it
Kubernetes ships a built-in Pod Security admission controller. You apply a level to a namespace with a label of the form pod-security.kubernetes.io/<MODE>: <LEVEL>, where the mode is one of:
enforce: violating pods are rejectedaudit: violations are allowed but annotated in the audit logwarn: violations are allowed with a user-facing warning
A workable rollout is to label namespaces with warn and audit at Baseline first, fix what appears, then switch to enforce. Infrastructure namespaces that genuinely need privilege, such as those running CNI or storage node agents, can stay at the Privileged level on their own, so the exception is scoped to a namespace rather than granted cluster-wide.
Alternatives to privilege
Most workloads that ask for privileged: true need one or two specific powers. Kubernetes lets you add or drop individual Linux capabilities in the container’s securityContext.capabilities instead. Granting a single capability is still a risk to review, but it is far narrower than turning off isolation. Also note that allowPrivilegeEscalation: false cannot be combined with a privileged container; the two settings are inconsistent.
Is this a cost topic?
Indirectly. A privileged pod on a shared node pool raises the risk of every workload scheduled next to it. If the answer is to isolate sensitive workloads on dedicated node pools, each pool carries its own spare capacity, so the cluster needs more nodes for the same work. Removing unnecessary privilege keeps dense, shared node pools an option.
How ZopNight detects it
ZopNight’s Privileged Container rule runs on Deployments, StatefulSets, and DaemonSets across EKS, GKE, and AKS at critical severity, and it inspects init containers as well as main containers because a privileged init container is the same host-escape path. It sits beside the related checks for containers running as root and containers using the host network, described in Kubernetes workload rules. For how security findings and cost findings relate, see security vs cost trade-offs.
Questions we get a lot.
If yours isn't here, email us and we'll answer directly.
Does the Baseline level allow privileged containers?
No. Baseline requires the privileged field to be unset or false for containers, init containers, and ephemeral containers. Only the Privileged level allows them.
How do I allow a system agent that needs privilege?
Run it in its own namespace labelled at the Privileged level, and keep application namespaces at Baseline or Restricted with the enforce mode.