CoursesRuntime & eBPF securityKernel hardening & isolation

Capabilities, namespaces & cgroups

Drop ALL, non-root, and the isolation primitives.

Advanced30 min · lesson 6 of 15

Namespaces, capabilities, and cgroups are the primitives every container is built from, and hardening them is what makes the container boundary meaningful. A container is just a process with isolated views and reduced privilege — so the security work is minimizing that privilege and tightening those views.

Capabilities: split and drop root

The Linux kernel splits root’s power into roughly forty capabilities — CAP_NET_BIND_SERVICE, CAP_SYS_ADMIN, CAP_SYS_PTRACE, CAP_DAC_READ_SEARCH, and so on. A container should drop ALL and add back only the few it genuinely needs; most web workloads need none. CAP_SYS_ADMIN is the one to fear most — it re-enables mounts and namespace operations that underpin many escapes, which is why it is nicknamed "the new root". Auditing which containers hold which capabilities is one of the highest-value hardening exercises.

a hardened securityContext
securityContext:
runAsNonRoot: true
runAsUser: 10001
allowPrivilegeEscalation: false # block setuid/gaining new privs
readOnlyRootFilesystem: true
capabilities:
drop: ["ALL"] # start from zero
add: ["NET_BIND_SERVICE"] # add back only if truly needed
seccompProfile: { type: RuntimeDefault }
# Never: privileged: true, hostPID, hostNetwork, or a hostPath mount of /

Namespaces, user namespaces, and cgroups

Namespaces isolate a container’s view of PIDs, network, mounts, and users; user namespaces go further by mapping root inside the container to an unprivileged UID on the host, so container-root is not host-root and an escape lands with far less power. cgroups cap resources (CPU, memory, PIDs) — which is also a security control, since a PID or memory limit blunts fork-bomb and resource-exhaustion attacks. Sharing host namespaces (hostPID, hostNetwork, hostIPC) or running privileged collapses these boundaries, which is why they are the settings admission policy should forbid.

The isolation primitives, hardened
privilege
drop ALL caps
add back only what is needed
non-root + no priv-esc
shrink what a foothold has
views
namespaces
isolated PID/net/mnt/user
user namespace
container-root ≠ host-root
limits
cgroups
CPU/mem/PID caps blunt DoS
Minimize privilege, tighten views, cap resources. These primitives are what runtime detection then watches for tampering.
privileged: true throws away the whole boundary
A privileged container gets all capabilities and host device access — it is effectively running on the host. Combined with a hostPath or the Docker socket, escape is trivial. Forbid privileged, hostPID/hostNetwork, and broad hostPath mounts by admission policy; they are the settings behind most real container escapes.