Philipp 2d58558b5a
CI Tests / JS Unit Tests (push) Successful in 8s
CI Tests / cross-check-mixed-sbom (sbom=true) (push) Successful in 6m54s
CI Tests / without-inbuild-sbom (sbom=false) (push) Successful in 6m54s
CI Tests / cross-check-mixed-sbom (sbom=false) (push) Successful in 6m56s
CI Tests / with-inbuild-sbom (sbom=false) (push) Successful in 9m11s
CI Tests / without-inbuild-sbom (sbom=true) (push) Successful in 9m11s
CI Tests / with-inbuild-sbom (sbom=true) (push) Successful in 9m10s
Merge pull request 'chore(deps): update actions/upload-artifact action to v7' (#19) from renovate/major-github-artifact-actions into main
Reviewed-on: #19
2026-09-18 00:54:58 +02:00
2026-09-13 00:28:19 +02:00

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 inspect to 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:

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-release and 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 head and target images 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 --distro to 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-json directly 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:

  1. Debian Source vs. Binary Packages: Debian security advisories (DSAs / DLAs) are tracked and published per source package (e.g., the source package glibc produces multiple binary packages like libc6, libc-bin, locales). Trivy's filesystem scanner reads /var/lib/dpkg/status to 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.
  2. 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 enable use-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

S
Description
An github / gitea action to compare docker image CVEs
Readme MIT
171 KiB
0 Stars 1 Watchers 0 Forks
0.0.2
Latest
2026-10-12 21:36:46 +02:00
Languages
JavaScript 92.5%
Go Template 7.5%