Security context in Kubernetes is the set of fields, defined at either the pod or container level, that control the Linux security settings a container runs with — user ID, whether the root filesystem is writable, and which kernel capabilities are available — and it's the single most effective lever for reducing what an attacker can do after a container is compromised. A container escape or a code-execution bug is still bad with a locked-down securityContext, but the blast radius is dramatically smaller when the process inside was never running as root, couldn't write to its own filesystem, and had every unnecessary Linux capability dropped.
What's the difference between pod securitycontext and container-level settings?
A pod securitycontext sets defaults that apply to every container in the pod — things like the filesystem group ID (fsGroup) that determines ownership of mounted volumes, and a default runAsUser/runAsGroup that individual containers inherit unless they override it. Container-level securityContext fields, nested under each container spec, take precedence over the pod-level defaults and are where capability drops (capabilities.drop), read-only root filesystem (readOnlyRootFilesystem), and privilege escalation controls (allowPrivilegeEscalation) actually live. The practical pattern is setting sane pod-level defaults — non-root user, a shared fsGroup for volume ownership — and then tightening further at the container level for anything with elevated needs or, more commonly, for containers that need nothing extra at all and should be locked down as far as possible.
What does kubernetes runasuser actually control?
Kubernetes runasuser specifies the numeric user ID the container process runs as, overriding whatever USER directive (if any) is set in the image itself. This matters because a huge number of container images — including a lot of officially published ones — either default to running as root or don't set a USER at all, which means root is the default unless you explicitly override it in the pod spec. Setting runAsUser to a non-zero, non-privileged UID (and pairing it with runAsNonRoot: true, which makes Kubernetes refuse to start the pod if the resulting user is root) closes this gap without requiring you to rebuild every image your team depends on. This is exactly the same principle discussed for Node.js Docker images — the image should ideally set a non-root user itself, but runAsUser at the Kubernetes layer is the backstop when it doesn't.
How do kubernetes securitycontext capabilities drops work in practice?
Kubernetes securitycontext capabilities settings let you drop specific Linux kernel capabilities from a container's process — things like NET_RAW (needed for raw sockets, used in some network tools but rarely by application code), SYS_ADMIN (a notoriously broad capability that grants a wide range of privileged operations), and others that a typical web application or API server never actually needs. The safest starting policy is drop: ["ALL"] and then explicitly add back only the specific capabilities a workload genuinely requires — for most stateless application containers, that ends up being an empty add list, because HTTP servers, databases, and most application logic don't need any elevated capabilities at all. Containers that do need something specific — binding to a low port below 1024, for instance, which requires NET_BIND_SERVICE — should have that one capability added back explicitly rather than running with the full default set, which typically includes more capabilities than almost any workload actually uses.
What's a sane default securityContext policy to start from?
A reasonable baseline for most application workloads: runAsNonRoot: true, an explicit non-root runAsUser, readOnlyRootFilesystem: true with explicit emptyDir volumes mounted for any paths that genuinely need write access (temp files, cache directories), allowPrivilegeEscalation: false, and capabilities: { drop: ["ALL"] } with nothing added back unless a specific, justified need exists. Enforcing this consistently across a cluster is usually done with admission control — Pod Security Standards' "restricted" profile, or a policy engine like Kyverno or OPA Gatekeeper — rather than trusting every team to remember to set these fields correctly in every manifest. Scanning manifests and Helm charts for missing or weak securityContext settings before they reach a cluster is part of what infrastructure-as-code security tooling checks for, alongside the container image scanning that catches vulnerabilities in the packages running inside the pod, which the SCA product covers for the dependency layer.
Safeguard's container and IaC scanning flags pods and Deployments missing key securityContext hardening — root user defaults, missing capability drops, writable root filesystems — as part of the same pipeline that scans image dependencies, so a misconfigured securityContext and a vulnerable package in the same image surface together.
FAQ
Does security context in kubernetes protect against every container escape?
No — it reduces the blast radius and the attacker's available privileges after a compromise, but it doesn't prevent every kernel-level escape technique. It's a defense-in-depth layer, not a substitute for keeping the underlying node OS and container runtime patched.
What happens if I set runAsNonRoot: true but the image only has a root user?
The pod fails to start — Kubernetes checks the actual resulting UID at runtime and refuses to run it as root when runAsNonRoot is set, which is a useful safety net but means you need an image (or an explicit runAsUser override) that actually supports running as non-root.
Do I need readOnlyRootFilesystem for every container?
Not literally every one — some legitimately need to write to their own filesystem — but for most stateless application containers it's achievable, and any paths that do need write access can be mounted as explicit, size-limited emptyDir volumes rather than leaving the whole filesystem writable.
How do kubernetes securitycontext capabilities differ from Linux capabilities in general?
They're the same underlying Linux kernel capability model (the CAP_* set) — Kubernetes just exposes add/drop fields to control which of those capabilities a containerized process is granted, on top of whatever the container runtime and image already configure.