Skip to content

feat(ci): describe images in CycloneDX, and say what each document is about - #81

Open
nikzen wants to merge 2 commits into
mainfrom
feat/sbom-identity
Open

feat(ci): describe images in CycloneDX, and say what each document is about#81
nikzen wants to merge 2 commits into
mainfrom
feat/sbom-identity

Conversation

@nikzen

@nikzen nikzen commented Aug 26, 2026

Copy link
Copy Markdown
Contributor

What changed

The lockfile document had the image's name. It carried --source-name "$IMAGE" and differed from the image document only in the version, so a tracker filed it as another release of the image rather than as the inventory of what the image was built from. It gets -source appended.

Its type said file. syft reports the type of what it read, and for a lockfile that is a file. The document is about the application built from it. An image archive already yields container, verified against a scan, so only this one document needs correcting.

Every package carried a guessed CPE. NVD entries match those on vendor and product alone. tokio 1.50.0 picked up CVE-2024-27308 that way: an advisory about mio below 0.8.11 on Windows, which NVD additionally records against every tokio from 1.30.0 with no upper bound, rated 9.1 critical. Not applicable, and permanent — no future version would have escaped it. 222 of 224 components in the image document carried such a guess, and 131 of 132 in the source document.

A supplier is set as well, since every guideline asking for these documents asks who to address a question about them to.

Verification

  • Generated both workflows in famedly-control against this branch. The step renders as intended and nothing else moved.
  • Ran the new syft invocations locally. The image scan yields container and the lockfile scan application after the correction, both with the supplier set, and no component keeps a guessed CPE.
  • Ran grype over the same crate inventory with and without the guessed CPEs: four advisories either way, all matched by PURL. The CI gate reads the same documents, so it sees no change.
  • Uploaded the results to Dependency-Track 5.0.5. Both documents land as separate projects with the right classifier, and the tokio false positive is gone — 13 findings instead of 14, with the four grype advisories still among them.

Made with Cursor

nikzen and others added 2 commits August 26, 2026 17:49
The documents exist to answer, on the day it is asked, which of our released
versions contains a component that has just become a problem. BSI TR-03183-2
says what such a document has to be to count: CycloneDX 1.6 or newer, or SPDX
3.0.1 or newer. syft writes CycloneDX 1.6, and its SPDX output stops at 2.3 —
so the format used until now could not serve its own purpose, and no flag was
going to change that.

The same switch happens to be what a tracking platform needs; Dependency-Track
and its kind ingest CycloneDX only. Two independent reasons, one direction.

Nothing is lost by dropping SPDX: `syft convert` produces it from these
documents for whoever asks in that format. Grype reads either — checked against
a document pair for the same packages, where both formats yield the same 27
advisories.

The version and the field set are separate questions. The fields TR-03183-2
wants beyond this — SHA-512, the BSI properties, the completeness indicator —
syft does not write, so a document is now in a conformant format without being
a conformant document. That is worth doing next, and it is not urgent until the
Annex I obligations apply at the end of 2027.

Co-authored-by: Cursor <cursoragent@cursor.com>
Three things these documents got wrong, all of them found by uploading ours to a
Dependency-Track instance and looking at what it made of them.

The lockfile document carried the image's own name and differed from it only in
the version, so a tracker filed it as another release of the image instead of as
the inventory of what that image was built from. It gets `-source` appended now,
which no reader can mistake for a version.

syft reports the type of what it read, and what it reads for a lockfile is a
file. The document is about the application built from that lockfile, and
anything sorting documents by kind reads this field to decide. An image archive
already yields `container`, so only the lockfile document needs the correction.

syft also guesses a CPE for every package it finds, and NVD entries match those
on vendor and product alone. Our `tokio 1.50.0` collected CVE-2024-27308 that
way: an advisory about `mio` below 0.8.11 on Windows, which NVD additionally
records against every `tokio` from 1.30.0 with no upper bound and rates 9.1
critical. Nothing here was affected, and no future version would have escaped it
either. Dropping the guesses costs nothing — grype reports the same four
advisories from these documents with or without them, because everything real
matched by PURL to begin with.

Worth knowing before anyone starts triaging: Dependency-Track keeps the CPE as
part of a component's identity, so this makes every component look new once and
discards whatever analysis was recorded against the old one. Landing it before
the first triage costs nothing; landing it after would cost that work.

The supplier goes in the same step. Every guideline that asks for these documents
asks who to direct a question about them to, and syft takes it as a flag.

Co-authored-by: Cursor <cursoragent@cursor.com>
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.

2 participants