CRA Desk
Every generate step

Generating an SBOM for Rust (Cargo)

The step below writes a CycloneDX JSON software bill of materials (SBOM) in your own pipeline. The CRA Desk scan reads that file and turns it into a Cyber Resilience Act (CRA) readiness report - it never generates one for you.

Run in CI:

cargo install cargo-cyclonedx
cargo cyclonedx --format json
Produces:
bom.json
Format:
CycloneDX JSON
Generator documentation

What the generator actually reads

cargo-cyclonedx reads Cargo.lock, so the inventory is exactly what the lock resolved - not what a different feature set would compile. Committing Cargo.lock is what makes the file reproducible; a library crate that leaves the lock out of version control produces a different SBOM on every run.

Versions and package URLs

Crates come out as pkg:cargo purls matching OSV's crates.io advisories, which are fed by RustSec. Note what a lockfile-based inventory over-reports: build-dependencies, dev-dependencies and optional dependencies behind features you never enable are all in Cargo.lock whether or not they reach the shipped binary.

The whole CI job

GitHub Actions

- uses: actions/checkout@v4
- run: cargo install cargo-cyclonedx
- run: cargo cyclonedx --format json
- uses: mmalinowski/cradesk-action@v1
  with:
    sbom-path: bom.json

GitLab CI/CD

generate-sbom:
  script:
    - cargo install cargo-cyclonedx
    - cargo cyclonedx --format json

include:
  - component: gitlab.com/cradesk/scan/readiness@1
    inputs:
      sbom_path: bom.json

Only the first step changes with your stack - the CRA Desk step after it is identical everywhere.

What goes wrong here

A workspace writes one bom.json per member crate next to its Cargo.toml, so name the crate you ship rather than assuming a single file at the root.

Repositories with more than one thing in them

The lock is shared across a workspace but the output is not: each member crate gets its own file beside its Cargo.toml. That is convenient and it is also the moment to decide what the report is about - a workspace of ten crates that ships one has nine inventories nobody should be scanning.

What CRA Desk does with the result

Components from this build carry pkg:cargo package URLs, which the watch matches against OSV's crates.io advisories when the SBOM arrives and again as new advisories land. Matching runs on every plan; e-mail alerts and the full match list are what a paid plan adds.

A generator that runs is not the same as coverage. Components with no purl, no version, or from an ecosystem outside the ones we watch are counted as gaps in every report rather than reported as clean.

Other stacks