This reverts commit17e5dab1b2, reversing changes made to46c4fedc47.
CVE Differential
A self-contained Gitea and GitHub Actions composite action that extracts multi-platform SBOM attestations from container images, runs vulnerability scans with Trivy, and produces a set-based CVE delta report between a head image and a target baseline image.
✨ Features
- Dynamic Multi-Platform Support: Automatically discovers and scans all architectures present in container images, or iterates over an explicit list of target architectures.
- Fast Attestation Extraction with Automatic Fallback: Uses
docker buildx imagetools inspectto extract platform-specific SBOMs directly from registry manifest indices. If attestations are missing or produce 0 CVE findings (common when third-party generators omit OS qualifiers in SPDX), it automatically falls back to generating SBOMs directly with Trivy per architecture. - Set-Based Differential Analysis: Categorizes vulnerabilities into:
- 🔴 Introduced Vulnerabilities (newly added in this branch / commit)
- 🟢 Fixed Vulnerabilities (present in target baseline, resolved in this branch)
- ⚪ Unchanged Vulnerabilities (pre-existing in target baseline)
- Secure & Unit Tested: Verified Trivy binary downloads against static SHA256 checksum lockfiles, single-step unified caching, and comprehensive native unit tests (
node:test).
📥 Inputs
| Input | Description | Required | Default |
|---|---|---|---|
head-image |
Head container image reference to scan (e.g. registry.example.com/repo:git-sha) |
Yes | — |
target-image |
Target baseline container image reference to compare against (e.g. registry.example.com/repo:latest) |
Yes | — |
target-branch |
Target branch name for report headings | No | main |
architectures |
Comma-separated architectures/platforms to scan (e.g. amd64,arm64). If omitted, scans all architectures present in the image. |
No | (all) |
output-delta |
Output path for the CVE delta Markdown report | No | cve-delta.md |
output-summary |
Output path for the full vulnerability Markdown summary | No | cve-summary.md |
write-summary |
Whether to append the generated reports to the job summary ($GITHUB_STEP_SUMMARY) |
No | true |
use-inbuild-sbom |
Whether to inspect and use built-in image SBOM attestations. If false (recommended default), generates SBOMs directly with Trivy for maximum vulnerability fidelity. If true, extracts attestations without pulling layers (faster, but findings reflect binary-package SBOMs without rootfs source-mapping; falls back to Trivy image scan if 0 CVEs detected). | No | false |
📤 Outputs
| Output | Description |
|---|---|
delta-report |
Path to the generated CVE delta Markdown report |
summary-report |
Path to the full vulnerability Markdown summary report |
🔍 Built-in SBOM Attestations vs. Trivy Direct Scanning (Syft vs. Trivy)
This action supports two modes for obtaining SBOMs:
1. Direct Image Scanning with Trivy (use-inbuild-sbom: false — Default & Recommended)
By default, the action uses trivy image --format spdx-json to generate the SBOM directly from the container images:
- Full Filesystem Fidelity: Inspects the entire flattened root filesystem, reading
/etc/os-releaseand native package databases (e.g./var/lib/dpkg/status, RPM databases, apk). - Accurate OS & Language Package Detection: Catalogs both OS packages (Debian, Alpine, RHEL, etc.) and application dependencies (Python, Node.js, Go, etc.).
- Symmetric, Apples-to-Apples Comparisons: Both
headandtargetimages are analyzed using the identical Trivy engine and vulnerability database, preventing skewed diffs.
2. Built-in Attestation Extraction with Resilient Fallback (use-inbuild-sbom: true)
When enabled, the action extracts SBOM attestations attached to the container image using docker buildx imagetools inspect:
- Speed: Extracts the SBOM JSON metadata directly from the registry manifest index in seconds without pulling image layer blobs.
- Underlying Generator (Syft / Docker Scout): Docker Buildx (
sbom: true) uses BuildKit's embedded Syft scanner (moby/buildkit-syft-scanner). - Distro Detection: Automatically extracts OS distribution information from package PURLs (e.g.
debian/12) and queries Trivy with--distroto accurately identify vulnerabilities on the extracted SBOM. - Resilient Fallback: If an extracted in-build SBOM scan produces 0 CVE findings (a common issue when third-party generators omit OS distribution qualifiers from SPDX packages) or if scanning fails, the action automatically falls back to running
trivy image --platform "$platform" --format spdx-jsondirectly on the image. This guarantees that vulnerability scans never fail silently or report false zeros. - Audit Copies: The action preserves copies of both the raw extracted in-build SBOM (
inbuild-sbom-*.spdx.json) and the final scanned SBOM (sbom-*.spdx.json) for auditing and debugging.
⚖️ Trade-offs: Why do the results differ between strategies?
The vulnerability results between Strategy 1 (sbom: false) and Strategy 2 (sbom: true) are not identical:
| Feature / Metric | Direct Trivy Scan (use-inbuild-sbom: false) |
Built-in Attestation (use-inbuild-sbom: true) |
|---|---|---|
| Generator | Trivy directly on container rootfs | Docker Scout / BuildKit (Syft) |
| Execution Speed | Slower (pulls image layer blobs) | Very Fast (~5x faster, 0 layer downloads) |
| Debian Slim Findings Example | ~225 CVEs (debian:bookworm-slim) |
~104 CVEs (debian:bookworm-slim) |
| Package Resolution Model | Source & binary packages (/var/lib/dpkg/status) |
Binary packages cataloged in SPDX PURLs |
| Filesystem Inspection | Full filesystem (static binaries, libraries) | Manifest-only (packages cataloged at build time) |
| Primary Use Case | High-fidelity security audits & release gates | High-speed PR checks & developer feedback loops |
Why the vulnerability counts differ:
- Debian Source vs. Binary Packages: Debian security advisories (DSAs / DLAs) are tracked and published per source package (e.g., the source package
glibcproduces multiple binary packages likelibc6,libc-bin,locales). Trivy's filesystem scanner reads/var/lib/dpkg/statusto map installed binary packages directly to Debian source package advisories. Syft's default SPDX output catalogs installed binary packages as PURLs without source-package relations, so Trivy's SBOM scan queries only the exact binary package entries that match Debian database schemas without the source-mapping context. - Filesystem vs. Manifest Scope: Direct image scanning unpacks and inspects the entire container image filesystem (including file hashes, crypto libraries, and static binaries). An in-build SBOM scan is strictly limited to the package inventory written by the build-time generator.
Tip
Setting
use-inbuild-sbom: 'false'remains the recommended default for maximum accuracy and cross-platform consistency. If you choose to enableuse-inbuild-sbom: 'true', the built-in fallback ensures full coverage even when third-party attestations lack OS package metadata.
🚀 Usage Example
jobs:
build-and-scan:
runs-on: ubuntu-latest
steps:
- name: Build and Push Head Container Image
uses: docker/build-push-action@v5
with:
context: .
push: true
tags: registry.example.com/my-app:git-${{ github.sha }}
- name: Compare Vulnerabilities (Head vs Target)
uses: https://git.horstenkamp.eu/Philipp/cve-differential.git@main
with:
head-image: registry.example.com/my-app:git-${{ github.sha }}
target-image: registry.example.com/my-app:latest
target-branch: ${{ github.base_ref || 'main' }}
📄 License
MIT