Build verifiable artifacts
Create an SBOM
Generate a software bill of materials for each release so components, versions, relationships, and vulnerability impact can be queried later.
An SBOM (software bill of materials) is an inventory, not a certificate that software is safe. It helps answer what a release contains.
Here is the situation it exists for. A new compression-library advisory appears on Friday. The team has ten released images, and manifests alone cannot show which final images contain the affected operating-system package. With an SBOM per release, that becomes a query instead of a rebuild-and-check archaeology session.
Generate one
npm can produce an SBOM straight from the resolved dependency graph, in the standard SPDX format:
npm sbom --sbom-format spdx > sbom.spdx.json
That covers JavaScript packages. For a container image, generate the SBOM from the final image so operating-system packages and bundled binaries are included too. syft does this well:
syft ghcr.io/acme/api:1.4.2 -o spdx-json=sbom.spdx.json
# ✔ Cataloged 212 packages
The count in the output usually surprises people: the application’s npm tree plus every Debian or Alpine package in the base image.
Store it with the release, query it later
Store the SBOM beside the artifact, protect its integrity, and connect it to the exact artifact digest it describes. An SBOM that cannot be matched to specific released bytes answers nothing.
When Friday’s advisory arrives, query instead of guessing:
jq '.packages[] | select(.name == "zlib") | .versionInfo' sbom.spdx.json
# "1.2.13"
Now you know which releases contain the affected version, and which do not.
Generate at the right moment
Timing is the common failure. An inventory generated too early — from package.json before install, or from source before the container build — can omit bundled or container components. Generate from the final build or the resolved graph, after the last stage that adds files.
Generate an SPDX SBOM from a final application artifact or container and save it beside the artifact digest. Locate one direct, one transitive, and one operating-system component. Then add a component during the final build stage and prove whether the SBOM includes or misses it.
Lesson completed