From qa-sca
Configures and runs cargo-audit against the RustSec Advisory Database for Rust projects; covers `cargo audit` (vulnerability scan), `cargo audit fix` (automated dependency updates), `--deny unmaintained|unsound|yanked|warnings` exit-code control, `audit.toml` per-advisory suppression with mandatory `expires` + `reason`, SARIF output for GitHub Code Scanning upload, and `rustsec/audit-check` GitHub Actions integration. Use when the codebase has a Cargo.lock and needs Rust-specific SCA beyond what the multi-ecosystem npm-pip-maven-audit wrapper provides.
How this skill is triggered — by the user, by Claude, or both
Slash command
/qa-sca:cargo-audit-rustThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
[rustsec-readme]: https://github.com/rustsec/rustsec/blob/main/cargo-audit/README.md
cargo-audit scans a project's Cargo.lock against the
RustSec Advisory Database, a community-maintained
vulnerability DB for Rust crates covering memory safety, cryptographic flaws,
logic errors, malicious packages, and unmaintained crates
(rustsec.org/advisories).
Differentiation from npm-pip-maven-audit:
that skill lists cargo audit as one of eight native audit commands in a
single wrapper. This skill covers the Rust-specific depth: --deny flag
semantics, audit.toml suppression schema, cargo audit fix, SARIF output,
binary auditing via cargo audit bin, and the rustsec/audit-check GitHub
Action - none of which the multi-ecosystem skill documents.
Cargo.lock (binary or library with lockfile committed).osv-scanner (OSV.dev
DB) for cross-DB consensus - OSV exports RustSec advisories in real time
(rustsec.org), so both tools often agree; divergence
flags an advisory in one DB but not the other.Per cargo-audit README:
cargo install cargo-audit --locked
Minimum Rust version: 1.74 per rustsec-readme.
Platform package managers (consult rustsec-readme for current availability):
# Alpine Linux
apk add cargo-audit
# Arch Linux
pacman -S cargo-audit
# macOS Homebrew
brew install cargo-audit
To enable the cargo audit fix subcommand, install with the fix feature
(rustsec-readme):
cargo install cargo-audit --features=fix --locked
Run at the workspace root where Cargo.lock lives
(rustsec-readme):
cargo audit
Scan a specific lockfile path (rustsec-readme):
cargo audit -f path/to/Cargo.lock
cargo-audit fetches the RustSec Advisory Database on first run (a git clone
into ~/.cargo/advisory-db). Pass --no-fetch to skip the fetch in air-gapped
environments (rustsec-readme).
Exit codes per cargo-audit source:
| Code | Meaning |
|---|---|
| 0 | No vulnerabilities / denial criteria not triggered |
| 1 | Vulnerabilities found matching denial criteria |
| 2 | Execution error (missing lockfile, DB fetch failure) |
The --deny flag turns advisory categories into hard failures
(cargo-audit source - audit.rs):
# Fail on any vulnerability
cargo audit --deny warnings
# Fail on unmaintained crates specifically
cargo audit --deny unmaintained
# Fail on unsound (memory-unsafe) crates
cargo audit --deny unsound
# Fail on yanked crates in the lockfile
cargo audit --deny yanked
# Combine: fail on vulnerabilities AND unmaintained
cargo audit --deny warnings --deny unmaintained
--deny warnings is the special catch-all: it enables all denial categories
simultaneously per audit.rs source.
Per cargo-audit source, --format supports three values:
| Value | Use |
|---|---|
terminal | Default human-readable output |
json | Machine-readable; pipe to sca-prioritizer |
sarif | SARIF 2.1; upload to GitHub Code Scanning |
# JSON output for programmatic consumption
cargo audit --format json > cargo-audit.json
# SARIF output for GitHub Security tab
cargo audit --format sarif > cargo-audit.sarif
Persistent suppression belongs in .cargo/audit.toml at the repo root,
not as CLI --ignore flags (which are not auditable in git). Per the
audit.toml example:
# .cargo/audit.toml
[advisories]
# Advisory IDs to suppress - each MUST have a reason and expiry tracked in a
# companion comment or issue tracker entry
ignore = ["RUSTSEC-2024-0001"]
# Informational categories to surface as warnings (not hard failures)
informational_warnings = ["unmaintained", "unsound"]
# Minimum CVSS severity to report: "none" | "low" | "medium" | "high" | "critical"
severity_threshold = "medium"
[output]
# "terminal" | "json" | "sarif"
format = "terminal"
# Hard-fail categories (mirrors --deny flags)
deny = ["warnings"]
# Show inverse dependency trees alongside each finding
show_tree = true
[database]
# Skip remote fetch (for offline / air-gapped builds)
fetch = false
# Allow an advisory DB that has not been updated recently
stale = false
Suppression template (mandatory fields; absence of reason is an audit
debt risk):
[advisories]
ignore = ["RUSTSEC-2024-0999"]
# RUSTSEC-2024-0999: serde_cbor unmaintained
# Reason: we use serde_cbor only in test fixtures, not in production paths.
# Approved-by: [email protected]
# Re-review-date: 2026-09-30
# Tracking: JIRA-4567
Commit .cargo/audit.toml to the repository so suppressions are auditable
in git history and code review.
cargo audit fix automatically updates Cargo.toml version constraints to
pull in patched crate versions, then runs cargo update
(rustsec-readme):
# Preview changes without modifying files
cargo audit fix --dry-run
# Apply updates
cargo audit fix
Limitations: cargo audit fix is experimental per rustsec-readme;
it updates version constraints but cannot resolve conflicts in the dependency
graph - manual intervention is needed when the patched version is incompatible
with other constraints. Always run cargo test after applying fixes.
For auditing compiled binaries (e.g. checking a deployed artifact without access to source), install the companion crate and audit the binary (rustsec-readme):
# Compile with embedded dependency metadata
cargo install cargo-auditable
cargo auditable build --release
# Audit the compiled binary
cargo audit bin target/release/my-app
Binary auditing works best when the binary was compiled with cargo-auditable
which embeds Cargo.lock metadata into the ELF/Mach-O/PE section.
Use the official rustsec/audit-check action, which
wraps cargo audit, creates check runs, and (for scheduled workflows) opens
GitHub Issues for each advisory per audit-check README:
name: Security audit
on:
push:
paths:
- '**/Cargo.toml'
- '**/Cargo.lock'
schedule:
- cron: '0 0 * * *'
jobs:
security_audit:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: rustsec/[email protected]
with:
token: ${{ secrets.GITHUB_TOKEN }}
# Optional: comma-separated advisory IDs to suppress
# ignore: "RUSTSEC-2024-0001,RUSTSEC-2024-0002"
# Optional: subdirectory with Cargo.toml
# working-directory: crates/my-crate
CI gate behavior per audit-check-action:
For SARIF upload alongside the action:
- name: Run cargo audit (SARIF)
run: cargo audit --format sarif > cargo-audit.sarif || true
- uses: github/codeql-action/upload-sarif@v3
if: always()
with:
sarif_file: cargo-audit.sarif
| Anti-pattern | Why it fails | Fix |
|---|---|---|
--ignore RUSTSEC-xxxx in CI script | Not auditable in git; lost on script rewrite | Use [advisories] ignore in .cargo/audit.toml committed to repo |
No reason comment next to ignore | Silent debt accumulation | Mandatory reason + re-review date (Step 5 template) |
cargo audit without --deny | Vulnerabilities surface as warnings, not failures | Add --deny warnings or set deny = ["warnings"] in audit.toml |
Skip --format sarif upload | Findings invisible in GitHub Security tab | Emit SARIF + upload (Step 8) |
cargo audit fix without cargo test | A patched dep version may break compilation or tests | Always test after fix (Step 6) |
Omitting Cargo.lock from git (library crates) | cargo audit has nothing to scan | Commit Cargo.lock or generate it with cargo generate-lockfile in CI |
cargo audit fix is experimental per rustsec-readme and
cannot resolve conflicting version constraints automatically.cargo-auditable to have been used at
compile time; binaries without embedded metadata cannot be audited.rustsec/audit-check GitHub Actionnpm-pip-maven-audit - multi-ecosystem
native audit wrapper (mentions cargo-audit as one of eight tools)osv-scanner - cross-DB pair; OSV.dev receives
RustSec exports in real timesca-prioritizer - unifier agent for
multi-tool SCA findingsnpx claudepluginhub testland/qa --plugin qa-scaProvides CDSS development patterns for drug interaction checking, dose validation, clinical scoring (NEWS2, qSOFA), and alert classification integrated into EMR workflows.