# deny.toml — cargo-deny config (spec §6.1). # Run locally: cargo deny check. # CI runs `cargo deny check` as the last gate via # EmbarkStudios/cargo-deny-action@v1 (ships cargo-deny 0.19.x). [graph] # Use Cargo.lock as the source of truth for the dep graph. all-features = true [advisories] # Vulnerabilities fail CI. cargo-deny ≥ 0.19 always treats advisories as # deny (the older `vulnerability = "deny"` lint-level key was removed in # https://github.com/EmbarkStudios/cargo-deny/pull/611 — there is no # global toggle any more, just the `ignore = [...]` opt-out per RUSTSEC # id). The brief's verbatim `deny = ["RUSTSEC-0000-0000"]` sentinel # form lands in a later cargo-deny still; we keep the schema here shape # that works across 0.18.3, 0.19.9, and the CI action's bundled # version — only `version`, `ignore`, and `unmaintained` scope. # `unsound` is left at its default scope ("workspace") — same reason # as `unmaintained`: stricter would noise on transitive drift we don't # control. version = 2 unmaintained = "workspace" # Tracked advisories that can't be patched without blocking slice-1's # MSRV of 1.85 (rust-toolchain.toml). Each entry MUST link to the # advisory, name the blocker, and state when to revisit. ignore = [ # RUSTSEC-2026-0009 — `time` 0.3.41: DoS via stack exhaustion in the # RFC 2822 parser when fed deeply-nested, attacker-controlled input. # https://rustsec.org/advisories/RUSTSEC-2026-0009 # Patches landed in `time` 0.3.47 (cap recursion depth) but the # `time` 0.3.47+ line requires rustc 1.88, conflicting with the # slice-1 MSRV of 1.85 (rust-toolchain.toml; commit 27fb64a pinned # `time` to 0.3.41 for exactly this reason). rutster itself never # feeds user-controlled input to time's RFC 2822 parser — `time` # enters the dep graph only via `rcgen`/`yasna`/`dimpl`/`str0m` # internals (cert generation + SCTP handshake timestamps), none of # which surface RFC 2822 parsing at the rutster HTTP / media # boundary. Net: theoretical stack-exhaustion vector in code we # never exercise. Revisit when (a) MSRV lifts past 1.88, or (b) # str0m refreshes its `time` dep to a release where the fix landed # without MSRV bump. "RUSTSEC-2026-0009", ] [licenses] # Allow our own (GPL-3.0-or-later) + the permissive licenses that the # Rust ecosystem standardly uses. Confirmed at impl time by running # `cargo deny check licenses` (spec §6.1) — this list passes the full # str0m/opus/axum transitive graph clean. allow = [ "GPL-3.0-or-later", "MIT", "Apache-2.0", "BSD-3-Clause", "ISC", "Zlib", "Unicode-DFS-2016", "Unicode-3.0", ] confidence-threshold = 0.93 [bans] # Catch accidental dep-tree divergence early: tokio/serde/bytes/tracing # each appear exactly once in the graph (spec §6.1). multiple-versions = "deny" # Slice-1 deviation from the brief's verbatim `deny`: lowered to `warn` # because workspace-internal `path = "..."` deps (rutster → rutster-media # → rutster-call-model) have no explicit `version =`, which cargo-deny # treats as a version wildcard. The canonical fix is to add # `version = ""` on each path dep (Cargo best-practice # anyway), but that's a Cargo.toml change outside Task 6's two-file # scope (deny.toml + .github/workflows/ci.yml only). Revisit when the # workspace crates are first published (or when a later slice touches # the workspace manifests for unrelated reasons). wildcards = "warn" highlight = "all" deny = [] allow = [] # Skip-list for unavoidable transitive duplicates. Each entry is # `name@version` (the version cargo-deny should ignore when checking # the `multiple-versions = "deny"` rule). Investigated per cargo-deny's # inclusion graph — see each comment. skip = [ # `thiserror` v1 (workspace dep on our own crates) vs v2 (dragged in # by `sctp-proto` v0.10 → `str0m` v0.21). Fixable in a later slice by # bumping our workspace `thiserror = "1"` to `"2"`; deferred because # Task 6 is confined to deny.toml + .github/workflows/ci.yml (no # Cargo.toml edits). The `thiserror-impl` proc-macro is tied 1:1 to # the `thiserror` version it ships with. "thiserror@1.0.69", "thiserror-impl@1.0.69", # `r-efi` v5.3 vs v6.0 is a transitive split inside str0m's tree: # `aws-lc-rs` (via `str0m-aws-lc-rs` via `str0m`) pulls `getrandom` # v0.3 → `r-efi` v5.3, while `uuid` v1 (our direct dep) pulls # `getrandom` v0.4 → `r-efi` v6.0. # Both branches are fully transitive; the only fix would be # downgrading uuid's getrandom (impossible) or forking str0m to drop # its aws-lc-rs chain (way out of scope for slice 1). Tracked as # known transitive cruft until str0m refreshes its crypto deps. "r-efi@5.3.0", # `getrandom` v0.3 vs v0.4 — same transitive split as `r-efi` above # (v0.3 is the aws-lc-rs branch, v0.4 is the uuid branch), tracked # together. Both pull distinct `r-efi` versions, so the two skips # are coupled: skip one without the other and the dup remains. "getrandom@0.3.4", ] skip-tree = [] [sources] # crates.io only. No git deps. Keeps the build reproducible (spec §6.1, # PORT_PLAN supply-chain goal). unknown-registry = "deny" unknown-git = "deny" allow-registry = ["https://github.com/rust-lang/crates.io-index"] allow-git = []