Kubernetes Security Context Audit: Five Flags Worth Checking
Secrets are not the only dangerous thing in a manifest. Five configuration flags decide how much damage a compromised container can do, and every one of them is easy to set carelessly and hard to notice in review. The Cloud Config Sanitizer audits them alongside its secret detection: privileged: true, hostNetwork: true, and hostPID: true are flagged wherever they appear, and a securityContext that omits readOnlyRootFilesystem or runAsNonRoot draws an absent marker. Each of these findings arrives at info severity, deliberately below the credential findings, because the right response is a deliberate decision rather than automatic redaction. Kubernetes documents the same concerns in its Pod Security Standards, where the baseline and restricted profiles exist precisely to rule these settings out by default.1
A reviewer skimming a pull request rarely spots a missing field, yet a missing field is exactly what turns an ordinary container escape into full node compromise.2
The three escape hatches: privileged, hostNetwork, hostPID
Privileged mode is the bluntest of the three. A container with privileged: true runs with essentially the node's full capabilities, able to mount host filesystems, load kernel modules, and step outside its namespace, while hostPID: true lets processes in the container see and signal every process on the node, turning process inspection into an attack surface.3 hostNetwork: true shares the node's network namespace, exposing localhost-bound node services to the pod and letting it bind node ports directly.2 The baseline profile of the Pod Security Standards forbids all three outright.1
When these flags need a documented reason
None of the three is inherently wrong to set; the failure mode is setting one without anyone being able to say why. Consequently, any of these flags in a manifest should map to a documented reason, typically a CNI plugin, node agent, or monitoring daemon; a web application with one of them set is a finding worth escalating past info in your own review.
Combining two of the three flags on the same pod, which some copied examples do without needing to, compounds the blast radius well beyond what either flag grants alone. Reviewing manifests for that pattern specifically, rather than treating each flag as an isolated checkbox, catches the riskiest combinations before they ship.
The two hardening defaults: read-only root and non-root user
Absence is the finding here. When a securityContext block exists but readOnlyRootFilesystem is unset or false, an attacker with code execution inside the container can write to the container filesystem, drop tools, and modify binaries; setting it true forces all writes through explicit volume mounts you chose. Similarly, an unset or false runAsNonRoot leaves the container free to run as root, so a container-runtime vulnerability escalates further than it needed to.4 The sanitizer flags both conditions with an absent marker at the exact path where the field belongs.
An empty findings list is not a clean bill of health
That distinction trips up more reviews than the flags themselves do, since a quiet audit output reads as reassuring when it is really just uninformative. One honest subtlety: the absent checks run on securityContext blocks the manifest actually contains, so a pod with no securityContext at all yields no such findings.
Reading zero flags as a clean audit is therefore wrong; it may mean nothing was declared. Adding an explicit securityContext block, even a minimal one, is the precondition for either hardening check to ever fire in the first place. Treat a clean scan as a prompt to check the manifest's structure rather than proof the workload is already hardened.
Running the audit and acting on info findings
Paste any manifest in, and the findings table surfaces privileged, hostNetwork, and hostPID wherever they appear, the same way it lets you check for privileged mode in a borrowed Helm chart; it also catches a securityContext block that never set readOnlyRootFilesystem, flagged at the exact path where the field belongs.
Info severity means the sanitized output leaves these values unchanged; a boolean cannot be redacted into a placeholder without changing behavior, so the tool surfaces rather than rewrites. Work the list in two passes: first confirm each escape-hatch flag has a justification, then add the missing hardening fields with explicit true values. Building on this, namespaces enforcing the restricted profile will reject regressions at admission time instead of relying on the next manual audit to catch them.5 Pairing the scan with admission enforcement turns a one-time cleanup into a standing guarantee that new manifests cannot quietly regress past it.
Two passes, run in a fixed order
Working the list in two passes keeps the audit from turning into an unfocused scroll through findings: confirm each escape-hatch flag against a real justification first, then add the missing hardening fields with explicit true values afterward. Treating both passes as separate steps keeps a legitimate hostNetwork daemon from being lumped in with a securityContext block that just needs two more lines.
Pod Security Admission is what turns this from a one-time audit into a standing guarantee, since a namespace enforcing the restricted profile rejects a regression at admission time rather than waiting for the next manual pass to catch it.5 Pairing the scan here with that enforcement is what keeps a hardened manifest hardened.
When to use this
Run this audit before promoting a manifest to a shared or production namespace, when reviewing third-party charts and examples copied from documentation, and during periodic hardening passes over existing workloads. It pairs naturally with secret scanning on the same paste, so one check covers both what the manifest leaks and what it permits. Teams introducing Pod Security Admission for the first time can also use it to preview which existing manifests would fail the restricted profile before enforcement is switched on.
Examples
A monitoring agent chart ships with privileged: true
The flag appears as an info finding at its exact path. Node-level agents often genuinely need it; the audit output is your prompt to verify the vendor's documentation says so, and to confine the setting to that DaemonSet rather than letting it spread by copy-paste.
A web app Deployment has a securityContext with only fsGroup set
securityContext: fsGroup: 2000
securityContext: fsGroup: 2000 runAsNonRoot: true readOnlyRootFilesystem: true
Both absences are flagged. Adding the explicit fields hardens the pod, though readOnlyRootFilesystem belongs at the container level and may require an emptyDir mount for writable paths like /tmp.
A manifest shows no security findings at all
Check whether it declares a securityContext before celebrating. The absent-field checks evaluate declared blocks, so a manifest with no securityContext produces no absence findings. Add the block with hardening defaults and re-run to confirm.
- 1.
Kubernetes, "Pod Security Standards," kubernetes.io, accessed July 2026. https://kubernetes.io/docs/concepts/security/pod-security-standards/
- 2.
System Hardening, "From Pod Breakout to Kubelet Credential Theft: The Node Compromise Attack Chain," systemshardening.com, accessed July 2026. https://www.systemshardening.com/articles/linux/pod-breakout-to-kubelet-credential-theft/
- 3.
Kubernetes, "Configure a Security Context for a Pod or Container," kubernetes.io, accessed July 2026. https://kubernetes.io/docs/tasks/configure-pod-container/security-context/
- 4.
System Hardening, "Pod Security Context Deep Dive: runAsNonRoot, readOnlyRootFilesystem, and Capabilities," systemshardening.com, accessed July 2026. https://www.systemshardening.com/articles/kubernetes/pod-security-context/
- 5.
AWS, "Pod Security - Amazon EKS Best Practices," docs.aws.amazon.com, accessed July 2026. https://docs.aws.amazon.com/eks/latest/best-practices/pod-security.html