Skip to content

fix: prefer Syft over cdxgen for Docker image SBOMs - #273

Open
vpetersson wants to merge 4 commits into
masterfrom
fix/prefer-syft-for-docker-images
Open

fix: prefer Syft over cdxgen for Docker image SBOMs#273
vpetersson wants to merge 4 commits into
masterfrom
fix/prefer-syft-for-docker-images

Conversation

@vpetersson

Copy link
Copy Markdown
Contributor

Fixes #264

Problem

For Docker images, the generator registry preferred cdxgen-image (priority 20) over syft-image (priority 35). cdxgen image SBOMs lack the operating-system component and distro metadata, so vulnerability scanners can't detect OS packages:

  • Trivy bails with Unsupported os family="none" and scans nothing — which also breaks Dependency-Track's Trivy analyzer, the workflow reported in the issue.
  • Older Grype (0.91, as in the issue report) found nothing either; Grype ≥ 0.115 partially copes via source-package purls.

Reproduction confirmed the pipeline itself is not the problem: a Syft-generated SBOM run through the full sbomify pipeline (augment + enrich) keeps the operating-system component, and both Trivy and Grype scan it correctly. Only the generator choice was wrong.

Fix

Swap the image generator priorities — lockfile generators are untouched:

Generator Before After
syft-image 35 25 (preferred)
cdxgen-image 20 40 (fallback)

cdxgen remains the fallback when Syft isn't installed, and is still automatically selected for CycloneDX 1.7 image requests (Syft caps at 1.6 — the registry's version-based selection handles this, verified).

Verification

Against gcr.io/distroless/cc-debian13:latest via sbomify-action --docker-image ... --no-upload --enrich:

Before (cdxgen selected):

trivy: WARN Unsupported os  family="none" → Target: - (not scanned)

After (syft selected):

trivy: INFO Detected OS  family="debian" version="13"
       INFO [debian] Detecting vulnerabilities...  os_version="13" pkg_num=13
grype: 12 matches (libc6, zlib1g) — identical to a raw `syft` SBOM

(Trivy showing 0 vulnerabilities on this image is expected — same result as the issue author's raw-syft test; the CVEs Grype lists are Debian no-advisory/"won't fix" entries Trivy filters.)

Package coverage check (steelman): compared Syft vs cdxgen image SBOMs on distroless and python:3.13-alpine. Language-package coverage is at parity (identical pypi purls); cdxgen's "extra" entries were source-package duplicates of installed binaries (glibc vs libc6, openssl vs libssl3) plus hundreds of pkg:generic/* noise components (shared-object filenames, even license IDs like pkg:generic/Apache-2.0). Syft additionally catalogs the interpreter binary cdxgen misses. Nothing of value is lost.

  • uv run pytest: 2413 passed, 4 skipped
  • ruff check / ruff format --check: clean

🤖 Generated with Claude Code

cdxgen image SBOMs lack the operating-system component and distro
metadata, so vulnerability scanners can't detect OS packages: Trivy
bails with 'Unsupported os family=none' and scans nothing, which also
breaks Dependency-Track's Trivy analyzer. Syft image SBOMs carry the
OS component and distro PURL qualifiers, and survive the full
augment/enrich pipeline intact — Trivy and Grype both scan them
correctly.

Swap the image generator priorities (lockfile generators unchanged):

- syft-image: 35 -> 25 (preferred)
- cdxgen-image: 20 -> 40 (fallback when Syft is unavailable, and the
  only generator for CycloneDX 1.7 image requests, which Syft does
  not support)

Verified against gcr.io/distroless/cc-debian13: Trivy now detects
'debian 13' and scans all 13 packages; Grype reports the same 12 CVEs
as against a raw syft SBOM. Package coverage is equal or better —
cdxgen's extra entries were source-package duplicates and pkg:generic
noise (shared-object filenames, license IDs).

Fixes #264

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Updates the generator registry’s Docker image selection so Syft is preferred over cdxgen, addressing missing OS/distro metadata in cdxgen image SBOMs that prevents downstream vulnerability scanners (e.g., Trivy / Dependency-Track analyzer) from scanning OS packages.

Changes:

  • Reordered image generator priorities: syft-image → 25 (preferred), cdxgen-image → 40 (fallback).
  • Updated registry documentation and README generator selection docs to reflect the new image preference and rationale.
  • Adjusted unit tests to assert the new priority values and ordering for Docker image generation.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
tests/test_generation_plugin.py Updates tests to reflect new generator ordering/priorities for Docker images.
sbomify_action/_generation/generators/syft.py Lowers SyftImageGenerator priority to prefer it for Docker images; adds rationale docs.
sbomify_action/_generation/generators/cdxgen.py Raises CdxgenImageGenerator priority so it becomes the Docker image fallback; updates rationale/docs.
sbomify_action/_generation/generator.py Reorders default registry registration and updates priority documentation to match new behavior.
README.md Updates user-facing generator selection documentation to reflect Syft-first for Docker images.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines 6 to 7
Syft is a comprehensive SBOM generator that supports version selection.
It supports more versions than Trivy but is slightly lower priority.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in ff6a3b4 — reworded the module docstring so the Trivy comparison is scoped to lock files, and states that for Docker images Syft now ranks higher than both Trivy and cdxgen.

- Fix the syft.py module docstring: the "slightly lower priority than
  Trivy" comparison only holds for lock files now; for Docker images
  Syft ranks higher than both Trivy and cdxgen.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 16, 2026 12:54

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Comment on lines 315 to +320
# run_command raises SBOMGenerationError on failure (uses check=True).
# log_errors=False: cdxgen image scanning is a priority-20 fallback
# ahead of syft; a benign failure here shouldn't spam ERROR when syft
# can still succeed. (Docker-image-not-found is handled separately and
# still logs at WARNING.)
# log_errors=False: cdxgen image scanning is a fallback behind syft;
# a benign failure here shouldn't spam ERROR — the orchestrator
# surfaces a real ERROR only if every generator fails.
# (Docker-image-not-found is handled separately and still logs at
# WARNING.)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 2b97439 — reworded to say the pipeline raises SBOMGenerationError when every generator fails, rather than claiming the orchestrator logs an ERROR (the registry logs failures at INFO, as you noted).

- Fix the log_errors comment in CdxgenImageGenerator: the registry logs
  generator failures at INFO; what actually surfaces an all-generators
  failure is the SBOMGenerationError raised by the pipeline, not an
  ERROR log from the orchestrator.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 16, 2026 13:01

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Comment on lines +34 to 38
Priority 20 - Comprehensive Multi-Ecosystem (cdxgen, lock files):
- CdxgenFsGenerator: Filesystem/lock file scanning
- Input: Python, JavaScript, Java/Gradle, Go, Rust, Ruby, Dart, C++,
PHP, .NET, Swift, Elixir, Scala
- Output: CycloneDX 1.4-1.7 (no SPDX support)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in e6b6f87 — updated the generators/init.py docstring to the new priorities (syft-image 25, cdxgen-image 40) and reordered the list by priority. Also swept the generation module for any other stale priority references; none remain.

- Update the generators/__init__.py docstring to the new image
  generator priorities (syft-image 25, cdxgen-image 40), reordered
  by priority.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings July 16, 2026 13:08

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 6 out of 6 changed files in this pull request and generated no new comments.

@nissessenap

nissessenap commented Jul 16, 2026

Copy link
Copy Markdown

This PR closes #232

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

trivy can't scan syft or cdxgen SBOMs, DT vuln issue

3 participants