Read-only Docker host and container baseline checker with CIS Docker Benchmark ids (MIT, free; pipx install) https://errant.solutions/tools/docker-baseline-auditor.html
  • Python 86.3%
  • Shell 13.7%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
Ronald Farrer dc1c6c1ff0
All checks were successful
tests / test (3.14) (push) Successful in 2m49s
tests / test (3.8) (push) Successful in 2m38s
ci: pin pytest<9 for mutmut 3.8.0 (pytest 9 removed Item._nodeid: every nightly mutation job died at stats collection)
2026-11-06 09:15:24 -08:00
.forgejo/workflows mutation/chaos CI on every rw-man host again (owner decision 2026-10-18: colo backlog too big, GuardDuty suppression kept): EC2 guards are opt-in (refuse only with CI_COLO_ONLY=1, code kept), colo jobs move to the shared labels mutation-x86_64 / mutation-any (rw-man-01..05, 6g slots) 2026-10-18 13:45:32 -07:00
ci ci: pin pytest<9 for mutmut 3.8.0 (pytest 9 removed Item._nodeid: every nightly mutation job died at stats collection) 2026-11-06 09:15:24 -08:00
tests tests/test_accuracy: under mutation testing build the reference (18-container corpus + Docker Bench verdicts) once per mutation run and reuse it for every mutant; only the tool's audit reruns. Per-mutant rebuilds made a third of mutants time out (90/268 in run 4009) and leaked ~800 containers on rw-man-04. The mutation corpus is labelled with its mutation container's id and reaped once that container is gone 2026-10-17 09:43:29 -07:00
.gitignore nightly mutation: incremental (only functions changed since the last green run) except a weekly full run on the repo's own weekday; replace-queued concurrency; staggered cron 2026-10-18 12:22:49 -07:00
CHANGELOG.md Release 1.2.1: the test-depth fixes since 1.2.0 (see CHANGELOG) 2026-10-17 01:50:03 -07:00
claims.json Test depth: accuracy suite vs Docker Bench for Security (18 real containers, per-container verdict on 18 CIS ids, documented Docker Bench deviations judged by the CIS audit text); CIS 5.15 follows the benchmark (unbounded restart policies flagged, none is compliant); content-trust + remote DOCKER_HOST tests; claims ledger; nightly mutation + matrix + install channels 2026-10-17 00:15:43 -07:00
docker_baseline_auditor.py Release 1.2.1: the test-depth fixes since 1.2.0 (see CHANGELOG) 2026-10-17 01:50:03 -07:00
LICENSE Add MIT LICENSE file 2026-10-16 14:07:53 -07:00
pyproject.toml Test depth: accuracy suite vs Docker Bench for Security (18 real containers, per-container verdict on 18 CIS ids, documented Docker Bench deviations judged by the CIS audit text); CIS 5.15 follows the benchmark (unbounded restart policies flagged, none is compliant); content-trust + remote DOCKER_HOST tests; claims ledger; nightly mutation + matrix + install channels 2026-10-17 00:15:43 -07:00
README.md Release 1.2.1: the test-depth fixes since 1.2.0 (see CHANGELOG) 2026-10-17 01:50:03 -07:00

docker-baseline-auditor

Read-only Docker security baseline checker for the host you run it on: the daemon's configuration, the Docker host's files and every running container, checked against the CIS Docker Benchmark v1.6.0. Every finding carries its CIS recommendation id, so results line up with the benchmark (and with Docker Bench for Security). Zero dependencies beyond a working docker CLI.

Area CIS ids
Daemon: icc on the default bridge, log level, insecure registries, aufs, TCP socket without TLS, user namespaces/rootless, centralized logging, no-new-privileges default, live restore, userland proxy, experimental features 2.2 2.3 2.5 2.6 2.7 2.9 2.13 2.14 2.15 2.16 2.18
Host files (local daemon only): docker.service/docker.socket units, /etc/docker, daemon.json, the Docker socket (owner + mode) 3.1-3.6 3.15-3.18
Docker Content Trust not enabled 4.5
Containers: configured to run as root, AppArmor/seccomp unconfined, added capabilities, privileged, sensitive host paths mounted (/, /etc, /proc, /var/run...), privileged host ports, host network, memory limit, writable root filesystem, ports published on every interface, restart policy without a retry cap (always/unless-stopped/on-failure over 5), host PID/IPC/UTS/user namespaces, host devices, shared mount propagation, no-new-privileges, health check, pids limit, Docker socket mounted 4.1 5.2 5.4 5.5 5.6 5.8 5.10 5.11 5.13 5.14 5.15 5.16 5.17 5.18 5.20 5.21 5.22 5.26 5.27 5.29 5.31 5.32
:latest/untagged images (ops hygiene) -

"Run as root" means the container's configured USER (what docker inspect shows), not a live process listing.

Install

pipx install git+https://git.canutethegreat.com/CanuteTheGreat/docker-baseline-auditor.git        # latest release branch; puts `docker-baseline-auditor` on PATH
pipx install git+https://git.canutethegreat.com/CanuteTheGreat/docker-baseline-auditor.git@v1.2.1  # a pinned release
brew install canutethegreat/errant-tools/docker-baseline-auditor   # after: brew tap canutethegreat/errant-tools https://git.canutethegreat.com/CanuteTheGreat/homebrew-errant-tools
scoop install errant-tools/docker-baseline-auditor                 # after: scoop bucket add errant-tools https://git.canutethegreat.com/CanuteTheGreat/scoop-errant-tools

Or download the single file (stdlib-only Python 3.8+) and run it directly: curl -fsSLO https://errant.solutions/downloads/docker_baseline_auditor.py && python3 docker_baseline_auditor.py --help. Every release has a changelog, the wheel, the sdist and a SHA256SUMS file. Not on PyPI yet, so plain pipx install docker-baseline-auditor doesn't work until it's published there.

Usage

docker-baseline-auditor                       # text report
docker-baseline-auditor --json                # machine-readable, for CI
docker-baseline-auditor --fail-on medium      # CI gate: exit 1 on MEDIUM or worse
docker-baseline-auditor --exclude 5.27,2.13   # skip checks/sections by CIS id
docker-baseline-auditor --include 5 --all     # only container checks, including stopped containers
docker-baseline-auditor --version

Read-only: docker info, docker network inspect bridge, docker ps and docker inspect, plus stat() on the local Docker files. Never modifies anything. No network calls, no data leaves the host. With a remote DOCKER_HOST the host-file checks (3.x) are skipped and the report says so.

Exit codes (same convention as every Errant Solutions tool):

Code Meaning
0 no finding at or above --fail-on (default high)
1 at least one finding at or above --fail-on
2 the docker CLI is missing, the daemon can't be reached, or bad usage

--json prints {"version", "engine", "daemon": [findings], "containers": [{"name", "image", "findings"}], "summary"} where each finding is {"id": "5.5", "severity": "HIGH", "message": "..."}.

License / pricing

MIT — see LICENSE. Free, pay-what-you-want. If it's useful, there's a payment link on https://errant.solutions. No obligation.

Part of the Errant Solutions spare-capacity tools series (see also: sshd-hardening-auditor, tls-cert-watchdog, mail-security-auditor, aws-waste-finder).

Tests

tests/ exercises every option and check end-to-end (against real containers on a real Docker engine) in Forgejo CI on Python 3.8 and current Python, then installs the package with pip and checks\n--version/--help; sh ci/run-tests.sh 3.13 reproduces it locally (needs docker).