Rust's reputation for memory safety can lull teams into thinking dependency risk is someone else's problem. It is not. A crate can be perfectly memory-safe and still ship a logic flaw, a denial-of-service vector, or an unsafe block with an exploitable bug — and Rust projects pull in transitive crates just as eagerly as any other ecosystem. A mid-size binary can compile in a couple of hundred crates from your Cargo.lock, most of them chosen by other crates rather than by you. cargo-audit is the community's answer to auditing that graph.
How cargo-audit works
cargo-audit is maintained by the RustSec project. It reads your Cargo.lock — the fully resolved, exact-version dependency graph — and compares every crate against the RustSec Advisory Database, a curated feed of Rust-specific security advisories hosted at rustsec.org. Because it reads the lockfile, it sees the complete transitive set, not just the crates you named in Cargo.toml.
Install it as a Cargo subcommand and run it from your project root:
cargo install cargo-audit
cargo audit
The report lists each advisory, the affected crate and version, the patched versions, and a short description with a link to the advisory. cargo-audit also flags two categories that pure CVE scanners miss: crates that have been yanked from crates.io (often because a version was found to be broken or malicious) and crates marked unmaintained or unsound in the advisory database — early-warning signals that a dependency is becoming a liability even before a CVE lands.
Gating, filtering, and fixing
To make cargo-audit a strict CI gate, treat warnings as failures so unmaintained and yanked notices block the build alongside outright vulnerabilities:
cargo audit --deny warnings
When you have triaged a specific advisory and decided to accept it for now, ignore it explicitly rather than muting everything:
cargo audit --ignore RUSTSEC-2021-0000
For automation, request JSON output:
cargo audit --json > cargo-audit.json
cargo-audit also has an experimental fix capability, available when installed with the fix feature, that attempts to bump vulnerable crates to a patched version within your constraints:
cargo install cargo-audit --features=fix
cargo audit fix --dry-run
Preview with --dry-run first — as with any automated upgrade, a version bump can pull in incompatible transitive changes.
Beyond CVEs: warnings that predict future pain
The feature that sets cargo-audit apart from a plain CVE scanner is worth dwelling on. The RustSec database carries advisories that are not vulnerabilities in the classic sense: a crate marked unmaintained signals that no one is left to ship a fix when a bug is eventually found; a crate marked unsound has an API that can trigger undefined behavior from safe code even without a specific CVE; and a yanked version has been pulled from crates.io, sometimes because it was found to be malicious. Treating these as build-blocking warnings — via --deny warnings — gives you a genuine early-warning system. By the time a critical CVE is filed against an abandoned crate, you want to have already migrated off it, not be discovering the abandonment and the vulnerability in the same report.
The limitations
- No reachability. cargo-audit reports that a vulnerable crate version is in your lockfile. It does not analyze whether your code paths ever reach the vulnerable function, so a DoS advisory in a parser you never feed untrusted input is presented the same as a critical flaw in your network stack.
- RustSec scope. The RustSec database is excellent but Rust-specific and community-curated. Advisories can lag, and coverage depends on volunteers filing them.
- Lockfile-only. If your
Cargo.lockis not committed or not representative of what you ship, the audit describes a graph that may not match production. - No cross-repo policy. Each run is a local snapshot. There is no shared SLA, no persistent accepted-risk log with expiry, and no consolidated dashboard across the many services a Rust shop typically runs.
Extending the audit
Keep cargo-audit as your fast, local, Cargo-native gate — it is genuinely good at what it does, and the yanked/unmaintained detection is uniquely valuable. Then add a continuous layer for the questions it cannot answer. Safeguard's software composition analysis ingests the same Cargo.lock but adds call-path reachability, so the handful of advisories that touch code you actually execute are separated from the long tail that does not, and both are tracked with real policy rather than a per-run printout.
When a patched version exists, the autonomous auto-fix workflow opens a pull request that updates the crate and re-runs your build and tests, so the safe upgrades cargo-audit merely suggests become changes you can review and merge in minutes. Developers keep the tight local loop through the Safeguard CLI, which runs the same analysis on their machine and in CI without leaving the terminal.
Teams standardizing this across a fleet of Rust services can see how it scales on the pricing overview.
Rust dependency audit checklist
- Commit
Cargo.lock— for binaries always, and for auditing libraries too, so results are reproducible. - Run
cargo audit --deny warningsin CI to catch vulnerable, yanked, and unmaintained crates. - Use
--ignorewith a documented reason instead of silencing the whole run. - Preview
cargo audit fix --dry-runbefore applying automated upgrades. - Layer reachability-aware, continuous scanning so triage focuses on exploitable advisories and every service reports into one policy.
cargo-audit gives Rust teams a solid, ecosystem-native baseline — and its willingness to flag unmaintained and yanked crates is ahead of many mainstream tools. Add reachability, cross-service policy, and autonomous remediation on top, and you turn a periodic check into a program.
Bring continuous, prioritized auditing to your Rust services — get started free or read the documentation.