Docker Hardening CI
Move a service from "it builds" to a reproducible, signed, scanned image produced by a least-privilege pipeline, without sacrificing build speed, developer ergonomics, or the ability to ship a fix in an hour.
Start every run
- Read references/hardening-checklist.md before editing any Dockerfile; it is the rubric the linter encodes.
- Read references/ci-playbook.md before editing a workflow, choosing scanner thresholds, or adding signing.
- Read references/operations.md before running the tools; it has the exact commands, versions and exit codes.
- Inspect current state: every
Dockerfile*,.dockerignore,.github/workflows/*.yml, the last scan report, and the registry's current tags. Run both linters read-only before proposing changes. - Confirm authorization. Linting, scanning and proposing patches in a branch need none. Pushing images, rotating registry credentials, changing branch protection or organization Actions policies, or deleting tags need an explicit request from a repository admin.
Non-negotiable rules
- Every
FROMis a tag plus a@sha256:digest.:latestand untagged images fail the build. Digests are refreshed by Dependabot or Renovate pull requests, not by hand edits. - The final stage runs as a non-root numeric UID (
USER 65532:65532or10001:10001), neverroot, never a name that resolves only in the