
Rust Dependency Audit
- 70 installs
- 62 repo stars
- Updated August 3, 2026
- terrylica/cc-skills
Helps with security tasks.
About
rust-dependency-audit is a Claude Code skill for security. It helps solo builders move faster with AI-assisted development.
- rust-dependency-audit
- Security
- AI-coding skill
Rust Dependency Audit by the numbers
- 70 all-time installs (skills.sh)
- +1 installs in the week ending Jul 27, 2026 (Skillselion tracking)
- Ranked #1,176 of 2,203 Security skills by installs in the Skillselion catalog
- Data as of Aug 4, 2026 (Skillselion catalog sync)
npx skills add https://github.com/terrylica/cc-skills --skill rust-dependency-auditAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 70 |
|---|---|
| repo stars | ★ 62 |
| Last updated | August 3, 2026 |
| Repository | terrylica/cc-skills ↗ |
What it does
Helps with security tasks.
Files
Rust Dependency Audit
Comprehensive dependency audit workflow using four complementary tools: freshness checking, vulnerability scanning, license/advisory compliance, and supply chain verification.
Self-Evolving Skill: This skill improves through use. If instructions are wrong, parameters drifted, or a workaround was needed — fix this file immediately, don't defer. Only update for real, reproducible issues.
CRITICAL: Web-Verify Before Upgrade Decisions
Always check crates.io for latest versions before recommending upgrades. Static docs go stale; the crates.io API is ground truth.
1. Before upgrading a crate: Check what version is current and what it depends on
WebFetch: https://crates.io/api/v1/crates/{crate_name}
Prompt: "What is the latest version? List recent versions and their dependencies."2. Before ignoring a vulnerability: Verify whether a patched version exists
WebSearch: "{advisory_id} {crate_name} fix patch"3. Check compatibility chains: When crate A depends on crate B, verify both latest versions are compatible
WebFetch: https://crates.io/api/v1/crates/{crate_name}/{version}/dependencies
Prompt: "What version of {dependency} does this require?"4. Fallback: Firecrawl scrape (if WebFetch fails — JS-heavy pages, rate limits, incomplete data):
curl -s -X POST http://littleblack:3002/v1/scrape \
-H "Content-Type: application/json" \
-d '{"url": "https://crates.io/crates/{crate_name}", "formats": ["markdown"], "waitFor": 0}' \
| jq -r '.data.markdown'Requires Tailscale connectivity. See /devops-tools:firecrawl-research-patterns for full API reference.
When to Use
- Before a release (full audit pipeline)
- After
cargo update(verify no new vulnerabilities) - CI pipeline setup (automated dependency checks)
- License compliance review (open source projects)
- Supply chain security assessment
Four-Tool Audit Workflow
Run in this order — each tool catches different issues:
# 1. Freshness — what's outdated?
cargo outdated
# 2. Vulnerabilities — any known CVEs?
cargo audit
# 3. Licenses + Advisories — compliance check
cargo deny check
# 4. Supply Chain — who audited these crates?
cargo vetQuick Assessment
# One-liner: run all four (stop on first failure)
cargo outdated && cargo audit && cargo deny check && cargo vetFreshness: Finding Outdated Dependencies
Three tools for different needs:
| Tool | Install | Purpose | Best For |
|---|---|---|---|
cargo-outdated | cargo install cargo-outdated | Full outdated report with compatible/latest versions | Comprehensive audit |
cargo-upgrades | cargo install cargo-upgrades | Lightweight — only shows incompatible (breaking) updates | Quick check |
cargo upgrade (cargo-edit) | cargo install cargo-edit | Actually updates Cargo.toml versions | Performing updates |
# Show all outdated deps (compatible + incompatible)
cargo outdated --root-deps-only
# Show only breaking updates needed
cargo upgrades
# Actually update Cargo.toml (dry run first)
cargo upgrade --dry-run
cargo upgrade --incompatible
# Nightly: native cargo support (experimental)
cargo +nightly update --breakingRecommendation: Use cargo-upgrades for quick checks, cargo-outdated for full audits, cargo upgrade (cargo-edit) when ready to actually update.
See cargo-outdated reference.
Security: Vulnerability Scanning
cargo-audit (RUSTSEC Database)
# Scan for known vulnerabilities
cargo audit
# Auto-fix where possible (updates Cargo.lock)
cargo audit fix
# Binary scanning (audit compiled binaries)
cargo audit bin ./target/release/my-binary
# Custom config (ignore specific advisories)
# Create audit.toml:# audit.toml
[advisories]
ignore = [
"RUSTSEC-YYYY-NNNN", # Reason for ignoring
]See cargo-audit reference.
cargo-deny (Advisories + More)
cargo-deny's advisory check complements cargo-audit with additional sources:
# Check advisories only
cargo deny check advisories
# All checks (advisories + licenses + bans + sources)
cargo deny checkSee the License section below for full cargo-deny configuration.
License: Compliance Checking
cargo-deny License Check
# deny.toml
[licenses]
allow = [
"MIT",
"Apache-2.0",
"BSD-2-Clause",
"BSD-3-Clause",
"ISC",
"Unicode-3.0",
]
confidence-threshold = 0.8
[[licenses.clarify]]
name = "ring"
expression = "MIT AND ISC AND OpenSSL"
license-files = [{ path = "LICENSE", hash = 0xbd0eed23 }]# Check licenses
cargo deny check licenses
# Generate deny.toml template
cargo deny initSee cargo-deny reference.
Supply Chain: Audit Verification
cargo-vet (Mozilla)
cargo-vet tracks which crates have been audited and by whom:
# Check supply chain status
cargo vet
# Audit a specific crate (certify you've reviewed it)
cargo vet certify <crate> <version>
# Import audits from trusted organizations
cargo vet trust --all mozilla
cargo vet trust --all google
# See what needs auditing
cargo vet suggestKey files:
supply-chain/audits.toml— Your auditssupply-chain/imports.lock— Imported auditssupply-chain/config.toml— Trusted sources
See cargo-vet reference.
Unsafe Code: Dependency Safety Audit
cargo-geiger
cargo-geiger quantifies unsafe code usage across your entire dependency tree:
# Quick check: which deps forbid unsafe? (fast, no compilation)
cargo geiger --forbid-only
# Full audit: count unsafe blocks per crate
cargo geiger
# Output as ratio (for CI/scripting)
cargo geiger --forbid-only --output-format ratio
# Markdown report
cargo geiger --output-format markdown > unsafe-report.mdKey flags:
--forbid-only: Fast mode — only checks#--output-format:ratio,markdown,ascii,json--all-features: Check with all features enabled
See cargo-geiger reference.
Combined CI Workflow (GitHub Actions)
name: Dependency Audit
on:
pull_request:
schedule:
- cron: "0 6 * * 1" # Weekly Monday 6am
jobs:
audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Install Rust
uses: dtolnay/rust-toolchain@stable
- name: cargo-audit
run: |
cargo install cargo-audit
cargo audit
- name: cargo-deny
uses: EmbarkStudios/cargo-deny-action@v2
- name: cargo-vet
run: |
cargo install cargo-vet
cargo vet
- name: cargo-geiger
run: |
cargo install cargo-geiger
cargo geiger --forbid-only
- name: cargo-outdated
run: |
cargo install cargo-outdated
cargo outdated --root-deps-only --exit-code 1Reference Documents
- cargo-audit-guide.md — Vulnerability scanning
- cargo-deny-guide.md — License + advisory compliance
- cargo-outdated-guide.md — Freshness + alternatives
- cargo-vet-guide.md — Supply chain audit
- cargo-geiger-guide.md — Unsafe code quantification
Troubleshooting
| Problem | Solution |
|---|---|
cargo audit stale database | Run cargo audit fetch to update RUSTSEC DB |
cargo deny false positive license | Add [[licenses.clarify]] entry in deny.toml |
cargo vet too many unaudited | Import trusted org audits: cargo vet trust --all mozilla |
cargo outdated shows yanked | Run cargo update first to refresh Cargo.lock |
| Private registry crates | Configure [sources] in deny.toml for private registries |
| Workspace vs single crate | Most tools support --workspace flag |
Post-Execution Reflection
After this skill completes, check before closing:
1. Did the command succeed? — If not, fix the instruction or error table that caused the failure. 2. Did parameters or output change? — If the underlying tool's interface drifted, update Usage examples and Parameters table to match. 3. Was a workaround needed? — If you had to improvise (different flags, extra steps), update this SKILL.md so the next invocation doesn't need the same workaround.
Only update if the issue is real and reproducible — not speculative.
cargo-audit
Vulnerability scanning for Rust dependencies using the RustSec Advisory Database. The canonical tool for checking Cargo.lock against known CVEs.
Installation
cargo install cargo-auditBasic Usage
# Scan for known vulnerabilities
cargo audit
# Auto-fix where possible (updates Cargo.lock)
cargo audit fix
# Dry-run fix (show what would change)
cargo audit fix --dry-run
# Update the advisory database
cargo audit fetchOutput
cargo-audit reports:
- Advisory ID: RUSTSEC-YYYY-NNNN format
- Affected crate: Name and version range
- Severity: Informational, Low, Medium, High, Critical
- Description: What the vulnerability does
- Patched version: Version to upgrade to (if available)
Binary Scanning
Scan compiled binaries for vulnerable dependencies (doesn't need source):
# Scan a binary
cargo audit bin ./target/release/my-binary
# Scan multiple binaries
cargo audit bin ./target/release/*Binary scanning reads embedded dependency metadata from the Rust binary.
Configuration
audit.toml
Create audit.toml at project root:
[advisories]
# Ignore specific advisories (with documented reason)
ignore = [
# RUSTSEC-YYYY-NNNN: Not affected because we don't use feature X
"RUSTSEC-YYYY-NNNN",
]
# Severity threshold (ignore below this level)
severity-threshold = "medium"
# Treat informational advisories as warnings (not errors)
informational-warnings = ["unmaintained", "unsound"]
[database]
# Advisory database URL (default: RustSec GitHub)
# url = "https://github.com/RustSec/advisory-db"
# Path to local database (for air-gapped environments)
# path = "/path/to/advisory-db"CI Integration
GitHub Actions
- name: Security audit
run: |
cargo install cargo-audit
cargo auditWith audit-check Action
- uses: rustsec/audit-check@v2
with:
token: ${{ secrets.GITHUB_TOKEN }}Scheduled Scanning
name: Security Audit
on:
schedule:
- cron: "0 0 * * *" # Daily
push:
paths:
- "Cargo.lock"
jobs:
audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: cargo install cargo-audit && cargo auditRustSec Database
- Open source: <https://github.com/RustSec/advisory-db>
- Community-maintained advisories
- Covers: vulnerabilities, unmaintained crates, unsound APIs
- Auto-fetched on first run (cached locally)
- Update with
cargo audit fetch
Complementary Tools
| Tool | Overlaps With | Unique Value |
|---|---|---|
cargo-deny | Advisory checking | Also checks licenses, bans, sources |
cargo-vet | Supply chain | Audit trail, trusted organizations |
cargo-outdated | None | Freshness (not security) |
Recommendation: Use cargo-audit for quick vulnerability checks, cargo-deny for comprehensive policy enforcement.
Tips
- Run on CI: Every PR should pass
cargo audit - Schedule daily scans: New advisories are added frequently
- Ignore with reason: Always document why you're ignoring an advisory
- Auto-fix:
cargo audit fixis safe — it only updates Cargo.lock within semver - Binary scanning: Useful for auditing deployed artifacts
- Exit codes: 0 = clean, non-zero = vulnerabilities found (good for CI)
cargo-deny
Comprehensive dependency policy enforcement: advisories, licenses, bans, and source restrictions. More powerful than cargo-audit alone.
Installation
cargo install cargo-denyWhy cargo-deny
cargo-deny checks four categories:
| Check | What It Does |
|---|---|
| advisories | RUSTSEC vulnerabilities (like cargo-audit) + unmaintained warnings |
| licenses | Allow/deny license types for all dependencies |
| bans | Block specific crates or duplicate versions |
| sources | Restrict where crates can come from (crates.io, git, etc.) |
Quick Start
# Generate deny.toml template
cargo deny init
# Run all checks
cargo deny check
# Run specific check
cargo deny check licenses
cargo deny check advisories
cargo deny check bans
cargo deny check sourcesConfiguration: deny.toml
Advisories
[advisories]
# Vulnerability database
db-urls = ["https://github.com/rustsec/advisory-db"]
# How to handle advisories
vulnerability = "deny" # Deny known vulnerabilities
unmaintained = "warn" # Warn on unmaintained crates
unsound = "warn" # Warn on unsound APIs
yanked = "warn" # Warn on yanked versions
# Ignore specific advisories
ignore = [
# Reason for ignoring
"RUSTSEC-YYYY-NNNN",
]Licenses
[licenses]
# List of allowed licenses
allow = [
"MIT",
"Apache-2.0",
"BSD-2-Clause",
"BSD-3-Clause",
"ISC",
"Unicode-3.0",
"Zlib",
"Unicode-DFS-2016",
]
# Confidence threshold for license detection
confidence-threshold = 0.8
# How to handle unlicensed crates
unlicensed = "deny"
# Crate-specific license clarifications
[[licenses.clarify]]
name = "ring"
# ring uses a custom license
expression = "MIT AND ISC AND OpenSSL"
license-files = [
{ path = "LICENSE", hash = 0xbd0eed23 },
]
# Exceptions for specific crates
[[licenses.exceptions]]
allow = ["OpenSSL"]
name = "ring"Bans
[bans]
# How to handle multiple versions of the same crate
multiple-versions = "warn"
# Deny specific crates
deny = [
# Reasons should be documented
{ name = "openssl", wrappers = ["openssl-sys"] },
]
# Skip specific crate version combinations (for duplicate detection)
skip = [
{ name = "bitflags", version = "=1.3" },
]
# Skip entire dependency trees
skip-tree = [
{ name = "windows-sys" },
]Sources
[sources]
# Where crates are allowed to come from
unknown-registry = "deny"
unknown-git = "deny"
allow-registry = ["https://github.com/rust-lang/crates.io-index"]
allow-git = []
# Allow specific crates from git
[sources.allow-org]
github = ["my-org"]SARIF Output
Generate SARIF format for GitHub code scanning:
# SARIF output (for GitHub Security tab)
cargo deny check --format sarif > deny-results.sarifCI Integration
GitHub Actions (Official Action)
- uses: EmbarkStudios/cargo-deny-action@v2
with:
command: check
arguments: --all-featuresManual CI
- name: cargo-deny
run: |
cargo install cargo-deny
cargo deny checkWith SARIF Upload
- name: cargo-deny (SARIF)
run: |
cargo install cargo-deny
cargo deny check --format sarif > deny.sarif
continue-on-error: true
- uses: github/codeql-action/upload-sarif@v3
with:
sarif_file: deny.sarifWorkspace Support
# Check all workspace members
cargo deny check --workspace
# Check specific package
cargo deny check -p my-crateCommon Patterns
Permissive License Only
[licenses]
allow = ["MIT", "Apache-2.0", "BSD-2-Clause", "BSD-3-Clause", "ISC", "Zlib"]
copyleft = "deny"No Duplicate Dependencies
[bans]
multiple-versions = "deny"Crates.io Only (No Git Dependencies)
[sources]
unknown-registry = "deny"
unknown-git = "deny"
allow-registry = ["https://github.com/rust-lang/crates.io-index"]Tips
- Start with `cargo deny init`: Generates a well-documented template
- Incremental adoption: Start with
advisories, addlicenses, thenbans - License clarifications: Some crates need manual
[[licenses.clarify]]entries - SARIF integration: GitHub Security tab shows cargo-deny findings inline
- Multiple versions:
multiple-versions = "warn"is a good default (strict: "deny") - Complements cargo-audit: cargo-deny does everything cargo-audit does plus more
- Active maintenance: Frequent releases by Embark Studios — check crates.io for the latest
cargo-geiger
Quantifies unsafe code usage across your entire Rust dependency tree. Answers the question: how much unsafe code am I pulling in through my dependencies?
Installation
cargo install cargo-geigerWhy cargo-geiger
Rust's safety guarantees only hold for safe code. Dependencies can (and do) use unsafe blocks. cargo-geiger gives visibility into:
- Which dependencies use
unsafecode - How much
unsafeexists per crate - Which crates declare
#![forbid(unsafe_code)] - Overall safety ratio of your dependency tree
This complements clippy's unsafe lints, which only check your code — cargo-geiger audits the entire dependency tree.
Quick Usage
Fast Mode (No Compilation)
# Check which deps declare #![forbid(unsafe_code)] — no compilation needed
cargo geiger --forbid-onlyThis is the fastest check. It scans source files for the #![forbid(unsafe_code)] attribute without compiling anything. Ideal for CI pipelines.
Full Audit
# Count all unsafe blocks across the dependency tree
cargo geigerFull mode parses and analyzes every crate, counting unsafe usage in functions, expressions, and impls.
Output Formats
# Default ASCII tree (human-readable)
cargo geiger
# Ratio output (for CI thresholds)
cargo geiger --forbid-only --output-format ratio
# Markdown report (for documentation/PRs)
cargo geiger --output-format markdown > unsafe-report.md
# JSON output (for scripting/tooling)
cargo geiger --output-format jsonUnderstanding the Output
The default ASCII output shows a dependency tree with counters:
Metric output format: x/y
x = unsafe code used by the build
y = total unsafe code found
Symbols:
:) = No unsafe code found
! = Unsafe code detected
Functions Expressions Impls Traits Methods Dependency
0/0 0/0 0/0 0/0 0/0 :) my-crate 0.1.0
2/4 18/30 0/0 0/0 0/2 ! ├── some-dep 1.2.3
0/0 0/0 0/0 0/0 0/0 :) │ └── safe-dep 0.5.0Columns explained:
| Column | Meaning |
|---|---|
| Functions | Functions containing unsafe blocks |
| Expressions | Individual unsafe expressions |
| Impls | unsafe impl blocks |
| Traits | unsafe trait declarations |
| Methods | Methods containing unsafe code |
| x/y format | x = used in build / y = total found in source |
Key Flags
| Flag | Purpose |
|---|---|
--forbid-only | Fast mode: only check for #![forbid(unsafe_code)] |
--output-format | ascii, ratio, markdown, json |
--all-features | Check with all features enabled |
--no-default-features | Check without default features |
--features | Check with specific features |
--workspace | Check all workspace crates |
--package | Check a specific package |
--update-readme | Update safety badge in README |
CI Integration
GitHub Actions
- name: Unsafe code audit
run: |
cargo install cargo-geiger
cargo geiger --forbid-onlyThreshold-Based CI Gate
cargo-geiger's ratio output can be used to enforce safety thresholds:
- name: Unsafe code threshold
run: |
cargo install cargo-geiger
RATIO=$(cargo geiger --forbid-only --output-format ratio 2>/dev/null | tail -1)
echo "Safety ratio: $RATIO"
# Parse and enforce threshold (example: fail if <70% safe)Generate PR Report
````yaml
- name: Unsafe code report
run: | cargo install cargo-geiger echo "## Unsafe Code Report" >> $GITHUB_STEP_SUMMARY echo '``' >> $GITHUB_STEP_SUMMARY cargo geiger --forbid-only 2>/dev/null >> $GITHUB_STEP_SUMMARY echo '`' >> $GITHUB_STEP_SUMMARY ```
Comparison with Clippy's Unsafe Lints
| Aspect | clippy::unsafe | cargo-geiger |
|---|---|---|
| Scope | Your code only | Entire dependency tree |
| Granularity | Per-lint warnings | Per-crate counters |
| Speed | Part of normal build | Separate pass |
forbid check | #![forbid(unsafe_code)] in your crate | Across all deps |
| CI integration | Built into cargo clippy | Separate tool |
| Actionability | Fix your code | Choose safer dependencies |
Use both: clippy for your own code, cargo-geiger for your dependency tree.
Threshold Configuration
cargo-geiger does not have a built-in threshold config file. Implement thresholds via scripting:
#!/usr/bin/env bash
# scripts/check-unsafe-threshold.sh
# Count crates that use unsafe
UNSAFE_COUNT=$(cargo geiger --forbid-only 2>/dev/null | grep -c '!')
TOTAL_COUNT=$(cargo geiger --forbid-only 2>/dev/null | grep -cE '[:!]')
echo "Unsafe crates: $UNSAFE_COUNT / $TOTAL_COUNT"
MAX_UNSAFE=${1:-10} # Default threshold: 10 crates
if [ "$UNSAFE_COUNT" -gt "$MAX_UNSAFE" ]; then
echo "FAIL: $UNSAFE_COUNT crates use unsafe (threshold: $MAX_UNSAFE)"
exit 1
fi
echo "PASS: within threshold"Tips
- Start with
--forbid-only— it is fast and gives a useful overview - Use the full audit when evaluating new dependencies
- Generate markdown reports for security reviews and audits
- Combine with
cargo-audit(known vulns) andcargo-vet(review coverage) for complete supply chain security - Some
unsafeis expected and necessary (e.g.,libc,crossbeam) — focus on unexpected or excessive usage - The
x/yformat helps distinguish between unsafe code that is actually used in your build vs. dead unsafe code in the crate
Dependency Freshness: cargo-outdated and Alternatives
Three tools for checking and updating outdated Rust dependencies, plus emerging native Cargo support.
Tool Comparison
| Tool | Purpose | Install |
|---|---|---|
cargo-outdated | Full outdated report (compatible + latest versions) | cargo install cargo-outdated |
cargo-upgrades | Lightweight — only shows incompatible (breaking) updates | cargo install cargo-upgrades |
cargo upgrade (cargo-edit) | Actually updates Cargo.toml versions | cargo install cargo-edit |
cargo update --breaking | Native Cargo support (nightly) | Built-in (nightly only) |
cargo-unmaintained | Find unmaintained dependencies | cargo install cargo-unmaintained |
cargo-outdated
Full dependency freshness report showing both compatible and incompatible updates.
Usage
# Show all outdated dependencies
cargo outdated
# Root dependencies only (skip transitive)
cargo outdated --root-deps-only
# Specific depth
cargo outdated --depth 1
# Exit with error if outdated (for CI)
cargo outdated --exit-code 1
# Workspace mode
cargo outdated --workspaceOutput Format
Name Project Compat Latest Kind Platform
---- ------- ------ ------ ---- --------
serde 1.0.180 1.0.195 1.0.195 Normal ---
tokio 1.28.0 1.35.0 1.35.0 Normal ---
clap 4.3.0 --- 4.5.0 Normal ---- Project: Current version in Cargo.toml
- Compat: Latest compatible version (within semver range)
- Latest: Absolute latest version (may require version bump)
- Kind: Normal, Build, or Development dependency
Note on Maintenance
cargo-outdated works well for comprehensive audits. Cargo is gaining native support for dependency freshness (see cargo update --breaking below), which may eventually reduce the need for this tool.
cargo-upgrades
Lightweight alternative that only shows incompatible (breaking) updates:
# Show only breaking updates needed
cargo upgradesOutput is simpler — only shows deps where the Cargo.toml version specifier doesn't include the latest.
When to use: Quick check in development. No flags needed, fast execution.
cargo upgrade (cargo-edit)
Part of cargo-edit — actually updates version numbers in Cargo.toml:
# Dry run first (show what would change)
cargo upgrade --dry-run
# Update all dependencies to latest compatible
cargo upgrade
# Include incompatible (breaking) updates
cargo upgrade --incompatible
# Specific packages only
cargo upgrade -p serde -p tokio
# Specific package to specific version
cargo upgrade serde@<version>
# Workspace-wide
cargo upgrade --workspaceWhen to use: When you're ready to actually update dependencies, not just check.
Native Cargo Support (Nightly)
Cargo has native support for updating dependencies including breaking changes:
# Update deps including breaking changes (check `cargo update --help` for availability)
cargo update --breakingAs Cargo's native features mature, this may reduce the need for cargo-outdated for basic use cases.
cargo-unmaintained
Find dependencies that appear unmaintained:
# Check for unmaintained dependencies
cargo unmaintainedChecks for:
- No commits in 2+ years
- Repository archived
- No recent releases
- Marked unmaintained in RustSec DB
Recommended Workflow
Development
# Quick check: any breaking updates?
cargo upgrades
# Detailed check: what's outdated?
cargo outdated --root-deps-onlyBefore Release
# Full audit
cargo outdated --root-deps-only
cargo unmaintained
# Update compatible deps
cargo update
# Consider breaking updates
cargo upgrade --incompatible --dry-runCI
- name: Check outdated dependencies
run: |
cargo install cargo-outdated
cargo outdated --root-deps-only --exit-code 1
# Or weekly schedule
on:
schedule:
- cron: '0 6 * * 1' # Monday 6amTips
- `cargo update` first: Always run
cargo updatebeforecargo outdatedto refresh Cargo.lock - Root deps only:
--root-deps-onlyskips transitive deps (which you don't directly control) - Semver trust: Compatible updates (
cargo update) are generally safe; breaking updates need review - Yanked crates:
cargo outdatedshows yanked versions — runcargo updateto move off them - Lock file: Commit
Cargo.lockfor binaries, omit for libraries (Cargo convention)
cargo-vet
Mozilla's supply chain security tool for Rust. Tracks which crates have been audited, by whom, and enables importing audits from trusted organizations.
Installation
cargo install cargo-vetWhy cargo-vet
While cargo-audit checks for known vulnerabilities and cargo-deny enforces policies, cargo-vet answers a different question: has anyone actually reviewed this code?
cargo-vet maintains an audit trail:
- Which crate versions have been reviewed
- Who reviewed them
- What they certified (safe-to-deploy, safe-to-run)
- Imported audits from trusted organizations (Mozilla, Google, etc.)
Quick Start
# Initialize cargo-vet in your project
cargo vet init
# Check supply chain status
cargo vet
# See what needs auditing
cargo vet suggest
# Audit a crate (certify you've reviewed it)
cargo vet certify <crate> <version>How It Works
Certification Levels
| Level | Meaning | Use For |
|---|---|---|
safe-to-deploy | Reviewed for production use | Production dependencies |
safe-to-run | Reviewed for dev/build use | Dev-dependencies, build scripts |
Directory Structure
supply-chain/
├── config.toml # Trusted organizations, criteria
├── audits.toml # Your organization's audits
├── imports.lock # Imported audits (auto-generated)
└── exemptions.toml # Temporary exemptions (unaudited)Trusting Organizations
Import audits from organizations you trust:
# Trust all audits from Mozilla
cargo vet trust --all mozilla
# Trust all audits from Google
cargo vet trust --all google
# Trust specific crate audits
cargo vet trust serde --who mozillaAvailable Audit Sources
Major organizations publishing cargo-vet audits:
- Mozilla — Firefox codebase audits
- Google — Chromium/Android codebase audits
- Bytecode Alliance — Wasmtime/Cranelift audits
- Embark Studios — Game engine audits
Auditing a Crate
# Mark a crate version as audited
cargo vet certify serde <version>
# With specific certification level
cargo vet certify serde <version> --criteria safe-to-deploy
# Diff audit (review only the diff between versions)
cargo vet diff serde <old-version> <new-version>Diff Auditing
The most practical workflow — review only what changed between versions:
# See what changed between versions
cargo vet diff serde <old-version> <new-version>
# Opens a diff viewer
# After review, certify the delta:
cargo vet certify serde <new-version> --criteria safe-to-deployExemptions
For crates you haven't audited yet:
# Add temporary exemption
cargo vet add-exemption <crate> <version>Exemptions are tracked in supply-chain/exemptions.toml and serve as a TODO list.
Configuration
config.toml
[policy]
# Default criteria for dependencies
criteria = "safe-to-deploy"
# Per-crate policy overrides
[policy.my-dev-tool]
criteria = "safe-to-run" # Only used in development
[imports.mozilla]
url = "https://raw.githubusercontent.com/nickel-org/nickel.rs/cargo-vet/supply-chain/audits.toml"
[imports.google]
url = "https://chromium.googlesource.com/chromium/src/+/main/aspect/aspect-supply-chain/audits.toml?format=TEXT"CI Integration
- name: Supply chain audit
run: |
cargo install cargo-vet
cargo vetcargo-vet fails if any dependency lacks audits or exemptions — enforcing review coverage.
Workflow
Initial Setup
1. cargo vet init — creates supply-chain/ directory 2. cargo vet trust --all mozilla — import trusted audits 3. cargo vet suggest — see what's unaudited 4. For each unaudited crate: cargo vet certify or cargo vet add-exemption
Ongoing
1. cargo vet on every PR (CI) 2. When adding new deps: audit or exempt 3. When updating deps: diff-audit the changes 4. Periodically: review and remove exemptions
Reducing Audit Burden
# Import from multiple trusted orgs
cargo vet trust --all mozilla
cargo vet trust --all google
# Check remaining unaudited
cargo vet suggestMost popular crates are already audited by Mozilla or Google.
The Trifecta
For comprehensive dependency security, use all three:
| Tool | Question Answered |
|---|---|
cargo-audit | Are there known vulnerabilities? |
cargo-deny | Do licenses and policies comply? |
cargo-vet | Has someone actually reviewed this code? |
# Complete supply chain audit
cargo audit && cargo deny check && cargo vetTips
- Start with imports: Trusting Mozilla/Google covers most popular crates
- Diff audits: Review only deltas between versions — much faster than full audits
- Exemptions are OK: They're a tracking mechanism, not a failure
- Team workflow: Share
supply-chain/in version control — audits are cumulative - `cargo vet suggest`: Prioritizes crates by download count and dependency depth
- Not a replacement: cargo-vet complements cargo-audit and cargo-deny, doesn't replace them
Evolution Log: rust-dependency-audit
2026-03-01 — Initial Creation
- Created skill with 4 reference documents covering dependency audit trifecta
- Tools: cargo-audit (RUSTSEC), cargo-deny (license + advisory), cargo-vet (supply chain), cargo-outdated + alternatives
- Includes cargo-upgrades and cargo-edit as alternatives to cargo-outdated
- Notes native Cargo support for
cargo update --breaking(nightly) - All tools web-verified for maintenance status