Skip to content

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/newgidmap for 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-remap in 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 :z or :Z volume 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=1 environment 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 --publish to 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 context to 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

References