diff --git a/docs/troubleshooting.md b/docs/troubleshooting.md index 11fdb1c..ae69093 100644 --- a/docs/troubleshooting.md +++ b/docs/troubleshooting.md @@ -80,6 +80,71 @@ Do not silence a warning without understanding its contract or security impact. Prefer a small code correction and add a regression test if the warning exposed incorrect behavior. +## `cargo-deny` and `cargo-audit` failures + +CI enforces dependency security, license compliance, and supply-chain rules defined in [`deny.toml`](../deny.toml) across both `x86_64-unknown-linux-gnu` and `wasm32-unknown-unknown` targets. Run the full suite locally before pushing any `Cargo.toml` or `Cargo.lock` change: + +```bash +cargo deny check +cargo audit +``` + +### License check failures (`cargo deny check licenses`) + +If a new or updated crate uses a license not listed in `[licenses].allow` in `deny.toml` (or falls below `confidence-threshold = 0.8`), `cargo deny check licenses` will fail: + +1. Inspect the failing crate and its license identifier in the error output: + ```bash + cargo deny check licenses + ``` +2. Prefer replacing the dependency with an alternative licensed under one of the already-approved permissive licenses (`MIT`, `Apache-2.0`, `Apache-2.0 WITH LLVM-exception`, `BSD-2-Clause`, `BSD-3-Clause`, `ISC`, `Unicode-3.0`, `Unicode-DFS-2016`, `Zlib`, `CC0-1.0`, `MPL-2.0`). +3. If the dependency is required and its license is OSI-approved and compatible with the repository's MIT license, add the SPDX identifier to the `allow` list under `[licenses]` in `deny.toml` and explain the addition in your pull request. + +### Advisory check failures (`cargo deny check advisories` / `cargo audit`) + +`deny.toml` sets `yanked = "deny"` and checks RustSec advisories against `Cargo.lock`: + +1. **Vulnerability or unmaintained crate reported**: + Check which dependency chain pulls in the affected crate: + ```bash + cargo tree -i + ``` +2. **Upgrade first**: + Run `cargo update -p ` (or update the parent crate within semver-compatible bounds) and re-run `cargo test --workspace` and `cargo deny check advisories`. +3. **Yanked crate version**: + If a locked version was yanked on crates.io, run `cargo update -p ` so `Cargo.lock` resolves to a non-yanked release. + +### Duplicate dependency warnings and bans (`cargo deny check bans sources`) + +In `deny.toml`, `[bans]` sets `multiple-versions = "warn"` and `wildcards = "deny"`, while `[sources]` restricts crates to the official crates.io index (`unknown-registry = "deny"`, `unknown-git = "deny"`): + +- **Wildcard version constraints**: Never use `"*"` in `Cargo.toml`; always pin explicit semver ranges. +- **Duplicate crate versions**: Inspect duplicate versions with: + ```bash + cargo tree -d + ``` + Align feature flags or version ranges across workspace members (`learn-token`, `credential-nft`, `progress-tracker`) so Cargo unifies them to a single version in `Cargo.lock`. +- **Disallowed git or registry sources**: All dependencies must come from `https://github.com/rust-lang/crates.io-index`. + +### Adding new ignores to `deny.toml` + +Only add an ignore entry to `deny.toml` as a last resort when an upstream transitive dependency (for example, pulled in via `soroban-sdk`'s test environment) has no safe upstream fix available and does not affect on-chain WASM execution: + +1. Verify with `cargo tree -i --target wasm32-unknown-unknown` whether the crate is compiled into the production WASM binary or only used by host-side test tooling. +2. Add the RustSec advisory ID to `[advisories].ignore` (or the crate entry to `[bans].skip`) in `deny.toml` with a comment explaining: + - Which upstream crate pulls it in transitively, + - Why it cannot be upgraded directly right now, and + - Why it poses no risk to deployed contracts. + ```toml + [advisories] + ignore = [ + # Explain the transitive path (e.g., soroban-sdk -> soroban-wasmi) + # and why no upstream upgrade exists yet. + "RUSTSEC-YYYY-NNNN", + ] + ``` +3. Document the exception in the pull request description for maintainer review. + ## Deployment and invocation errors ### `Deployment file ... not found`