> Learn how to generate Software Bill of Materials for Rust projects. Complete guide with Cargo.lock examples, workspace dependencies, and CycloneDX output.

- **Updated:** 2026-08-31

## Source vs Build SBOMs

Rust has excellent support for reproducible builds through Cargo, its package manager. The `Cargo.lock` file provides precise dependency information, making source SBOMs highly accurate.

The Rust ecosystem's security focus means:

- Crates are immutable once published
- `Cargo.lock` contains exact versions and checksums
- Reproducible builds are a first-class concern

For source SBOMs, you generate from `Cargo.lock`. For build SBOMs, you analyze the compiled binary (which embeds dependency information in debug builds).

## Lockfile Deep Dive

### Cargo.lock Structure

The `Cargo.lock` file contains precise dependency information:

```toml
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3

[[package]]
name = "actix-web"
version = "4.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e43428f1a9b00f007c853a2adf1e46700a2d81e1d498299a9d5198d417c8e030"
dependencies = [
 "actix-codec",
 "actix-http",
 "actix-router",
]

[[package]]
name = "serde"
version = "1.0.193"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89"
dependencies = [
 "serde_derive",
]
```

Each package entry includes:

- **name**: Crate name
- **version**: Exact semantic version
- **source**: Where the crate comes from (usually crates.io)
- **checksum**: SHA-256 hash for integrity verification
- **dependencies**: Direct dependencies of this crate

### Cargo.toml vs Cargo.lock

| File         | Purpose                                  | Commit to VCS?                                |
| ------------ | ---------------------------------------- | --------------------------------------------- |
| `Cargo.toml` | Dependency declarations (can use ranges) | Always                                        |
| `Cargo.lock` | Exact resolved versions                  | Yes for binaries/apps, Optional for libraries |

**Important for SBOMs:** Always use `Cargo.lock` for SBOM generation, as it contains the resolved versions.

## Workspace Dependencies

Rust workspaces allow sharing dependencies across multiple crates:

```
my-project/
├── Cargo.toml       # Workspace root
├── Cargo.lock       # Shared lockfile
├── app/
│   └── Cargo.toml
├── lib-core/
│   └── Cargo.toml
└── lib-utils/
    └── Cargo.toml
```

Workspace root `Cargo.toml`:

```toml
[workspace]
members = ["app", "lib-core", "lib-utils"]

[workspace.dependencies]
serde = { version = "1.0", features = ["derive"] }
tokio = { version = "1.0", features = ["full"] }
```

Member crate `Cargo.toml`:

```toml
[package]
name = "app"
version = "0.1.0"

[dependencies]
serde = { workspace = true }
tokio = { workspace = true }
lib-core = { path = "../lib-core" }
```

For workspace SBOMs, generate from the root `Cargo.lock` which covers all members.

## Build vs Runtime Dependencies

Cargo distinguishes between dependency types:

```toml
[dependencies]
serde = "1.0"              # Runtime dependency

[dev-dependencies]
mockall = "0.12"           # Test-only dependency

[build-dependencies]
cc = "1.0"                 # Build script dependency
```

**SBOM considerations:**

- `[dependencies]` - Should always be in your SBOM
- `[dev-dependencies]` - Usually excluded from production SBOMs
- `[build-dependencies]` - Consider including if build-time supply chain matters

## Generating an SBOM

