Skip to content

SBOM

Automated generation of a Software Bill of Materials in CycloneDX format for supply chain transparency and compliance.

FieldValue
Workflow.github/workflows/release.yml (job sbom)
Toolanchore/sbom-action
FormatCycloneDX JSON
TriggersVersion tags, workflow_dispatch dry-run

A machine-readable inventory of:

  • All dependencies (direct and transitive)
  • License information
  • Package versions
  • Supplier information

Common uses: supply chain security (EO 14028 compliance), vulnerability tracking, license compliance, and dependency auditing.

During a release the sbom job in release.yml:

  1. Downloads the built platform binaries.
  2. Generates a CycloneDX JSON SBOM with anchore/sbom-action (output ${bin}-${version}-sbom.cdx.json).
  3. Attests the SBOM with actions/attest-sbom, binding every binary to the SBOM.
  4. Uploads it as a build artifact and attaches it to the GitHub release.
{
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"metadata": {
"component": {
"type": "application",
"name": "rust_template",
"version": "0.1.0"
}
},
"components": [
{
"type": "library",
"name": "serde",
"version": "1.0.0",
"licenses": [{ "license": { "id": "MIT" } }],
"purl": "pkg:cargo/serde@1.0.0"
}
]
}
  • Executive Order 14028 — machine-readable format (CycloneDX; SPDX also acceptable to regulators), dependency enumeration, license identification, supplier information.
  • NIST SP 800-161r1 — supply chain risk management.

The CI job uses anchore/sbom-action, which wraps Syft. The local equivalent is syft directly (or cargo cyclonedx for a Cargo-native CycloneDX document):

Terminal window
# Install syft (the engine behind anchore/sbom-action)
curl -sSfL https://raw.githubusercontent.com/anchore/syft/main/install.sh | sh -s -- -b /usr/local/bin
# Generate a CycloneDX JSON SBOM
syft dir:. -o cyclonedx-json > sbom.cdx.json
# View SBOM
cat sbom.cdx.json | jq '.components[] | {name, version, licenses}'

Alternatively, a Cargo-native CycloneDX generator:

Terminal window
cargo install cargo-cyclonedx
cargo cyclonedx --format json

Verify: sbom.cdx.json parses as JSON and lists component entries.

Terminal window
# Download from a GitHub release
wget https://github.com/zircote/rust-template/releases/download/v0.1.0/rust_template-0.1.0-sbom.cdx.json
# Validate with a CycloneDX-aware tool
cyclonedx validate --input-file rust_template-0.1.0-sbom.cdx.json

Verify: the validator reports the document as valid.

Terminal window
# SPDX JSON output (also accepted by regulators)
syft dir:. -o spdx-json
# Restrict to a single artifact
syft dir:. -o cyclonedx-json --select-catalogers cargo

Verify: the output header reflects the requested format.

Missing dependencies — refresh the lockfile first:

Terminal window
cargo update
syft dir:. -o cyclonedx-json

License issues — unknown licenses appear blank or as NOASSERTION; declare your crate’s license in Cargo.toml:

[package]
license = "MIT"

Format errors — validate the document:

Terminal window
cyclonedx validate --input-file sbom.cdx.json

Verify: validation completes without errors.

An SBOM turns “trust us, the dependencies are fine” into a verifiable artifact. When a new CVE lands against a transitive dependency, the inventory answers “are we affected?” in seconds instead of a manual cargo tree audit, and the same document satisfies the machine-readable enumeration that EO 14028 and NIST SP 800-161r1 require. Generating it at release time and attesting it over the shipped binaries binds the bill of materials to exactly the versions that shipped, so the record reflects the released artifact rather than a drifting development tree.