From 73abed787b0e469adbcee5e97cf4251d6e8ce0d6 Mon Sep 17 00:00:00 2001 From: "Ajeet Singh Raina, Docker Captain, ARM Innovator" Date: Tue, 10 Mar 2026 15:11:12 +0530 Subject: [PATCH] Merge pull request #24303 from ajeetraina/fixvex add: build child images with provenance attestations --- content/manuals/dhi/how-to/scan.md | 87 ++++++++++++++++++++++++++++++ 1 file changed, 87 insertions(+) diff --git a/content/manuals/dhi/how-to/scan.md b/content/manuals/dhi/how-to/scan.md index 3a76d9756d..b90dac37a8 100644 --- a/content/manuals/dhi/how-to/scan.md +++ b/content/manuals/dhi/how-to/scan.md @@ -53,6 +53,93 @@ Example output: For more detailed filtering and JSON output, see [Docker Scout CLI reference](/reference/cli/docker/scout/). +### Build child images with provenance attestations + +When you build a custom image that uses a Docker Hardened Image as its base, you must build with `--provenance=mode=max` and `--sbom=true` so that Docker Scout can trace the base image lineage and correctly apply VEX statements. + +Without these flags, Docker Scout cannot identify the DHI base image in +the provenance chain. As a result, it reports CVEs that are already suppressed +by VEX statements in the base image, producing false CVE positives in your +scan results. + +> [!NOTE] +> **Why provenance attestation is required** +> +> Docker Scout uses max-mode provenance attestations to identify the DHI base image +> and track its lineage. A cryptographically signed provenance attestation ensures that +> base image lineage is verified and tamper-resistant, giving Docker Scout the trust +> anchor it needs to correctly apply VEX statements from the base image. + +To build with maximum provenance and SBOM attestations: + +```console +$ docker build \ + --provenance=mode=max \ + --sbom=true \ + --push \ + -t docker.io//: . +``` + +After building with these flags, Docker Scout reads the full provenance +chain, matches the DHI base image, and applies its VEX statements. Scans of +your child image then reflect the correct suppressed CVEs, giving you an +accurate vulnerability assessment. + +### VEX attestations in child images + +If you introduce new layers in your child image and want to suppress CVEs in those layers, you can attach your own VEX attestation to the child image independently, you do not need to duplicate or aggregate the VEX statements from the DHI base image. + +When `docker scout cves` runs against your child image, Scout reads VEX attestations from the full provenance chain and applies them cumulatively: + +- **Base image VEX** - attached to the DHI, applied to CVEs in base image layers +- **Child image VEX** - attached to your image, applied to CVEs in layers you introduced + +For example, if you add a `requests` layer to a DHI Python base image and attach a VEX statement suppressing `CVE-2024-47081`, Scout applies both VEX attestations independently and attributes each to its respective author: + +```text +✓ VEX statements obtained from attestation +CVE-2024-47081 VEX: not affected [vulnerable code not present] : +``` + +Scout suppresses CVEs from the DHI base VEX and CVEs from your child VEX in the same scan - no aggregate VEX document is required. + +To create and attach a VEX attestation to your child image: + +```bash +cat > child-vex.json << 'EOF' +{ + "@context": "https://openvex.dev/ns/v0.2.0", + "@id": "https:///vex//1", + "author": "", + "timestamp": "", + "version": 1, + "statements": [ + { + "vulnerability": { + "name": "" + }, + "products": [ + { + "@id": "pkg:pypi/@" + } + ], + "status": "not_affected", + "justification": "vulnerable_code_not_present" + } + ] +} +EOF + +docker scout attestation add \ + --file child-vex.json \ + --predicate-type https://openvex.dev/ns/v0.2.0 \ + docker.io//: +``` + +> [!NOTE] +> This is only possible because you built with `--provenance=mode=max`. Without the full +> provenance chain, Scout cannot traverse back to the base image to retrieve its VEX attestations. + ### Automate DHI scanning in CI/CD with Docker Scout Integrating Docker Scout into your CI/CD pipeline enables you to automatically