Generating an SBOM for what you ship
A software bill of materials is the list of every component inside something you ship, with its version, in a format other tools can read. The Regulation requires one for every product, covering at least the top-level dependencies, and the reporting duty is unworkable without one: you cannot say whether a vulnerability in a component affects your product if you cannot say which products contain it.Annex I Part II(1)
The one-minute version, with syft
Syft is a free, open-source tool from Anchore that builds an SBOM by reading a container image, a source directory or a binary. Install it once and point it at a release.
# Install, on macOS brew install syft # ...or anywhere else curl -sSfL https://get.anchore.io/syft | sh -s -- -b /usr/local/bin # A container image you ship syft acme/agent:4.2.1 -o cyclonedx-json > sbom.json # A source checkout, at the tag you released syft dir:. -o cyclonedx-json > sbom.json # A binary or an installer syft file:./dist/agent-4.2.1.tar.gz -o cyclonedx-json > sbom.json
Replace the image or path with your own. The redirect writes the bill of materials to the file; syft keeps its progress on stderr, so the file stays valid JSON.
Which format
Either of the two standards. CycloneDX 1.4 to 1.7 in JSON or XML, or SPDX 2.2 and 2.3 in JSON. CycloneDX is the more common choice for application software and carries package URLs on every component, which is what a vulnerability advisory is matched against; SPDX is what a licensing team may already produce. If you have neither preference, use CycloneDX JSON.
Per release, from the build
One SBOM per version you still support, generated by the build rather than by hand. A file produced once and kept describes a build that is no longer the one in the field, and an advisory about a component you removed two releases ago will still match it. In a pipeline, the same command runs after the artefact is built and the file is stored beside it.
# GitHub Actions, after the image is built
- run: curl -sSfL https://get.anchore.io/syft | sh -s -- -b /usr/local/bin
- run: syft ghcr.io/acme/agent:${{ github.ref_name }} -o cyclonedx-json > sbom.json
- uses: actions/upload-artifact@v4
with: { name: sbom, path: sbom.json }Many build tools also emit CycloneDX directly through a plugin, for Maven, Gradle, npm, .NET and others. Whichever produces the list closest to what actually ships is the right one.
What to do with it
Check it, first. The free SBOM check matches the file against the catalogue of vulnerabilities being exploited in the wild and shows what comes back, without an account and without storing the file. A hit there is a reason to assess whether your product is affected; it is not by itself a reportable event.
The map of your components is sensitive. The security page says exactly what happens to an uploaded SBOM, in the check and in the product.
This produces evidence, timelines and drafts. It is not legal advice, and you remain the party responsible for reporting.