Safeguard
Developer Tools•

How do you export a Rust dependency inventory with cargo metadata?

cargo metadata prints JSON describing every package and dependency in a Rust workspace. Here is how to use it for an inventory, with the flags that matter.

Safeguard Security Team
3 min read

Run cargo metadata with a pinned format version. It prints machine readable JSON describing the workspace, its packages and the resolved dependency graph. Add the locked option so it uses Cargo.lock as is. That output is a solid starting point for an inventory, an audit script or an SBOM.

What the output contains

The Cargo manual describes cargo metadata as outputting JSON about the current package. It includes all feature enabled dependencies unless the no deps flag is used, and the no deps output leaves the resolve data null. The manual recommends including the format version flag to future proof your code.

You get package names, versions, sources, features, targets and a resolved graph of who depends on whom.

Flags worth knowing

OptionWhat it does
format versionPins the JSON schema so scripts do not break
no depsOnly workspace members, no resolved graph
lockedRequires Cargo.lock to be up to date, errors otherwise
offlineDoes not touch the network
frozenEquivalent to locked plus offline, per the manual

A simple recipe

cargo metadata --format-version 1 --locked > metadata.json

From there, a short script can list each package with its version and source. The source field tells you whether a package came from a registry, a git repository or a local path. Anything that is not the registry you expect deserves a look, which links to blocking unknown registries and git dependencies with cargo deny.

Questions an inventory answers

  • Which crates are in the build, including transitive ones?
  • Are two versions of the same crate present? See cargo deny bans.
  • Which packages come from git or a path?
  • Which features are on for a given crate?

Limits to keep in mind

The metadata describes the graph for a given set of features and targets, so a different feature set can give a different list. It does not know what is compiled into a final binary, or about native libraries that a build script links. For those see what a -sys crate means for security and scanning a compiled Rust binary.

It also lists what is declared, not whether a vulnerable function is reachable. Treat the inventory as the first step, then add advisory data and reachability.

Where Safeguard fits

Safeguard's dependency scanning and SBOM generation produce a Rust inventory from your manifests without a custom script. You can try it with the free scan at gold.safeguard.sh/scan.

Try it yourself

Click through it at your own pace, or open it full screen.

Open the inventory and compare direct and transitive entries, the same split cargo metadata gives you.

Quick check

Does cargo metadata need the network?

Not if you use the offline option and the packages are already available. The frozen option combines locked and offline.

Why pass a format version?

The manual recommends it so your code keeps working if the JSON format changes.

Sources

Last reviewed: 19 October 2026.

Never miss an update

Weekly insights on software supply chain security, delivered to your inbox.

Self-healing security runs on Safeguard.

Your first fix PR is minutes away.

No sales call required, even your agent can complete the purchase over MCP.