Security

Scanning and attestations

How every tag is scanned before it is published, and the SBOM, provenance and VEX attestations shipped with each image.

Scan before publish

No tag that users pull is ever published unscanned. Each image goes through the same sequence in CI:

  1. Build for linux/amd64 and linux/arm64 and push under a candidate tag, candidate-<git sha>[-<minor>].
  2. Run Trivy against the candidate with --severity CRITICAL,HIGH --ignore-unfixed. Any finding fails the job.
  3. Attach the OpenVEX attestation.
  4. Promote the candidate to its real tags (8.4 and 8.4.26) with docker buildx imagetools create, which copies the manifest list including attestations.
  5. Delete the candidate tag.

If a scan fails, the public tags are untouched and keep serving the previous image. See Release pipeline.

Attestations

Every image carries:

AttestationWhat it is
SBOMSPDX software bill of materials generated by BuildKit at build time.
ProvenanceSLSA provenance describing the build inputs and the GitHub Actions run that produced the image.
OpenVEXStatements about CVEs that scanners report but that do not affect these images, with the justification.

Inspect them:

docker buildx imagetools inspect adamrollogi/php:8.4 --format '{{ json .SBOM }}' | jq '.SPDX.packages | length'
docker buildx imagetools inspect adamrollogi/php:8.4 --format '{{ json .Provenance }}' | jq '.SLSA.builder'
docker scout cves adamrollogi/php:8.4           # honours the attached VEX

The VEX document itself lives at .vex/openvex.json in the repository, and the reasoning behind each statement is on Known CVEs.

Scanning the images yourself

# Trivy, same settings as CI
trivy image --severity CRITICAL,HIGH --ignore-unfixed adamrollogi/php-nginx:8.4

# Everything, including MEDIUM and LOW
trivy image adamrollogi/php-nginx:8.4

# Docker Scout with the repository's VEX
git clone https://github.com/AdamRollinson/docker.git
docker scout cves --vex-location docker/.vex/ adamrollogi/php-nginx:8.4

At the time of writing all images report zero findings at every severity in Trivy. Two Docker Scout findings are suppressed with VEX for the reasons documented on the next page.

Keeping images fresh

Three things keep published images current without anyone pushing a commit:

  • A job every four hours bumps the PHP pins when Alpine ships a new release.
  • A weekly rebuild republishes every tag so Alpine's own fixes for musl, OpenSSL, Nginx and the rest are included.
  • Dependabot keeps the GitHub Actions and the Alpine base digest up to date.

See Automatic updates.