diff --git a/.github/workflows/supply-chain.yml b/.github/workflows/supply-chain.yml new file mode 100644 index 0000000..9f8d5ce --- /dev/null +++ b/.github/workflows/supply-chain.yml @@ -0,0 +1,52 @@ +name: supply-chain + +on: + pull_request: + paths: ["Cargo.toml", "Cargo.lock", "deny.toml", ".github/workflows/supply-chain.yml"] + push: + branches: [main] + schedule: + - cron: "17 4 * * 1" + workflow_dispatch: + +permissions: + contents: read + +env: + # Pinned tool versions (latest releases at the time of writing; both install + # with --locked on current stable). Bump deliberately. + CARGO_AUDIT_VERSION: "0.22.2" + CARGO_DENY_VERSION: "0.20.2" + +jobs: + audit: + runs-on: ubuntu-22.04 + timeout-minutes: 30 + steps: + - uses: actions/checkout@v4 + - name: Install stable Rust + run: | + rustup toolchain install stable --profile minimal + rustup default stable + - name: Cache installed cargo tools + id: tools-cache + uses: actions/cache@v4 + with: + path: ~/.cargo/bin/cargo-audit + key: cargo-audit-${{ env.CARGO_AUDIT_VERSION }}-${{ runner.os }}-${{ runner.arch }} + - name: Cache cargo-deny + id: deny-cache + uses: actions/cache@v4 + with: + path: ~/.cargo/bin/cargo-deny + key: cargo-deny-${{ env.CARGO_DENY_VERSION }}-${{ runner.os }}-${{ runner.arch }} + - name: Install cargo-audit (pinned) + if: steps.tools-cache.outputs.cache-hit != 'true' + run: cargo install --locked cargo-audit --version "$CARGO_AUDIT_VERSION" + - name: Install cargo-deny (pinned) + if: steps.deny-cache.outputs.cache-hit != 'true' + run: cargo install --locked cargo-deny --version "$CARGO_DENY_VERSION" + - name: cargo audit (RustSec advisories) + run: cargo audit + - name: cargo deny (advisories, licenses, bans, sources) + run: cargo deny check diff --git a/deny.toml b/deny.toml new file mode 100644 index 0000000..fef215f --- /dev/null +++ b/deny.toml @@ -0,0 +1,35 @@ +# cargo-deny policy. Kept deliberately minimal; tighten as the project matures. +[advisories] +version = 2 +yanked = "deny" + +[licenses] +version = 2 +# Allow-list intentionally broader than the current tree; do not warn on unused entries. +unused-allowed-license = "allow" +# Permissive licenses only; extend deliberately (copyleft is not allowed). +allow = [ + "MIT", + "Apache-2.0", + "Unicode-3.0", + "Unicode-DFS-2016", + "BSD-2-Clause", + "BSD-3-Clause", + "ISC", + "Zlib", +] + +[bans] +# Duplicate crate versions are common in transitive trees (e.g. across a +# dependabot bump) and are not a security problem by themselves: report them +# as warnings (visible in CI logs) but do not fail the build. +multiple-versions = "warn" +# Wildcard version requirements ("*") in our own manifest are denied: every +# dependency must have a bounded requirement so builds are reviewable. +wildcards = "deny" +# Path dependencies of the workspace itself are exempt. +allow-wildcard-paths = true + +[sources] +unknown-registry = "deny" +unknown-git = "deny"