Gate the Rust dependency graph with cargo deny, and watch it with Dependabot and Trivy
Second of three CI-hardening pull requests for the Rust crate (card: hey-sdk Rust: CI hardening). Stacked on #155; the diff here is only the dependency-security layer. Merge #155 first.
What changes
rust/deny.toml is one cargo deny policy for both Cargo workspaces (rust/ and conformance/runner/rust):
advisories: RustSec, yanked crates denied, no ignores (each future entry carries the id, why it does not apply, and when to look again).licenses: an allow-list of real SPDX identifiers (MIT,Apache-2.0,Apache-2.0 WITH LLVM-exception,BSD-2-Clause,BSD-3-Clause,ISC,Unicode-3.0,Zlib,MPL-2.0,CDLA-Permissive-2.0,OpenSSL) — the fleet's list from the cross-repo Rust devex standard, not tuned to this tree, so an entry nothing uses yet is not a finding. The unpublished crates (generator, runner) are the repository's MIT and are skipped.bans:multiple-versions = "warn"— duplicates are a signal, not a defect (today:base640.22/0.23,syn2/3,winnow0.7/1);openssl-sysdenied since TLS is rustls; wildcard versions denied except the runner's path dependency.sources: crates.io only.
make rs-deny runs it over both workspaces (the runner with --config ../../../rust/deny.toml), and make rs-check now ends with it, so test-rust installs cargo-deny first (taiki-e/install-action, SHA-pinned, checksum-verified binary). CONTRIBUTING lists the tool.
Dependabot gets a grouped cargo entry for /rust and /conformance/runner/rust, with the same cooldowns as the Go entries.
security.yml gets trivy-rust beside trivy-go: Trivy reads each workspace's Cargo.lock (rust/ and conformance/runner/rust, uploaded under separate SARIF categories) and fails on HIGH/CRITICAL as the Go job does. It is the second reader of the same RustSec data on purpose — on a PR cargo deny has already failed on the same advisory, and the weekly run here is what puts findings on the Security tab — rather than a third tool: cargo audit reads the same database and was left out.
Verified locally: make rs-deny green on both workspaces (advisories, bans, licences, sources all ok, three duplicate-version warnings); make rs-check green; actionlint and zizmor clean apart from the pre-existing self-repository note.
Merge order
This PR is part of a five-PR stack, each rebased on the one below and all five on current main, so they merge cleanly in this order and only this order: #155 (build/MSRV/feature matrix) → #157 (cargo deny, Dependabot, Trivy) → #159 (semver-checks, packaging) → #160 (docs, examples, rustfmt) → #162 (crates.io publishing). Every one of them touches .github/workflows/test.yml and/or the Makefiles; the stacking is the conflict resolution. Merge each one after the one below has landed; GitHub retargets the next PR to main when the merged branch is deleted. #162 can merge before the crates.io bootstrap: it publishes nothing until the crate exists on crates.io (its publish job fails closed with instructions on a tag until then), and nothing in it changes after the bootstrap.