Skip to content
Back to skills

Rust Supply Chain Attestation

ASecurity

How sparq attests its Rust/cargo supply chain — cargo-deny (advisories/bans/licenses/sources), cargo-vet/cargo-auditable, CycloneDX SBOM + VEX, SLSA build provenance, and OpenSSF Scorecard — and which evidence each tool produces for the SBOM, SLSA, NIST SSDF, EU CRA, and OpenSSF certification frameworks. Use when working any of the sbom/slsa/ssdf/cra/openssf certification worktrees, when adding or changing a supply-chain CI lane, when filling out an SBOM/VEX or a SLSA-level claim, or when ask...

  • 12 stars
  • 0 votes
  • 0 copies
  • 2 views
  • Added September 12, 2026
devopsrustgodockergitsecurity

Works with

  • cli

Security analysis

A100/100

Scanned October 6, 2026

npx -y skills add sparq-org/sparq --skill rust-supply-chain-attestation --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Rust Supply Chain Attestation?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Rust Supply Chain Attestation
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/sparq-org-rust-supply-chain-attestation/badge)](https://www.skillsdirectory.com/skills/sparq-org-rust-supply-chain-attestation)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: rust-supply-chain-attestation
description: How sparq attests its Rust/cargo supply chain — cargo-deny (advisories/bans/licenses/sources), cargo-vet/cargo-auditable, CycloneDX SBOM + VEX, SLSA build provenance, and OpenSSF Scorecard — and which evidence each tool produces for the SBOM, SLSA, NIST SSDF, EU CRA, and OpenSSF certification frameworks. Use when working any of the sbom/slsa/ssdf/cra/openssf certification worktrees, when adding or changing a supply-chain CI lane, when filling out an SBOM/VEX or a SLSA-level claim, or when asked what evidence a given framework wants from a cargo workspace. Grounded in sparq's real deny.toml + supply-chain.yml + scorecard.yml + dependency-monitoring.yml + release.yml.
---

# Rust supply-chain attestation (sparq)

How sparq proves the integrity of what it ships — a Rust **library + binaries +
container** consumed as a dependency on crates.io / npm (WASM) / PyPI / ghcr.
The dominant risk for a dependency is **supply-chain integrity + build
provenance**, so this is the highest-fit framework family. This skill is the
cargo-specific recipe so the `sbom`, `slsa`, `ssdf`, `cra`, and `openssf`
engineers do not re-derive it.

> NON-CANONICAL timing. No measured numbers belong in this file.

## The tools, what they prove, and which framework consumes the evidence

| Tool | What it asserts | Evidence artifact | Frameworks |
|---|---|---|---|
| **cargo-deny** (advisories) | No known-vulnerable / yanked dependency in the tree | CI log + the daily tracking issue | SBOM, SSDF (RV), CRA (vuln-handling) |
| **cargo-deny** (bans) | No banned/duplicate-version crate sneaks in | CI log | SSDF (PW), SBOM |
| **cargo-deny** (licenses) | Every dependency is permissive / explicitly excepted | CI log + `deny.toml` allowlist | SBOM (NTIA "license"), ISO 27001, CRA |
| **cargo-deny** (sources) | Crates come only from crates.io (no rogue git/registry) | CI log + `deny.toml [sources]` | SLSA, SSDF (PS), SBOM (supplier) |
| **CycloneDX SBOM** (`cargo-cyclonedx`) | The full component inventory of the build | `*.cdx.json` | SBOM (the artifact itself), CRA (Annex I §2), SSDF (PS.3) |
| **VEX** (CycloneDX/CSAF) | Why a flagged advisory is *not exploitable* in sparq | `*.vex.json` alongside the SBOM | SBOM, CRA (vuln-handling) |
| **cargo-auditable** | The exact dependency manifest is embedded *inside* the binary | `cargo audit bin <file>` reads it | SLSA, SBOM, SSDF |
| **cargo-vet** | Each dependency carries a human audit attestation | `supply-chain/audits.toml` | SLSA (higher assurance), SSDF (PS) |
| **attest-build-provenance** | This binary was built by *this* workflow run (Sigstore-signed) | `gh attestation verify` | SLSA (the core L2 claim), CRA, SSDF |
| **OpenSSF Scorecard** | Aggregate posture score (pinned deps, branch protection, SAST…) | SARIF in Security tab + public dashboard | OpenSSF, SSDF |

## How each is wired in sparq today (ground truth — cite these, don't re-propose)

### cargo-deny — `deny.toml` + `.github/workflows/supply-chain.yml`
The policy lives in `deny.toml` (schema targets cargo-deny >= 0.18, "version 2"
advisories/licenses). The `supply-chain.yml` `audit` job runs on the **host
stable toolchain** (not the EmbarkStudios Docker action — its bundled cargo 1.83
can't parse the vendored `spargebra`, which needs `edition2024` / cargo >= 1.85).

- **GATING now:** all four checks — `cargo deny check advisories bans sources licenses`
  — on push + PR, skipped only when the PR touches no Rust/dependency-graph file
  (the `rust_changed` step guard; `merge_group` is deliberately excluded).
- **Licenses:** an allowlist of permissive licenses only (MIT, Apache-2.0, BSD-*,
  ISC, Unicode-3.0, CC0-1.0, Zlib, BlueOak-1.0.0) plus **per-crate exceptions**
  (CeCILL-B for the sophia/HDT tree, AFL-3.0 for `ntriple`, MPL-2.0 for `resiter`,
  Apache-2.0-WITH-LLVM-exception, CDLA-Permissive-2.0 for `webpki-roots`). Each
  exception is scoped to one crate so the broad allowlist stays permissive-only.
- **Sources:** `unknown-registry = "deny"`, `unknown-git = "deny"`, only
  crates.io allowed. The vendored `spargebra` is a `[patch.crates-io]` PATH source
  (a path patch is not a registry/git source, so it doesn't trip the gate);
  `allow-git = []` is the hook for any deliberately-allowed future git source.
- **Advisories ignore list:** reserved for `unmaintained` *informational* advisories,
  and for advisories reachable only through a transitive dep with no fixed upstream
  release — each with a `reason` + tracking bead. A real, fixable **vulnerability** or a
  **yanked** crate FAILS the gate. Read `deny.toml [advisories].ignore` for the live set;
  do not quote a count from here. **Prefer removing the dependency to ignoring it** —
  the ignore list has shrunk that way three times: `paste` via wgpu (sq-l8bv,
  RUSTSEC-2024-0436) left when the GPU stack dropped it (it later returned via parquet);
  `rustls-pemfile` via ureq (sq-g2xs, RUSTSEC-2025-0134) left when the federation HTTP
  client moved ureq 2 → ureq 3; and when the solid-server-rs import brought
  `rustls-pemfile` back for its mTLS PEM parse, sq-5ah3p removed it again by
  migrating that parse to `rustls-pki-types`' `PemObject` — dropping the ignore, the VEX
  statement and the cargo-vet exemption in ONE change, which is what the `vex-deny-sync`
  gate requires. The gate re-flags any regression that reintroduces the crate.

### The advisories PR-gate (GX-1 — closed)
`cargo deny check advisories` is **GATING** — `supply-chain.yml`'s
`cargo-deny check (advisories) — GATING` step carries no `continue-on-error`
(the file contains none). The CVSS-4.0 parse blocker that once forced
`continue-on-error` — cargo-deny failing to *load* the freshly-cloned RustSec DB
("unsupported CVSS version: 4.0"), a DB-wide error before any per-advisory
`ignore` applied — is **resolved** (bead **sq-q8de**): cargo-deny >= 0.19 parses
CVSS v4.0, so the DB loads and the `ignore` rules apply as intended. The policy
is fail-closed (`deny.toml`: `yanked = "deny"`, advisories v2 ⇒ every unignored
advisory fails), so a real vulnerability or a yanked crate blocks the PR. The
daily watchdog (`dependency-monitoring.yml`) is **defence in depth**, not the
gate: it runs advisories-only off-peak and opens/updates a single idempotent
`security:dependency-vuln` tracking issue for advisories disclosed *between* PRs
on an unchanged graph. When an auditor asks "is there PR-time vuln gating?", the
honest answer is *yes* — cite that step.

### CycloneDX SBOM — `supply-chain.yml` `sbom` job
`cargo cyclonedx --all --format json` emits one SBOM per workspace member plus an
aggregate (`**/*.cdx.json`), uploaded as a CI **artifact**. Gaps the `sbom`/`cra`
engineers must close (GX-2): there is **no checked-in / per-release SBOM** and
**no VEX** yet. CRA/SBOM want a *published, per-release* SBOM with VEX to justify
non-applicable advisories. Map the SBOM to the **NTIA minimum elements**
(supplier, component name, version, unique identifier/PURL, dependency
relationship, author, timestamp) when scoring.

### SLSA build provenance — `release.yml`
- `actions/attest-build-provenance` (SHA-pinned) signs (Sigstore) an attestation
  binding each packaged archive's digest to the workflow run; verify with
  `gh attestation verify <file>`. Plus `SHA256SUMS` over all archives.
- The container build uses buildkit `provenance: mode=max` + `sbom: true`,
  attaching SLSA provenance + an embedded SBOM to the ghcr.io image (verifiable
  via cosign / gh).
- **Honest level:** ≈ **SLSA L2** on GitHub-hosted runners (signed provenance,
  hosted build platform). The gaps to higher (GX-7/GX-8): no `cargo-auditable`
  (binaries don't embed their dependency manifest), no `cargo-vet`, and no
  reproducible-build evidence. State the level *honestly* and name the gap —
  never inflate to L3.

### OpenSSF Scorecard — `scorecard.yml`
Runs on push-to-main + weekly; `publish_results: true` uploads to the public
OpenSSF dashboard (required for the Scorecard badge) and to code-scanning (SARIF).
Gaps for the `openssf` worktree: the **Best-Practices (bestpractices.dev / CII)**
questionnaire isn't filled (GX-4), and there's no `.well-known/security.txt`
(RFC 9116) machine-discoverable disclosure pointer (GX-3).

## How to use this when working a certification framework

1. **Don't re-propose existing controls.** The list above is the live posture;
   cite the file (`deny.toml:line`, `supply-chain.yml:job`) as evidence.
2. **Gap-fixes land test-first.** Use the `test-driven-development` skill — a new
   CI lane or a checked-in SBOM lands with a verifying check before the change.
3. **Frameworks → evidence:** SBOM → the `*.cdx.json` + NTIA mapping + VEX; SLSA →
   the provenance attestation + the honest level statement; SSDF → map PO/PS/PW/RV
   to these tools; CRA → SBOM + coordinated-disclosure discoverability +
   security-update channel; OpenSSF → Scorecard score + Best-Practices badge.
4. **Honesty contract.** Never let a control table launder a gap (the missing
   per-release SBOM/VEX, the SLSA-L2-not-L3 reality) into a "done". Record each
   gap as a bead, not a silent pass.

## Local commands
```
cargo install --locked cargo-deny cargo-cyclonedx cargo-auditable cargo-audit
cargo deny check                 # advisories + bans + sources + licenses
cargo deny check bans sources licenses   # the non-advisory-DB subset (offline)
cargo cyclonedx --all --format json      # CycloneDX SBOMs
gh attestation verify <archive> --owner jeswr   # SLSA provenance check
```

<!-- Authored for bead sq-toze.1 (epic sq-toze, cert framework). Grounded in
deny.toml + .github/workflows/{supply-chain,scorecard,dependency-monitoring,release}.yml.
 -->

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.