Cargo and Package Management

Dependency Auditing

Modern software projects frequently pull in dozens or hundreds of transitive crates. Dependency auditing inspects Cargo.lock and crate source code to detect known security vulnerabilities (CVEs and RustSec advisories), unmaintained or yanked crates, incompatible open-source licenses, and untrusted third-party build scripts.

                   Cargo.toml + Cargo.lock
                              |
       +----------------------+----------------------+
       |                      |                      |
       v                      v                      v
[ cargo-audit ]        [ cargo-deny ]         [ cargo-vet ]
Checks Cargo.lock      Enforces policies:     Verifies peer-reviewed
against RustSec        - Advisories           supply-chain audits for
Advisory Database      - License allowlist    every crate version &
(CVEs, yanked,         - Banned crates        diff (`supply-chain/`)
 unmaintained)         - Duplicate versions

Auditing Tools in the Rust Ecosystem

Tool Install Command Primary Focus
cargo-audit cargo install cargo-audit --locked Scans Cargo.lock against the RustSec Advisory Database for memory-safety bugs, CVEs, unmaintained crates, and yanked versions.
cargo-deny cargo install cargo-deny --locked All-in-one CI linter (deny.toml) checking security advisories, SPDX license compliance, banned dependencies, duplicate crate versions, and allowed registry sources.
cargo-vet cargo install cargo-vet --locked Supply-chain verification tool that ensures every third-party crate version in Cargo.lock has been audited by your team or a trusted organization.

Scanning for Security Advisories with cargo audit

Running cargo audit compares every package and version in Cargo.lock against the RustSec database:

cargo audit --deny warnings
    Fetching advisory database from `https://github.com/RustSec/advisory-db.git`
      Loaded 745 security advisories (from /Users/dev/.cargo/advisory-db)
    Scanning Cargo.lock for vulnerabilities (42 crate dependencies)

Policy Enforcement with cargo-deny (deny.toml)

A deny.toml file at the root of a repository enforces four automated gates via cargo deny check:

# File: deny.toml
[advisories]
unmaintained = "workspace"
yanked = "deny"

[licenses]
# Only allow permissive open-source licenses in the dependency graph
allow = [
    "MIT",
    "Apache-2.0",
    "Unicode-3.0",
    "BSD-3-Clause",
]

[bans]
# Warn when two major versions of the same crate are pulled into the build
multiple-versions = "warn"
# Forbid OpenSSL to ensure pure-Rust `rustls` is used everywhere
deny = [
    { name = "openssl-sys" },
]

[sources]
unknown-registry = "deny"
unknown-git = "deny"
allow-registry = ["https://github.com/rust-lang/crates.io-index"]

Inspecting cargo metadata Programmatically

Under the hood, auditing tools inspect the resolved dependency graph by running cargo metadata --format-version 1, which outputs machine-readable JSON describing every package, license, target, and resolved feature in the workspace:

#[derive(Debug)]
struct CrateLicenseCheck {
    name: &'static str,
    spdx_expr: &'static str,
}

fn is_approved_license(spdx: &str, allowed: &[&str]) -> bool {
    // A compound expression like "MIT OR Apache-2.0" passes if ANY branch is allowed
    spdx.split(" OR ")
        .any(|part| allowed.contains(&part.trim()))
}

fn main() {
    let allowed = ["MIT", "Apache-2.0", "BSD-3-Clause"];
    let crates = [
        CrateLicenseCheck { name: "serde", spdx_expr: "MIT OR Apache-2.0" },
        CrateLicenseCheck { name: "ring", spdx_expr: "Apache-2.0 AND ISC" },
    ];

    for c in crates {
        println!(
            "Crate {:<8} ({:<18}) approved: {}",
            c.name,
            c.spdx_expr,
            is_approved_license(c.spdx_expr, &allowed)
        );
    }
}
Crate serde    (MIT OR Apache-2.0 ) approved: true
Crate ring     (Apache-2.0 AND ISC) approved: false