SBOM generation is the first step in the [SBOM lifecycle](https://sbomify.com/features/generate-collaborate-analyze/). After generation, you typically need to enrich your SBOM with package metadata and augment it with your organization's details.

### Using sbomify GitHub Action (Recommended)

The [sbomify action](https://sbomify.com/sbomify-action/) is a swiss army knife for SBOMs that automatically selects the best generation tool for your ecosystem, enriches the output with package metadata, and optionally augments it with your business information – all in one step. It runs on [any CI platform](https://sbomify.com/sbomify-action/runtimes/), not just GitHub, and the source is [on GitHub](https://github.com/sbomify/sbomify-action/).

For Rust, sbomify uses **cargo-cyclonedx** under the hood, because Cargo resolves a Rust project more accurately than a generic scanner can.

**Standalone (no account needed):**

```yaml
- uses: sbomify/sbomify-action@master
  env:
    LOCK_FILE: Cargo.lock
    OUTPUT_FILE: sbom.cdx.json
    COMPONENT_NAME: my-rust-app
    COMPONENT_VERSION: ${{ github.ref_name }}
    ENRICH: true
    UPLOAD: false
```

Using `github.ref_name` automatically captures your git tag (e.g., `v1.2.3`) as the SBOM version. For rolling releases without tags, use `github.sha` instead. See our [SBOM versioning guide](https://sbomify.com/guides/how-to-version-sboms/) for best practices.

**With sbomify platform (adds augmentation and upload):**

```yaml
- uses: sbomify/sbomify-action@master
  env:
    TOKEN: ${{ secrets.SBOMIFY_TOKEN }}
    COMPONENT_ID: my-component-id
    LOCK_FILE: Cargo.lock
    OUTPUT_FILE: sbom.cdx.json
    AUGMENT: true
    ENRICH: true
```

### Alternative Tools

If you prefer to run SBOM generation tools manually:

**cargo-sbom (Rust-native):**

```bash
cargo install cargo-sbom
cargo sbom > sbom.cdx.json
```

**cargo-cyclonedx:**

```bash
cargo install cargo-cyclonedx
cargo cyclonedx --format json > sbom.cdx.json
```

**cdxgen:**

```bash
npm install -g @cyclonedx/cdxgen
cdxgen -t rust -o sbom.cdx.json
```

When using these tools directly, you'll need to handle enrichment and augmentation separately.

### GitLab CI

```yaml
generate-sbom:
  image: ghcr.io/sbomify/sbomify-action
  variables:
    LOCK_FILE: Cargo.lock
    OUTPUT_FILE: sbom.cdx.json
    UPLOAD: "false"
    ENRICH: "true"
  script:
    - sbomify-action
  artifacts:
    paths:
      - sbom.cdx.json
```

## Handling Special Cases

### Git Dependencies

Cargo supports dependencies from Git:

```toml
[dependencies]
my-crate = { git = "https://github.com/example/my-crate", rev = "abc123" }
```

These appear in `Cargo.lock` with Git-specific information:

```toml
[[package]]
name = "my-crate"
version = "0.1.0"
source = "git+https://github.com/example/my-crate?rev=abc123#abc123def456"
```

SBOM tools should capture the Git commit hash as the version identifier.

### Path Dependencies

Local path dependencies won't have version information from crates.io:

```toml
[dependencies]
my-local-crate = { path = "../my-local-crate" }
```

These are useful for workspaces but require special handling in SBOMs.

### Features

Cargo features affect what code is compiled:

```toml
[dependencies]
tokio = { version = "1.0", features = ["full"] }
serde = { version = "1.0", features = ["derive"], default-features = false }
```

Features can enable additional dependencies, so your SBOM should reflect the features used.

### Vendored Dependencies

For offline builds or additional supply chain control:

```bash
cargo vendor
```

This creates a `vendor/` directory. Your `.cargo/config.toml`:

```toml
[source.crates-io]
replace-with = "vendored-sources"

[source.vendored-sources]
directory = "vendor"
```

## Best Practices

1. **Always commit Cargo.lock** - Essential for reproducible builds and accurate SBOMs
2. **Use exact versions in production** - Pin versions in `Cargo.toml` for applications
3. **Audit regularly** - Use `cargo audit` alongside SBOM generation
4. **Review dependencies** - Use `cargo deny` for license and security policies
5. **Consider vendoring** - For high-security environments
6. **Document unsafe code** - Note any crates using `unsafe` in your SBOM metadata

## Security Tooling Integration

Rust's security ecosystem complements SBOM generation:

```bash
# Install cargo-audit
cargo install cargo-audit

# Check for vulnerabilities
cargo audit

# Use RustSec advisory database
cargo audit --db ./advisory-db
```

Combine `cargo audit` results with your SBOM for comprehensive vulnerability tracking.

## Further Resources

For more SBOM tools and resources, see our [SBOM Resources](https://sbomify.com/resources/) page, which includes additional Rust-specific tools like CycloneDX Rust, sbom-rs, and sbom4rust.

---

From sbomify: https://sbomify.com/guides/rust/
