Secure your Python image supply chain
Prerequisites
Complete Configure CI/CD for your Python application.
Overview
When you ship a container image, what's inside it and where it came from matters. Supply chain attestations are signed records that answer questions like which packages are in the image, what vulnerabilities affect them, how the image was built, and what security checks it passed.
In this section, you'll inspect the attestations that ship with your Docker Hardened Image base, generate your own SBOM and provenance attestations during CI, and pin the base image by digest so your builds are reproducible.
The inspection commands in this topic are shown manually so you can see what each one returns. In a real workflow you'd automate these checks with Docker Scout, which runs the same scans on every push, enforces policies in CI, and surfaces results in your registry and pull requests.
Inspect the base image attestations
Docker Hardened Images are built to SLSA Build Level 3 and ship with a set of signed attestations covering bill-of-materials, vulnerabilities, build provenance, and security scans. See DHI attestations for the full list of types and how to verify their signatures with Cosign.
List all the attestations available on the Python DHI:
$ docker scout attest list registry://dhi.io/python:3.12
View the SBOM:
$ docker scout sbom registry://dhi.io/python:3.12
Check known vulnerabilities:
$ docker scout cves registry://dhi.io/python:3.12
NoteThe
registry://prefix forcesdocker scoutto fetch the image and its attestations from the registry instead of reading a locally pulled copy. If you've already pulled or built against the base image, the local copy doesn't have the attached attestations, so the prefix is required to see them.
When you base your own image on a DHI image, these attestations stay attached to the base layer in the registry. Tools that inspect your image can follow the chain back to the DHI source.
Generate attestations for your image
Update your GitHub Actions workflow to attach SBOM and provenance attestations to the image you push.
Edit .github/workflows/build.yml and update the build-and-push step:
- name: Build and push Docker image
uses: docker/build-push-action@v6
with:
context: .
push: true
sbom: true
provenance: mode=max
tags: ${{ steps.meta.outputs.tags }}sbom: truetells BuildKit to scan the built image and attach an SBOM attestation.provenance: mode=maxrecords detailed build provenance, including the source repository, commit, and build parameters.
The next time your workflow runs, the pushed image will carry these attestations alongside the image manifest in the registry.
Inspect your pushed image's attestations
After your workflow pushes the image, inspect it the same way you inspected the base image:
$ docker scout attest list registry://DOCKER_USERNAME/REPO_NAME:latest
$ docker scout sbom registry://DOCKER_USERNAME/REPO_NAME:latest
The SBOM includes packages from every layer, including those inherited from dhi.io/python:3.12. The provenance record references the DHI base image by digest, so consumers of your image can trace the build chain back to the DHI source.
Pin the base image by digest
Image tags like dhi.io/python:3.12 move over time as new patches land. For reproducible builds, pin to an immutable digest.
The Dockerfile uses two tags, dhi.io/python:3.12-dev in the builder stage
and dhi.io/python:3.12 in the runtime stage. Each tag has its own digest,
so look up both:
$ docker buildx imagetools inspect dhi.io/python:3.12-dev --format "{{ .Manifest.Digest }}"
sha256:4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945
$ docker buildx imagetools inspect dhi.io/python:3.12 --format "{{ .Manifest.Digest }}"
sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
Each digest is a 64-character hex string. Update your Dockerfile to reference
each digest on the matching FROM line:
FROM dhi.io/python:3.12-dev@sha256:4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945 AS builder
# ...
FROM dhi.io/python:3.12@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855TipPinning by digest also pins you to that image's vulnerabilities. Use Dependabot or Renovate to automate digest updates so you get a PR when a new patched image is available, with a changelog to review before merging.
Summary
In this section, you learned how to:
- Inspect the supply chain attestations that ship with the DHI base image, including SBOMs, CVE reports, VEX statements, and scan results
- Generate SBOM and provenance attestations for your own image in CI
- Pin base images by digest for reproducible builds
Related information:
Next steps
In the next section, you'll deploy your application to Kubernetes.