Container runtime security: least privilege, read-only filesystems, capabilities and monitoring
In short: Even a well-built image can be exploited, so you also limit what the running container may do. Run as non-root, drop Linux capabilities, make the filesystem read-only, apply seccomp and set resource limits. Then watch behaviour with runtime detection and respond by isolating and rebuilding.
Assume the app will be attacked
Image scanning finds known vulnerabilities, but not unknown bugs, stolen credentials or logic flaws. Runtime security assumes an attacker may eventually run code inside a container and asks: what can they do next? The goal is that the answer is "very little", and that you notice quickly.
Least-privilege settings
| Setting | Why it helps | Docker flag |
|---|---|---|
| Run as non-root | Root in a container is closer to root on the host than many expect | --user 10001:10001 |
| Drop capabilities | Removes powers such as changing network settings or loading modules | --cap-drop ALL |
| No privilege escalation | Blocks setuid binaries from gaining root | --security-opt no-new-privileges |
| Read-only root filesystem | Stops attackers dropping tools or changing binaries | --read-only --tmpfs /tmp |
| Resource limits | Contains crypto-mining and fork bombs | --memory 256m --pids-limit 100 |
docker run -d --name api \
--user 10001:10001 --cap-drop ALL --security-opt no-new-privileges \
--read-only --tmpfs /tmp \
--memory 256m --cpus 0.5 --pids-limit 100 \
registry.example.com/shop/api@sha256:<digest>
Linux capabilities split root's power into pieces such as NET_ADMIN, SYS_ADMIN and NET_BIND_SERVICE. Drop them all, then add back only what the app genuinely needs. SYS_ADMIN is so broad it is almost equivalent to full root.
Seccomp profiles filter system calls; Docker and Kubernetes ship a sensible default profile, so make sure it is not disabled. AppArmor or SELinux add mandatory access control over files and operations.
Settings to avoid
--privileged: gives the container almost all host powers and device access. Treat it as host root.- Mounting the Docker socket (
/var/run/docker.sock): whoever controls the socket controls the host. - Host namespaces (
--network host,--pid host) unless there is a clear, reviewed reason. - Mounting sensitive host paths such as
/,/etcor/procread-write.
Tip: in Kubernetes the same ideas appear in the pod securityContext and are enforced by Pod Security Standards.
Runtime detection and response
Runtime detection tools watch process, file and network activity, often using eBPF in the kernel. The open-source project Falco is a common example, and commercial cloud workload protection platforms offer similar features. Useful detections include a shell spawned inside a production container, a package manager running, writes to binary directories, unexpected outbound connections and access to cloud metadata endpoints.
Because containers are immutable, the response is different from a server. Capture evidence (logs, a copy of the container filesystem if needed), isolate the pod with a network policy or scale it down, then fix the cause and redeploy from a clean image rather than cleaning the running container. See cloud incident response for the wider process.
Practice
Why is mounting the Docker socket into a container dangerous?
An app writes temporary files but you want a read-only root filesystem. What can you do?
Name two behaviours a runtime detection rule might flag in a web container.
Key takeaways
- Assume compromise and limit what a container can do.
- Run as non-root, drop all capabilities and block privilege escalation.
- Use read-only filesystems, seccomp and resource limits.
- Avoid privileged mode, the Docker socket and host namespaces.
- Detect unusual behaviour at runtime and redeploy clean images.
Original content written by Mohamed Fayas for FM TecHub. © 2026 FM TecHub. You're welcome to share a link to this page; please don't copy the text elsewhere without permission.