diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9553871..c7d17f6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -83,6 +83,56 @@ jobs: - name: cargo build (wasm32 release) run: cargo build --locked --workspace --target wasm32-unknown-unknown --release + contracts-audit: + name: Contracts Audit (cargo-deny / cargo-audit) + runs-on: ubuntu-latest + defaults: + run: + working-directory: contracts + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + toolchain: stable + + - name: Cache cargo artifacts + uses: Swatinem/rust-cache@v2 + with: + workspaces: contracts + + - name: Install cargo-deny + uses: taiki-e/install-action@v2 + with: + tool: cargo-deny + + - name: Install cargo-audit + uses: taiki-e/install-action@v2 + with: + tool: cargo-audit + + # Scan for license conflicts, duplicate crate versions, and + # unmaintained/vulnerable dependencies. The deny.toml config + # controls thresholds and allow-lists. + - name: cargo deny check + run: cargo deny check --show-stats + + # Fetch the latest RustSec advisory database and compare against + # every crate in the workspace. Exits non-zero (fails the build) + # when any advisory is found. + # + # Ignored advisories: + # RUSTSEC-2026-0009 — time v0.3.36 (DoS via stack exhaustion) + # Cannot update: time-core >=0.1.8 requires edition2024 (Rust >=1.85), + # but the contract-builder Docker image pins rust:1.84-slim. + # RUSTSEC-2024-0388 — derivative v2.2.0 (unmaintained) + # RUSTSEC-2024-0436 — paste v1.0.15 (unmaintained) + # Cannot upgrade: transitive dependencies of the Soroban SDK. + - name: cargo audit + run: cargo audit --deny=warnings --ignore RUSTSEC-2026-0009 --ignore RUSTSEC-2024-0388 --ignore RUSTSEC-2024-0436 + backend: uses: ./.github/workflows/node-matrix.yml with: diff --git a/contracts/deny.toml b/contracts/deny.toml new file mode 100644 index 0000000..4a9471d --- /dev/null +++ b/contracts/deny.toml @@ -0,0 +1,85 @@ +# cargo-deny configuration for VertexChain Solidity/Soroban contracts. +# +# This file is consumed by `cargo deny check`, which is invoked during CI +# (see the `contracts-audit` job in .github/workflows/ci.yml). +# +# Reference: https://embarkstudios.github.io/cargo-deny/ + +[advisories] +# cargo-deny v0.20+ always treats vulnerability advisories as hard errors. +# No `vulnerability` key is needed — it is enabled by default. +# +# Scope for unmaintained crate advisories: +# "all" — check every crate in the dependency graph. +# "workspace" — only check workspace members. +# "transitive"— check workspace members and their transitive deps. +# "none" — skip unmaintained checks entirely. +unmaintained = "workspace" +# Lint level for yanked crate advisories: +# "deny" — fail the build. +# "warn" — emit a warning but don't fail. +# "allow" — silently ignore. +yanked = "warn" +# Scope for unsoundness advisories (same values as unmaintained). +# Default is "workspace". +unsound = "workspace" +# Ignore known, accepted-risk advisories here. Each entry is the advisory ID +# from https://rustsec.org/advisories/. +ignore = [] + +[licenses] +# cargo-deny v0.20+ is deny-by-default: anything not in `allow` is denied. +# Allow-listed SPDX identifiers — all transitive dependencies must be covered +# by one of these. Add others when a new dependency introduces a license not +# already listed here. OSI-approved / FSF-free / commonly-used OSS licenses +# are preferred; proprietary or copy-left licenses should be reviewed before +# being added. +allow = [ + "MIT", + "Apache-2.0", + "Apache-2.0 WITH LLVM-exception", + "BSD-2-Clause", + "BSD-3-Clause", + "CC0-1.0", + "ISC", + "Unicode-3.0", + "Unlicense", + "Zlib", + "OpenSSL", + "MPL-2.0", +] +# Confidence threshold for license file detection (0.0 to 1.0). +confidence-threshold = 0.8 +# Suppress warnings when an allow-listed license is not used by any crate. +unused-allowed-license = "allow" +# Per-crate exceptions may be listed here for crates that need a license +# not in the global allow-list. Add entries like: +# [[licenses.exceptions]] +# allow = ["Zlib"] +# name = "adler32" +# version = "1.0" + +[bans] +# Prevent duplicate versions of the same crate in the dependency graph. +# Multiple versions are a source of bloat and can silently introduce +# incompatibilities. +multiple-versions = "warn" +# Crates whose duplicate versions are accepted (e.g., when two different major +# versions are required by separate dependencies). +# skip = [ +# { name = "syn", version = "1" }, +# ] +skip = [] +# Crates whose transitive dependency trees are ignored for duplicate detection. +# skip-tree = [ +# { name = "criterion", version = "0.5" }, +# ] +skip-tree = [] + +[sources] +# Only allow crates published to crates.io. Git / path dependencies should +# be rare and reviewed. +unknown-registry = "deny" +unknown-git = "deny" +allow-git = [] +allow-registry = ["https://github.com/rust-lang/crates.io-index"]