Security¶
Docker security operates at multiple layers: the host OS kernel (namespaces, cgroups, seccomp, AppArmor/SELinux), the Docker daemon configuration, the container image supply chain, and network isolation. No single layer is sufficient; defense in depth is required.
See also: infrastructure/docker/index, infrastructure/docker/architecture, infrastructure/docker/architecture, infrastructure/docker/operations
Threat Model¶
| Threat Vector | Mitigation |
|---|---|
| Container breakout to host | User namespaces, rootless mode, seccomp, AppArmor |
| Privileged container abuse | Drop capabilities, run as non-root, avoid --privileged |
| Malicious base images | Image signing, vulnerability scanning |
| Supply chain compromise | Content Trust, Cosign, SBOM verification |
| Daemon socket exposure | Restrict /var/run/docker.sock access, use TLS |
| Network lateral movement | Network isolation, user-defined bridges, network policies |
Rootless Mode¶
Rootless mode runs both the Docker daemon and containers without root privileges. Introduced in Docker Engine 20.10, it is the strongest isolation mechanism available.
- The daemon and containers execute inside a user namespace
- No SETUID binaries or file capabilities required (except
newuidmap/newgidmapfor multi-UID support) - Container root (UID 0) maps to an unprivileged user on the host
- Eliminates the risk of container breakout escalating to host root
Rootless vs userns-remap
With userns-remap, the daemon still runs as root but maps container UIDs to unprivileged host UIDs. Rootless mode goes further: the daemon itself has no root privileges.
Limitations of rootless mode:
- Some --publish operations require root-owned slirp4netns or rootful kit for privileged ports (< 1024)
- Cgroup v2 is required for resource limiting
- Some storage drivers and network modes may not be available
User Namespaces¶
User namespaces map container user IDs to different host user IDs:
- Enabled via
--userns-remapin daemon configuration - Container root (UID 0) maps to an unprivileged host UID range
- Each container gets its own UID mapping, isolating containers from each other
- Available since Docker 1.10; can be used alongside rootless mode
Enhanced Container Isolation (ECI)
Docker Desktop Business tier offers ECI, which automatically runs all containers within Linux user namespaces. Each container root maps to a different unprivileged user in the Docker Desktop VM, providing inter-container isolation without developer workflow changes.
Seccomp Profiles¶
Seccomp (secure computing mode) restricts the system calls a container can make:
- Docker uses a default seccomp profile that blocks approximately 44 dangerous syscalls
- The default profile is applied to all containers unless overridden with
--security-opt seccomp=unconfined - Custom profiles can be written in JSON to allow or deny specific syscalls with argument filtering
- Profiles are essential for reducing the kernel attack surface accessible to compromised containers
Common syscalls blocked by the default profile: mount, umount2, swapon, swapoff, pivot_root, reboot, keyctl, init_module, finit_module, delete_module, and more.
AppArmor and SELinux¶
AppArmor¶
AppArmor confines containers with per-profile mandatory access controls:
- Docker generates a default AppArmor profile (
docker-default) for each container - Profiles restrict file access, capability usage, and network operations
- Custom profiles can be applied via
--security-opt apparmor=PROFILE_NAME - Available on Ubuntu, SUSE, and other distributions with AppArmor support
SELinux¶
SELinux provides mandatory access control on RHEL, CentOS, and Fedora:
- Docker applies SELinux labels (type:
container_t) to container processes - File contexts (
container_file_t) prevent containers from accessing host files - Enables multi-tenancy isolation via MCS (Multi-Category Security) labels
- Use
:zor:Zvolume mount flags to relabel volumes for container access
Linux Capabilities¶
Docker drops most Linux capabilities by default. The default capability set includes:
| Capability | Purpose |
|---|---|
CHOWN |
Change file ownership |
DAC_OVERRIDE |
Bypass file read/write permission checks |
FOWNER |
Bypass ownership checks on file operations |
FSETID |
Don't clear setuid/setgid on modification |
KILL |
Send signals to processes |
NET_BIND_SERVICE |
Bind to ports below 1024 |
SETFCAP |
Set file capabilities |
SETGID / SETUID |
Change process GID/UID |
Capabilities can be dropped with --cap-drop or added with --cap-add. Avoid --privileged which adds all capabilities.
Never use --privileged in production
The --privileged flag grants all capabilities, all device access, and overrides seccomp/AppArmor. It effectively disables container isolation.
Image Signing and Supply Chain Security¶
Docker Content Trust (DCT)¶
Docker Content Trust uses Notary (TUF framework) to sign image tags:
- Enabled by setting
DOCKER_CONTENT_TRUST=1environment variable - Signs image metadata (digests, sizes) with repository keys
- Prevents pulling tampered or unsigned images
- Key hierarchy: root key, repository key, timestamp key, snapshot key
Cosign (Sigstore)¶
Cosign is the modern alternative for container image signing:
- Signs images using key pairs or OIDC-based keyless signing
- Stores signatures in the same registry as the image (no separate Notary service)
- Supports transparency log (Rekor) for auditability
- Integrates with CI/CD pipelines for automated signing
- Part of the Sigstore project
Vulnerability Scanning¶
Docker Scout¶
Docker Scout is Docker's integrated vulnerability analysis tool:
- Scans images for CVEs using an expanded vulnerability database
- Compares images against base image updates to show remediation paths
- Generates SBOM (Software Bill of Materials) attestations
- Evaluates supply chain attestations (provenance, SBOM)
- Available in Docker Desktop and Docker Hub
Trivy¶
Trivy (Aqua Security) is a widely used open-source scanner:
- Scans OS packages, language dependencies, and IaC files
- Supports multiple targets: container images, filesystems, git repos, Kubernetes
- Fast scanning with local vulnerability database caching
- Integrates with CI/CD (GitHub Actions, GitLab CI)
Grype¶
Grype (Anchore) is another open-source vulnerability scanner:
- Focuses on fast, accurate matching against vulnerability databases
- Supports SBOM input (from Syft) for efficient scanning
- Configurable matching and severity filtering
Network Isolation¶
Docker provides several mechanisms for network-level security:
- User-defined bridges: Provide automatic DNS resolution and isolate containers from the default bridge network. Containers on different user-defined bridges cannot communicate.
- ICMP/destination port filtering: Docker blocks inter-container ICMP on the default bridge.
- Publish restrictions: Use
--publishto expose only necessary ports. - No
--network host: Avoid host networking in production; it removes all network isolation. - Macvlan caution: Macvlan gives containers direct network presence, bypassing the Docker firewall. Use only when necessary.
Network hardening
For production workloads, run containers on user-defined bridge networks, never expose the Docker daemon socket, and use external firewalls or cloud security groups to restrict published ports.
Daemon Socket Security¶
The Docker daemon socket (/var/run/docker.sock) grants full control over the host:
- Never expose the socket to containers or untrusted users
- Restrict filesystem permissions on the socket
- For remote access, configure TLS with mutual authentication (
--tlsverify) - Use
docker contextto manage multiple daemon connections securely
Security Checklist¶
| Area | Recommendation |
|---|---|
| Runtime | Use rootless mode or userns-remap |
| Runtime | Run containers as non-root (USER directive in Dockerfile) |
| Runtime | Drop unnecessary capabilities (--cap-drop ALL, add only what is needed) |
| Runtime | Apply seccomp profiles (use default at minimum) |
| Runtime | Enable AppArmor or SELinux |
| Image | Use minimal base images (distroless, Alpine, Chainguard) |
| Image | Scan images for CVEs before deployment |
| Image | Sign images with Cosign or Docker Content Trust |
| Image | Pin image digests, not tags (image@sha256:...) |
| Network | Use user-defined bridge networks |
| Network | Never use --privileged or --network host in production |
| Daemon | Restrict access to /var/run/docker.sock |
| Daemon | Enable TLS for remote daemon access |
| Daemon | Keep Docker Engine updated for security patches |