Skip to content

feat(ci): add cargo-deny for supply-chain vulnerability scanning #2671

Description

@Ygnas

Problem Statement

OpenShell has no automated supply-chain vulnerability scanning against the RustSec advisory database. The project has ~300+ transitive dependencies in Cargo.lock, and known CVEs in those dependencies go undetected. There is no license compliance checking or protection against dependencies pulled from unknown registries or git sources.

Proposed Design

Add cargo-deny to CI to gate PRs against known vulnerabilities, license violations, and untrusted dependency sources.

1. deny.toml configuration

  • Advisories: Check all dependencies against the RustSec advisory database. Enforce a 30-day maximum DB staleness (maximum-db-staleness = "P30D") so CI cannot silently pass against outdated data. Warn on yanked crates. Flag unmaintained workspace crates. Acknowledge pre-existing transitive advisories with documented ignore entries (to be removed as upstream deps are upgraded):

    • RUSTSEC-2026-0190 — anyhow unsoundness in downcast_mut
    • RUSTSEC-2026-0204 — crossbeam-epoch pointer deref (transitive via metrics/quanta)
    • RUSTSEC-2023-0071 — rsa Marvin attack (transitive via spiffe, no direct exposure)
    • RUSTSEC-2025-0134 — rustls-pemfile unmaintained (transitive via older kube/hyper)
    • RUSTSEC-2026-0098, RUSTSEC-2026-0099, RUSTSEC-2026-0104 — rustls-webpki vulnerabilities (transitive via older rustls)
    • RUSTSEC-2025-0068 — serde_yml unsound+unmaintained (transitive via kube)
  • Licenses: Allow only permissive licenses (Apache-2.0, MIT, BSD variants, ISC, Zlib, CC0-1.0, Unlicense, Unicode-3.0, etc.). Ignore private/unpublished workspace crates.

  • Bans: Warn on duplicate crate versions (informational, not blocking).

  • Sources: Deny dependencies from unknown registries or git sources. Only allow crates.io. (Verified: the workspace currently has zero git dependencies.)

2. CI workflow (.github/workflows/cargo-deny.yml)

  • Triggers: merge group checks, PR branches (pull-request/*), daily scheduled run (catch newly disclosed CVEs), and manual dispatch.
  • Smart change detection: Skip the check on PRs that don't touch Cargo.toml, Cargo.lock, deny.toml, or the workflow file itself. Always run on schedule and manual dispatch.
  • Runner: Use the existing linux-amd64-cpu8 CI container image with mise for tool installation.

3. Local developer task

  • Add a rust:deny mise task so developers can run mise run rust:deny locally before pushing.

Alternatives Considered

  1. cargo audit instead of or alongside cargo denycargo deny check advisories covers the same RustSec DB scan. Using cargo deny alone avoids redundant tooling while also providing license, ban, and source checks that cargo audit doesn't offer.

  2. Snyk — Evaluated but found to handle Rust codebases poorly. cargo-deny is purpose-built for the Rust ecosystem.

  3. Strict wildcard ban (wildcards = "deny") — Requires all workspace crates to set publish = false in their Cargo.toml. Our workspace crates use version = "*" for internal path dependencies and cargo-deny treats crates without that flag as publishable. Not worth a mass Cargo.toml change since these are internal workspace deps, not a supply-chain risk.

  4. Hard-fail on all unmaintained crates (unmaintained = "all") — Would require skip-tree entries for unfixable transitive deps we can't control. Scoping to "workspace" catches our own crates without that maintenance burden.

Agent Investigation

  • Identified eight pre-existing transitive advisories that need acknowledged ignore entries
  • Verified that cargo deny check passes cleanly with the proposed configuration
  • Verified zero git dependencies in the workspace — crates.io-only source restriction is safe

cc @alangou

Metadata

Metadata

Assignees

No one assigned

    Labels

    github_actionsPull requests that update GitHub Actions codestate:acceptedA maintainer decided OpenShell should pursue this issuestate:in-progressWork is currently in progresstopic:securitySecurity issues

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions