Skip to content

Use cargo SBOM precursor files, if available #213

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

tofay
Copy link
Contributor

@tofay tofay commented Jun 19, 2025

If cargo sbom function is enabled, cargo-auditable will read the SBOM precursor file and use it to generate dependency information rather than trying to use the cargo metadata command.

Closes #192

Slightly interestingly, cargo didn't include build dependencies for the test fixtures unless I added a build.rs files.

If cargo sbom function is enabled, cargo-auditable will read the
SBOM precursor file and use it to generate dependency information
rather than trying to use the `cargo metadata` command.
@Shnatsel
Copy link
Member

Thanks a lot! I'll take a closer look in the next few days.

Slightly interestingly, cargo didn't include build dependencies for the test fixtures unless I added a build.rs files.

Looks like a bug in Cargo's SBOM support. I don't think we can actually ship with a bug like that.

@arlosi are you aware of this issue? Should we file a bug upstream against Cargo?

@tofay
Copy link
Contributor Author

tofay commented Jun 19, 2025

Isn't that a case of cargo being more accurate than cargo metadata? Without a build.rs, a crate can have no build dependencies, regardless of what is declared in Cargo.toml.

@Shnatsel
Copy link
Member

Ah, you are probably right! I am a little rusty on the finer points of Cargo dependencies.

Copy link
Member

@Shnatsel Shnatsel left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've only done a cursory look so far - it's a really hot day, sorry 😅

By and large this looks great! I've noted some nits, and I'll take a closer look at the format transformation algorithm in the next few days.

Thanks again!

let version_info = if sbom_path.as_ref().map(|p| !p.is_empty()).unwrap_or(false) {
let sbom_paths = std::env::split_paths(&sbom_path.unwrap()).collect::<Vec<_>>();
// Cargo may create multiple SBOM precursor files.
// We can't control per-binary (or cdylib) dependency information, just grab the first non-rlib SBOM we find.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I recall correctly, this is only reached when running a rustc command to compile a specific crate. Since dependencies are crate-wide, but a crate can have multiple targets (rlib, bin, cdylib, etc) it shouldn't really matter which SBOM we find - they should all contain identical dependency trees.

If I'm mistaken, I'd really like to know about that. And if my understanding is correct, we should include this as a comment.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does cargo emit an SBOM file per-target or per-binary? A single lib target can result in multiple binaries for each different specified library crate type through a single rustc invocation.

// cargo sbom data format has more nodes than the auditable info format - if a crate is both a build
// and runtime dependency it will appear twice in the `crates` array.
// The `VersionInfo` format lists each package only once, with a single `kind` field
// (Runtime having precence over other kinds).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// (Runtime having precence over other kinds).
// (Runtime having precedence over other kinds).

@@ -21,6 +21,7 @@ cargo_metadata = "0.18"
pico-args = { version = "0.5", features = ["eq-separator", "short-space-opt"] }
serde = "1.0.147"
wasm-gen = "0.1.4"
cargo-util-schemas = "0.8.1"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This pulls in a really sprawling dependency tree. If we're only using two structs from it anyway, I'd prefer to just copy-paste their definitions and avoid this massive dependency bloat.

cargo auditable is meant to be used by companies too, and I shudder at the thought of dragging all that through a security review.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I was going to ask about this, all 400 lines of cargo.lock additions are from this dep

@Shnatsel
Copy link
Member

Okay, I think I found an actual bug in Cargo: if I run cargo +nightly build -Z sbom --release and then CARGO_BUILD_SBOM=true cargo +nightly build -Z sbom --release, the SBOM file will not be actually generated. It seems that whether the SBOM should be built or not is not part of the check for whether a rebuild is necessary or not.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Enhancement: Use SBOM generated by Cargo
3 participants