Free SKILL.md scraped from GitHub. Clone the repo or copy the file directly into your Claude Code skills directory.
npx versuz@latest install jmagly-aiwg-plugins-security-engineering-skills-supply-chain-trustgit clone https://github.com/jmagly/aiwg.gitcp aiwg/SKILL.MD ~/.claude/skills/jmagly-aiwg-plugins-security-engineering-skills-supply-chain-trust/SKILL.md---
namespace: aiwg
name: supply-chain-trust
platforms: [all]
description: Decision aid for supply-chain trust beyond CVE/SBOM — pinning depth, reproducible builds, snapshot pins, firmware locking, and vendor+hash-lock for critical-path deps.
---
# supply-chain-trust
Decision aid for verifying that the code you ship is the code you think you're shipping. Use when designing or reviewing systems whose threat model includes supply-chain compromise (build host, dependency mirror, package registry, firmware) — which is most production systems in 2026.
The skill is distinct from `sdlc-complete`'s SBOM and CVE-scanning capabilities. SBOM tells you **what is there**. CVE scanning tells you **what is known-broken**. This skill answers **"can I prove that what I shipped is what I expected, end-to-end"** — which neither of the others does.
## Triggers
- "reproducible build"
- "snapshot pinning" / "snapshot.debian.org"
- "vendor wheels" / "hash-locked deps"
- "firmware version" / "firmware pinning"
- "in-toto" / "SLSA"
- "transparency log" / "Sigstore"
- "build host compromise"
- "supply chain attack"
## When NOT to use this skill
- Pure CVE scanning of declared dependencies (use `sdlc-complete/skills/security-audit`)
- SBOM generation (use existing SBOM tooling — CycloneDX, SPDX)
- License compliance (out of scope; use a license scanner)
---
## Section 1: The four layers of supply-chain trust
```
Layer 4: Hardware / firmware
↑ (does the chip do what it says?)
Layer 3: Build environment
↑ (was the binary produced from the source we think?)
Layer 2: Source dependencies
↑ (did we get the source we expected?)
Layer 1: Source we wrote
↑ (we can audit this)
```
Each layer has its own attack surface and its own mitigations:
| Layer | Attack | Mitigation |
|---|---|---|
| 1 (own source) | malicious commit by insider | code review, signed commits, branch protection |
| 2 (deps) | typosquat, compromised maintainer, malicious update | pinning + hash-lock + vendoring; transparency logs |
| 3 (build) | compromised CI, build host malware | reproducible builds, signed-and-attested artifacts (in-toto, SLSA) |
| 4 (hardware) | malicious firmware, supply-chain implant | measured boot, vendor diversity, audit |
A system is only as trustworthy as the weakest layer in the chain it actually depends on.
---
## Section 2: Dependency pinning — beyond `requirements.txt`
### Suggested default: full hash-locked dependency manifests
For each language ecosystem:
| Ecosystem | Default tool | What it produces |
|---|---|---|
| Python | `pip-tools` (`pip-compile --generate-hashes`) → `requirements.txt` with hashes | `package==1.2.3 --hash=sha256:abc...` per dep, including transitive |
| Node | `npm ci` against `package-lock.json` (with `integrity` field), or `pnpm` | per-package SHA-512 integrity |
| Rust | `cargo` lock file (`Cargo.lock`) — versions only; for hashes use `cargo vet` |
| Go | `go.mod` + `go.sum` (per-module SHA-256) |
| Ruby | `Bundler` lockfile + `bundle config set --local frozen true` |
| Maven/Gradle | `dependency:resolve-plugin` with checksum verification |
**Required**: every dependency, including transitive, must have a hash in your lockfile. If a tool can't produce hashed locks, vendor the dep.
### Vendoring critical-path deps
For dependencies in security-sensitive paths (auth, crypto, key handling), go further than hash-locking — **vendor** them:
```
your-repo/
vendor/
python-fido2-1.1.3/ # checked-in source of the dep
cryptography-41.0.7/ # ditto
...
Cargo.toml or pyproject.toml # references vendor/ paths, not registry
```
Why vendoring on top of hash-locking:
- Hash-locking verifies you got the bytes you expected; vendoring lets you AUDIT those bytes
- A compromised registry could publish a new "version" with a malicious patch; you control what's in `vendor/`
- Reduces transitive surface — you can prune deps that you don't actually use
Cost: you own update cadence. Acceptable for security-critical paths; impractical for everything.
### Anti-pattern: SHA-verified `.deb` whose SHA came from poisoned `apt` repo (review M10)
Original: bootstrap verifies SHA-256 of each downloaded `.deb`, but the SHA-256 manifest itself comes from `apt-cache` against the build-time `apt` repo.
What this skill flags: the verification is **circular within the same trust domain**. If `apt` is compromised, the manifest is compromised, the SHAs are compromised, all three layers verify a poisoned package.
Remediation:
- **Pin to `snapshot.debian.org`** URLs with a specific timestamp (`http://snapshot.debian.org/archive/debian/20260301T000000Z/`) — content-addressed, immutable
- **Verify signed Debian `Release` file** with explicit Debian archive signing keys, ground-truth at the timestamp
- **Pin transitive `.deb` URLs** discovered at that timestamp; commit the resulting SHA manifest to your **signed** git repo
The hash of the package must come from a **separately-trusted channel** than the package itself.
---
## Section 3: Reproducible builds
### What it gives you
A reproducible build means: given the same source, the same build environment, and the same build inputs, **any builder produces a byte-for-byte identical output**. This lets you:
- Verify a third-party-built binary against your own rebuild
- Detect compromised CI by comparing CI output to your local rebuild
- Allow others to verify your published artifacts by rebuilding from source
### Suggested defaults
| Use case | Approach |
|---|---|
| Bootstrap installers | NixOS — reproducible by construction; the entire system specification is hash-tracked |
| Container images | Bazel + `rules_oci` OR Nix-built OCI images; pinned base layer with verified digest |
| Linux distro packaging | Reproducible Builds project tooling (`reproducible-builds.org`); `dpkg --reproducible` flag in Debian |
| Cross-platform binaries | Static linking, hermetic build env (Bazel), check `diffoscope` between rebuilds |
### Verification step
```bash
# Local rebuild
bazel build //my:artifact
sha256sum bazel-bin/my/artifact
# Compare to CI-published
sha256sum downloaded/artifact.tar.gz
# If they differ, run diffoscope to see what diverges
diffoscope bazel-bin/my/artifact downloaded/artifact.tar.gz
```
Common reproducibility breakers: timestamps in archives, build-time UUIDs, parallel-build nondeterminism, locale-dependent string sorting. The `reproducible-builds.org` site catalogs known issues per ecosystem.
### When reproducibility isn't worth it
For internal tools with a single source-of-truth build host and signed output, the value is marginal. Reproducibility shines when:
- You publish artifacts users will run (binaries, container images)
- Your CI runs untrusted code (third-party PRs, etc.)
- Your build host might be compromised and you want a way to detect it
---
## Section 4: Build attestation (in-toto, SLSA)
### Suggested default: SLSA Level 3+ attestation for production releases
SLSA (Supply-chain Levels for Software Artifacts) defines compliance levels:
| Level | What it requires | What it tells consumers |
|---|---|---|
| 0 | nothing | "this came from somewhere" |
| 1 | build process documented | "the build is repeatable in principle" |
| 2 | build runs on hosted CI; provenance generated | "we know which CI built it" |
| 3 | build is hermetic, isolated; provenance is signed and tamper-evident | "we can prove the build chain end-to-end" |
| 4 | additional constraints — two-person review, hermetic builds | "highest assurance" |
**Tooling:**
- `cosign` (Sigstore) — signs container images and arbitrary blobs; integrates with Rekor transparency log
- `slsa-github-generator` — produces SLSA L3 provenance from GitHub Actions
- `in-toto` (CMU) — generic supply-chain attestation framework
- `Tekton Chains` — Kubernetes-native build attestation
### Verification on consumer side
```bash
cosign verify --certificate-identity-regexp=...@my-org \
--certificate-oidc-issuer=https://token.actions.githubusercontent.com \
ghcr.io/my-org/my-image:1.2.3
```
Pin **specific certificate identities and OIDC issuers**. A bare `cosign verify` can be satisfied by any signature.
---
## Section 5: Hardware / firmware version locking
### Required pattern (review L6)
For systems with hardware-backed cryptographic operations (HSMs, YubiKeys, TPM-equipped hosts), pin to a known-good firmware range. Different firmware versions can have:
- Different cryptographic primitive support (FIDO2 features, attestation behavior)
- Different timing characteristics (side-channel surface)
- Different bug profiles
Example: YubiKey 5 firmware 5.4 vs 5.7 have **different FIDO2 PRF behavior**. Code that worked against 5.4 may fail or behave differently on 5.7.
### Inventory pattern
```yaml
# .aiwg/security-engineering/supply-chain/hardware-pins.yaml
yubikey-5:
tested-firmware: "5.4.3, 5.7.1"
acceptable-firmware: ">=5.4.0, <6.0"
test-vectors: "tests/yubikey-5-prf.txt"
last-validated: "2026-04-15"
tpm-2.0:
vendor: "Infineon"
acceptable-firmware: ">=7.83"
pcr-baseline: ".aiwg/security-engineering/chain-of-trust/pcr-baseline.yaml"
```
When a new firmware ships, run your test vectors against the new version before allowing it into production.
---
## Section 6: Worked examples
### Review M10 — SHA-256 manifest from poisoned apt source
Original: install-pkgs.sh verifies SHA-256 of each `.deb` file against a manifest produced by `apt-cache` at build time.
What this skill flags:
- Section 2 anti-pattern: verification within same trust domain as packaging
- Layer 2 attack: poisoned mirror produces consistent manifest + packages
Remediation:
- Pin to `snapshot.debian.org/archive/debian/<timestamp>/` URLs in install scripts
- Verify Debian `Release` file with explicit archive signing keys (`/usr/share/keyrings/debian-archive-keyring.gpg`)
- Generate `.deb` SHA manifest from the snapshot, NOT from `apt-cache`
- Commit the resulting manifest to a signed git repo
- Reproducibly rebuild the bootstrap partition; verify rebuild matches published
### Review H3 — `python-fido2` and transitive deps in PRF hot path
Original: bootstrap installs `python-fido2`, `cryptography`, `cffi`, `pyusb` from PyPI at first run.
What this skill flags:
- Layer 2 attack: PyPI compromise of any of 4+ packages affects PRF hot path
- Section 2: deps are not vendored OR hash-locked
Remediation (see also `auth-factor-design`):
- Replace `python-fido2` with `libfido2` C tools — drops Python from hot path
- If Python remains: vendor `python-fido2` + transitive deps with hash-locked wheels in bootstrap blob; verify per-wheel SHA-256 against manifest committed to signed repo; reproducible-build the bootstrap
### Review L6 — firmware version not documented
Original: design assumes "YubiKey 5 with FIDO2 PRF" without specifying firmware range.
What this skill flags:
- Section 5: hardware version not pinned
Remediation:
- Document tested firmware range (e.g., 5.4.0–5.7.x)
- Maintain test vectors in repo; run against any new firmware before adopting
- Operationally: standardize procurement to known-good firmware
---
## Section 7: Trust-boundary inventory
Mandatory exercise — for every external input to your build, document:
| Input | Source | Verification | Trust anchor |
|---|---|---|---|
| Source code (your repo) | git origin | signed commits + signed tags | dev signing keys |
| Source code (deps) | language registry | hash-locked manifest | dev publishes verified |
| Base OS packages | snapshot.debian.org | Debian archive key | embedded in keyring |
| Container base layer | OCI registry | image digest pinned | (none — ASSUMPTION) |
| Build CI | GitHub Actions | OIDC + SLSA L3 attestation | GitHub OIDC issuer |
| Hardware | physical procurement | (assumption: vendor not compromised) | (none — ASSUMPTION) |
| Firmware | (vendor) | version pinned, test vectors run | self-tested |
Rows with "ASSUMPTION" are explicitly accepted risks. Document why each assumption is acceptable.
---
## Section 8: Output format
When invoked as part of a review, produce findings in standard format. When authoring or updating, produce:
- `supply-chain-pins.yaml` — current pins for all layers
- `hardware-pins.yaml` — firmware versions tested
- `trust-boundary.md` — inventory and assumption acceptance
---
## Related
- **Existing**: `sdlc-complete/templates/security/sbom-guidance.md` (SBOM is upstream of this skill)
- **Existing**: `sdlc-complete/templates/security/dependency-policy-template.md` (this skill operationalizes the policy)
- **Companion skill**: `chain-of-trust-design` (Layer 3+4 — boot-time integrity)
- **Companion skill**: `physical-threat-modeling` (Layer 4 — hardware implant scenarios)
## Standards referenced
- SLSA Framework (`slsa.dev`)
- in-toto Specification (CMU)
- Reproducible Builds (`reproducible-builds.org`)
- Sigstore Cosign documentation
- NIST SP 800-204D — Strategies for Securing Software Supply Chains
- CISA Software Supply Chain Risk Management
- Trusted Platform Module 2.0 Library Specification (firmware identity)