From zeroize-audit
Source-level analyzer for Rust crates in zeroize-audit: generates rustdoc JSON, performs trait-aware zeroization audits (Zeroize/Copy/Drop), scans dangerous APIs, outputs findings JSON.
How this agent operates — its isolation, permissions, and tool access model
Agent reference
zeroize-audit:agents/2b-rust-source-analyzerinheritThe summary Claude sees when deciding whether to delegate to this agent
Identify sensitive Rust types and detect missing or incorrect zeroization at the source level. Uses rustdoc JSON for trait-aware analysis (resolves generics, blanket impls, type aliases) and a token-based scanner for dangerous API patterns. Produces source findings that drive crate-level compiler analysis. You receive these values from the orchestrator: | Parameter | Description | |---|---| | `...
Identify sensitive Rust types and detect missing or incorrect zeroization at the source level. Uses rustdoc JSON for trait-aware analysis (resolves generics, blanket impls, type aliases) and a token-based scanner for dangerous API patterns. Produces source findings that drive crate-level compiler analysis.
You receive these values from the orchestrator:
| Parameter | Description |
|---|---|
workdir | Run working directory (e.g. /tmp/zeroize-audit-{run_id}/) |
repo_root | Repository root path |
cargo_manifest | Absolute path to Cargo.toml |
rust_crate_root | Directory containing Cargo.toml (i.e. dirname(cargo_manifest)) |
rust_tu_hash | Short hash identifying this crate (e.g. a1b2c3d4) |
config | Merged config object (sensitive patterns, approved wipes) |
baseDir | Plugin base directory (for tool paths) |
Generate the rustdoc JSON file for the crate. This provides trait implementation data, derive macros, and type information needed for semantic analysis.
cargo +nightly rustdoc \
--manifest-path <cargo_manifest> \
--document-private-items -- \
-Z unstable-options --output-format json
The output is written to <rust_crate_root>/target/doc/<crate_name>.json. Find it with:
find <rust_crate_root>/target/doc -name "*.json" -not -name "search-index*.json" | head -1
If cargo +nightly rustdoc fails: write an error note and skip to Step 3 (dangerous API scan can still run without rustdoc JSON).
Run the trait-aware semantic auditor:
uv run {baseDir}/tools/scripts/semantic_audit.py \
--rustdoc <rustdoc_json_path> \
--cargo-toml <cargo_manifest> \
--out {workdir}/source-analysis/rust-semantic-findings.json
This detects:
#[derive(Copy)] on sensitive types → SECRET_COPY (critical)Zeroize/ZeroizeOnDrop/Drop → MISSING_SOURCE_ZEROIZE (high)Zeroize without auto-trigger → MISSING_SOURCE_ZEROIZE (high)Drop impl → PARTIAL_WIPE (high)ZeroizeOnDrop with heap fields → PARTIAL_WIPE (medium)Clone on zeroizing type → SECRET_COPY (medium)From/Into returning non-zeroizing type → SECRET_COPY (medium)ptr::write_bytes and no compiler_fence(...) call → OPTIMIZED_AWAY_ZEROIZE (medium, needs_review)#[cfg(feature=...)] wrapping cleanup → NOT_ON_ALL_PATHS (medium)#[derive(Debug)] on sensitive type → SECRET_COPY (low)#[derive(Serialize)] on sensitive type → SECRET_COPY (low)zeroize crate in Cargo.toml → MISSING_SOURCE_ZEROIZE (low)If the script is missing or fails: write a status-bearing error object to the output file and continue:
{
"status": "error",
"error_type": "script_failed",
"step": "semantic_audit",
"message": "<stderr or missing-script reason>",
"findings": []
}
Run the token/grep-based scanner across all .rs source files:
uv run {baseDir}/tools/scripts/find_dangerous_apis.py \
--src <rust_crate_root>/src \
--out {workdir}/source-analysis/rust-dangerous-api-findings.json
This detects:
mem::forget → MISSING_SOURCE_ZEROIZE (critical)ManuallyDrop::new → MISSING_SOURCE_ZEROIZE (critical)Box::leak → MISSING_SOURCE_ZEROIZE (critical)mem::uninitialized → MISSING_SOURCE_ZEROIZE (critical)Box::into_raw → MISSING_SOURCE_ZEROIZE (high)ptr::write_bytes → OPTIMIZED_AWAY_ZEROIZE (high)mem::transmute → SECRET_COPY (high)slice::from_raw_parts → SECRET_COPY (medium)mem::take → MISSING_SOURCE_ZEROIZE (medium).await → NOT_ON_ALL_PATHS (high)Findings without sensitive names in ±15 surrounding lines are downgraded to needs_review.
If the script is missing or fails: write a status-bearing error object to the output file and continue:
{
"status": "error",
"error_type": "script_failed",
"step": "dangerous_api_scan",
"message": "<stderr or missing-script reason>",
"findings": []
}
From the rustdoc JSON analysis, extract all sensitive types into the shared sensitive-objects.json. Read the existing file first (C/C++ objects may already be present) to determine the next available ID.
ID offset: Use SO-5000 as the starting ID for Rust objects to avoid collisions with C/C++ SO-NNNN IDs (which start at SO-0001).
Each sensitive object entry:
{
"id": "SO-5001",
"language": "rust",
"name": "HmacKey",
"kind": "struct",
"file": "src/crypto.rs",
"line": 12,
"confidence": "high",
"heuristic": "sensitive_name_match",
"has_wipe": false,
"wipe_api": null,
"related_findings": []
}
Append Rust entries to {workdir}/source-analysis/sensitive-objects.json. Create the file with [] if it does not exist.
Combine both finding arrays from Steps 2 and 3 into source-findings.json. Assign F-RUST-SRC-NNNN IDs (sequential, starting at 0001).
Each finding must include:
{
"id": "F-RUST-SRC-0001",
"language": "rust",
"category": "SECRET_COPY",
"severity": "critical",
"confidence": "likely",
"file": "src/crypto.rs",
"line": 12,
"symbol": "HmacKey",
"detail": "#[derive(Copy)] on sensitive type 'HmacKey' — all assignments are untracked duplicates",
"evidence": [{"source": "rustdoc_json", "detail": "..."}],
"related_objects": ["SO-5001"],
"related_findings": [],
"evidence_files": []
}
Append Rust findings to {workdir}/source-analysis/source-findings.json. Create with [] if the file does not exist.
Add the Rust crate entry to {workdir}/source-analysis/tu-map.json. Only add if at least one sensitive Rust object was found (otherwise no compiler-level analysis is needed).
{ "<cargo_manifest_path>": "<rust_tu_hash>" }
Read the existing tu-map.json first and merge; do not overwrite existing C/C++ entries.
Write all output files to {workdir}/source-analysis/:
| File | Content |
|---|---|
sensitive-objects.json | Appended Rust entries with SO-5000+ IDs |
source-findings.json | Appended Rust findings with F-RUST-SRC-NNNN IDs |
tu-map.json | Updated with {"<cargo_manifest>": "<rust_tu_hash>"} if sensitive objects found |
rust-semantic-findings.json | Intermediate output from semantic_audit.py (raw findings array or status-bearing error object) |
rust-dangerous-api-findings.json | Intermediate output from find_dangerous_apis.py (raw findings array or status-bearing error object) |
rust-notes.md | Summary: steps executed, finding counts by category, skipped steps and reasons |
| Entity | Pattern | Example |
|---|---|---|
| Rust sensitive object | SO-5000+ | SO-5001, SO-5002 |
| Rust source finding | F-RUST-SRC-NNNN | F-RUST-SRC-0001 |
Sequential numbering within this agent run. Zero-padded to 4 digits.
rust-notes.md, skip Step 2, continue with Step 3.rust-semantic-findings.json, continue.rust-dangerous-api-findings.json, continue.source-analysis-partial-failure in rust-notes.md.sensitive-objects.json (even if unchanged from C/C++ run) and tu-map.json.sensitive-objects.json, source-findings.json, tu-map.json) are missing, create them from scratch.| Category | Severity | Source |
|---|---|---|
MISSING_SOURCE_ZEROIZE | medium–critical | Steps 2 + 3 |
SECRET_COPY | low–critical | Steps 2 + 3 |
PARTIAL_WIPE | medium–high | Step 2 |
NOT_ON_ALL_PATHS | medium–high | Steps 2 + 3 |
OPTIMIZED_AWAY_ZEROIZE | medium–high | Step 2 (flag at source; confirmed at IR in rust-compiler-analyzer) |
npx claudepluginhub trailofbits/skills --plugin zeroize-auditAnalyzes Rust crates at MIR and LLVM IR levels to detect zeroization failures: dead-store elimination of wipes, stack retention, secret copies to FFI/aggregates, and path-specific drops. Crate-granular.
Rust security auditor for ownership and lifetime correctness, unsafe code verification, concurrency patterns, FFI safety, dependency scanning, and performance analysis. Delegate safety reviews and semantic LSP checks.
Expert Rust code reviewer focusing on safety, ownership, lifetimes, error handling, and idiomatic patterns. Runs cargo check, clippy, fmt, and tests on modified files.