SuperAPI AI Directory

docker-security

Deployment & operations

View repository

Updated 10-15 21:48

About this skill

Docker Security — Security Hardening and Protection

Comprehensive guidance for securing Docker across the full lifecycle.

When to Use

ALWAYS use this skill when the user mentions:

  • "docker security", "image security", "container security"
  • "non-root execution", "rootless", "least privilege"
  • "seccomp", "AppArmor", "SELinux"
  • "Docker Bench", "CIS"
  • "secrets management", "key management"
  • "image signing", "content trust"

Security Model — Layered Defense

Layer 1: Image Security    — minimal base, non-root, pinned versions
Layer 2: Build Security    — secret injection, noCOPY secrets
Layer 3: Runtime Security  — capabilities, seccomp, AppArmor, read-only
Layer 4: Registry Security — content trust, signing, vulnerability scan
Layer 5: Host Security     — Docker Bench, CIS, user namespace

Image Security Checklist

# Practice How
1 Minimal base image Use alpine or distroless (Go → scratch)
2 Non-root user USER 1000:1000 at end of Dockerfile
3 Pin versions FROM alpine:3.20@sha256:... not alpine:latest
4 COPY over ADD ADD auto-extracts tar — unexpected behavior
5 No secrets in image Use --secret or runtime injection
6 .dockerignore Exclude .env, .git, credentials

Secure Dockerfile

FROM alpine:3.20
RUN apk add --no-cache ca-certificates
RUN addgroup -S app && adduser -S -G app app
COPY --chown=app:app ./app /app
WORKDIR /app
USER app
CMD ["./server"]

Runtime Security

Capabilities (Least Privilege)

# Drop ALL capabilities, add only what's needed
docker run --cap-drop=ALL --cap-add=NET_BIND_SERVICE nginx

# Common needed caps: NET_BIND_SERVICE, CHOWN, DAC_OVERRIDE
# NEVER: --privileged (gives full host access)

Read-Only Root Filesystem

# Prevents container from writing anywhere (except volumes/tmpfs)
docker run --read-only --tmpfs /tmp --tmpfs /run nginx

Seccomp Profile

# Custom seccomp profile (block syscalls)
docker run --security-opt seccomp=profile.json app

# Unconfined (NEVER in production)
docker run --security-opt seccomp=unconfined app

No New Privileges

# Prevent privilege escalation via setuid binaries
docker run --security-opt no-new-privileges app

Secrets Management

BuildKit Secrets (build-time)

# syntax=docker/dockerfile:1
FROM alpine
RUN --mount=type=secret,id=aws_creds \
  AWS_ACCESS_KEY_ID=$(cat /run/secrets/aws_creds) \
  aws s3 cp s3://bucket/file .
docker build --secret id=aws_creds,src=$HOME/.aws/credentials -t app .

Docker Secrets (Swarm runtime)

echo "mysecretpassword" | docker secret create db_password -
docker service create --secret db_password postgres

Docker Bench Security Audit

docker run --rm \
  --pid host --network host \
  -v /var/run/docker.sock:/var/run/docker.sock \
  docker/docker-bench-security

Workflow — Security Hardening Process

Step 1: Image Security: docker scout cves <image> Scan vulnerabilities → update base images/dependencies Step 2: Dockerfile Hardening: USER non-root, COPY preferred over ADD, pin digest Step 3: Runtime Security: --read-only、--cap-drop=ALL、--security-opt no-new-privileges Step 4: Audit Check: docker run --rm docker/docker-bench-security Fix one by one Step 5: CI Gate: Scout policy blocks merge for critical/high CVE

Gotchas — Common Pitfalls

  • --privileged flag: Gives full host access. Never use in production. → Recovery: Use specific --cap-add=NET_BIND_SERVICE instead; audit with docker inspect --format='{{.HostConfig.Privileged}}'.
  • API keys in Dockerfile: ENV API_KEY=xxx is baked into image layers forever. → Recovery: Use runtime injection: docker run -e API_KEY=$KEY or BuildKit --mount=type=secret.
  • Root container: Default user is root. Escaping the container means root on the host. → Recovery: Always USER 1000:1000 in Dockerfile; verify with docker exec myapp whoami.
  • Docker socket mount: -v /var/run/docker.sock gives container control over ALL containers. → Recovery: Use Docker API with TLS auth instead of socket mount; never mount socket in production.
  • Ignoring CVE remediation: Running docker scout but never fixing findings. → Recovery: Set CI policy to block critical/high CVEs; update base images regularly.

Boundary — Capability Boundaries (Applicable and Non-Applicable Scenarios)

Category Scenario Description
✅ Can do Dockerfile security hardening USER non-root, COPY preferred over ADD, digest pinning
✅ Can do Runtime security configuration seccomp/AppArmor/capabilities/read-only
✅ Can do Secrets management Docker secrets + BuildKit --secret + Vault
✅ Can do Security audit (Docker Bench Security) CIS checklist + fix one by one
⚠️ Requires conditions Image signing (Notary) Requires DOCKER_CONTENT_TRUST=1 environment variables
⚠️ Requires conditions Full compliance check Requires combination of Scout scanning + organizational security policy
❌ Out of scope CVE vulnerability scanning Use docker-scout
❌ Out of scope Host system security Operating system level
❌ Out of scope Network security/firewall Network administrator domain

When NOT to Use This Skill

❌ Skip ✅ Use Instead
Vulnerability scanning docker-scout
Docker basics docker-basics
Production deployment docker-production
Registry management docker-hub

Security & Stability

  • All security practices are based on CIS Docker Benchmark and Docker official security guidance.
  • Run Docker Bench Security regularly in CI/CD to detect configuration drift.
  • Subscribe to Docker security advisories for CVE notifications.
  • No executable scripts bundled. Guidance only.

📚 Official Documentation Reference

Documentation Address
Docker Security https://docs.docker.com/security/
Docker Hardened Images https://docs.docker.com/dhi/
Docker Scout https://docs.docker.com/scout/
Docker Bench Security https://docs.docker.com/engine/security/bench/
seccomp configuration https://docs.docker.com/engine/security/seccomp/
AppArmor https://docs.docker.com/engine/security/apparmor/

🧭 Docker Skills Journey

📍 You are here: docker-security — Security Hardening

← Previous: docker-build | → Next: docker-scout / docker-cicd