Security and Supply-Chain Patterns
Use this recipe when adding dependencies, handling secrets, permitting unsafe code, or preparing CI quality gates.
Dependency Rules
- Prefer standard library features over new dependencies when the code remains clear.
- Add dependencies with minimal features and no unnecessary default features.
- Verify crate maintenance, MSRV, license, feature flags, and transitive dependency impact.
- Avoid duplicate crates with overlapping responsibilities.
- Gate optional integrations behind Cargo features.
Optional Tooling
Recommend these when available:
cargo audit
cargo deny check
cargo tree -d
cargo outdatedFor library crates with published APIs, add cargo-semver-checks to CI to catch accidental semver violations before release; cargo-machete is a fast unused-dependency check worth running alongside cargo tree -d.
Keep the toolchain itself patched: cargo binaries before 1.96 carried known CVEs (libssh2 batch fixed in 1.96.1; CVE-2026-5222/5223 fixed in 1.96.0; tar CVEs fixed in 1.94.1). Pinning an old toolchain for reproducibility must be a deliberate, reviewed decision.
Use cargo vet for higher-assurance organizations that want review/audit provenance.
cargo-deny Starter
[advisories]
yanked = "warn"
ignore = []
[licenses]
allow = ["MIT", "Apache-2.0", "BSD-2-Clause", "BSD-3-Clause", "ISC", "Unicode-3.0"]
confidence-threshold = 0.8
[bans]
multiple-versions = "warn"
wildcards = "deny"
[sources]
unknown-registry = "deny"
unknown-git = "deny"Unsafe Policy
Default to forbidding unsafe code:
[lints.rust]
unsafe_code = "forbid"If unsafe is required:
- Scope unsafe blocks tightly.
- Add a
// SAFETY:comment explaining invariants. - Prefer safe wrappers around unsafe internals.
- Test boundary conditions and malformed input.
- Document safety contracts for public unsafe functions.
// SAFETY: `ptr` is created from a valid reference above and is not used after the
// referenced value is dropped. No aliasing mutable reference exists.
let value = unsafe { ptr.as_ref().ok_or_else(|| ServiceError::invalid_input("null pointer"))? };Secret Handling
- Never log secrets, tokens, passwords, or connection strings.
- Redact
Debugoutput for secret wrappers. - Prefer managed identity and workload identity over static credentials.
- Load secrets at startup or through a dedicated provider; avoid ad-hoc global mutable secrets.
- Do not serialize secrets unless explicitly required.
Network Security
- Use TLS by default for external network calls.
- Validate endpoint configuration.
- Set timeouts on all outbound calls.
- Retry only idempotent operations.
- Do not disable certificate validation in production examples.