UNPKG

@sebastienrousseau/dotfiles

Version:

The Trusted Shell Platform — Universal dotfiles managed by Chezmoi. Features Bash & Zsh for macOS, Linux & WSL. Rust modern tooling & enterprise-grade security.

202 lines (160 loc) 8.02 kB
--- title: "Verify a Release" date: 2026-05-17 --- # Verifying a Release Every release of the framework ships four independent attestations. Verify any of them, they're orthogonal and each rules out a different class of attack. | Artefact | Format | Tool | Threat covered | |----------|--------|------|----------------| | **SBOM** (`dotfiles-sbom.spdx.json`) | SPDX 2.3 JSON | any SBOM viewer | "what's in the release?", full component inventory | | **Cosign signature** (`.sig` + `.pem`) | sigstore keyless | `cosign verify-blob` | "did our CI actually produce this SBOM?", short-lived Fulcio cert + Rekor transparency-log entry | | **SLSA provenance** (`.intoto.jsonl`) | in-toto v1 / SLSA L3 | `slsa-verifier` | "what build process produced this?", workflow ID, source ref, builder identity | | **Unified manifest** (`ALL_SHA256SUMS` + `.sig` + `.pem`) | text + sigstore keyless | `cosign verify-blob` then `sha256sum -c` | "is every other asset on this release the one our CI produced?", one signed line per asset | All four are attached to every GitHub Release as assets, from v0.2.503 forward. Releases v0.2.500 through v0.2.502 carry the SBOM bundle only: the unified manifest landed in v0.2.503 and is forward-only (re-tagging earlier releases would break consumer pins on existing SHAs). --- ## TL;DR — verify v0.2.503+ end-to-end ```sh # 0. Pick the release to verify TAG=v0.2.503 REPO=sebastienrousseau/dotfiles # 1. Download every attestation artefact gh release download "$TAG" --repo "$REPO" \ --pattern dotfiles-sbom.spdx.json \ --pattern dotfiles-sbom.spdx.json.sig \ --pattern dotfiles-sbom.spdx.json.pem \ --pattern dotfiles-sbom.spdx.json.intoto.jsonl \ --pattern ALL_SHA256SUMS \ --pattern ALL_SHA256SUMS.sig \ --pattern ALL_SHA256SUMS.pem # 2. Verify Cosign signature on the SBOM (binds SBOM to CI workflow identity) cosign verify-blob \ --certificate dotfiles-sbom.spdx.json.pem \ --signature dotfiles-sbom.spdx.json.sig \ --certificate-identity-regexp "^https://github.com/$REPO/" \ --certificate-oidc-issuer https://token.actions.githubusercontent.com \ dotfiles-sbom.spdx.json # 3. Verify SLSA provenance (binds SBOM to exact source tag + builder) slsa-verifier verify-artifact dotfiles-sbom.spdx.json \ --provenance-path dotfiles-sbom.spdx.json.intoto.jsonl \ --source-uri "github.com/$REPO" \ --source-tag "$TAG" # 4. Verify the unified manifest, then verify every other asset against it. # One signed file covers all release artefacts in one shot. cosign verify-blob \ --certificate ALL_SHA256SUMS.pem \ --signature ALL_SHA256SUMS.sig \ --certificate-identity-regexp "^https://github.com/$REPO/" \ --certificate-oidc-issuer https://token.actions.githubusercontent.com \ ALL_SHA256SUMS gh release download "$TAG" --repo "$REPO" --dir . # pull every other asset sha256sum -c ALL_SHA256SUMS # one line per asset ``` All four commands should print "Verified" / "PASSED" / "OK" and exit 0. If any fails, **the release was tampered with**: open an issue at <https://github.com/sebastienrousseau/dotfiles/issues> and do **not** install. --- ## Tool installation | Tool | macOS | Linux | Windows | |------|-------|-------|---------| | `gh` (GitHub CLI) | `brew install gh` | `apt install gh` / [release page](https://github.com/cli/cli/releases) | `scoop install gh` | | `cosign` | `brew install cosign` | `curl -sSfL https://github.com/sigstore/cosign/releases/latest/download/cosign-linux-amd64 -o /usr/local/bin/cosign && chmod +x /usr/local/bin/cosign` | `scoop install cosign` | | `slsa-verifier` | `brew install slsa-verifier` | `go install github.com/slsa-framework/slsa-verifier/v2/cli/slsa-verifier@latest` | `scoop install slsa-verifier` | If you don't have Go installed, fetch the pre-built `slsa-verifier` binary from <https://github.com/slsa-framework/slsa-verifier/releases> (SHA256-verify per their release notes). --- ## What each verification actually proves ### `cosign verify-blob` succeeds - The SBOM was signed by a workflow run **on this repository** (the `--certificate-identity-regexp` enforces it). - The signing OIDC token was issued by **GitHub Actions** (the `--certificate-oidc-issuer` enforces it). - The signature is recorded in the **Rekor public transparency log** (cosign queries this automatically) anyone can audit it. - The Cosign cert was issued by **Fulcio** (the sigstore CA) and was valid at the time of signing. This **does not** prove what the build process did only that "the file you have is the file CI produced." For "what did CI do", see SLSA verification below. ### `slsa-verifier verify-artifact` succeeds - The SBOM digest matches a provenance statement. - The provenance was generated by the **SLSA-Generator** running on **GitHub-hosted runners** for **this exact repository**. - The build was triggered by the named tag (`--source-tag $TAG`). - The provenance is anchored in Rekor (immutable, third-party-auditable). SLSA Level 3 is achieved because: (a) the provenance is generated by a *trusted, isolated* builder (slsa-github-generator), not by us; (b) the builder runs with hermetic, non-falsifiable inputs; (c) the provenance is signed by the builder's own identity, not ours. ### What none of this proves The framework's source code is **not formally verified**. SBOM + SLSA + Cosign protect the *supply chain* (you got what we shipped) not the *correctness* (what we shipped does what we claim). For correctness review: - Code is open under MIT read it. Start at `bin/dot`. - CI runs ~75 checks per PR (shellcheck, shfmt, CodeQL, Semgrep, Codacy, etc.). - Pre-commit hooks reject typos, unsigned commits, raw secrets. - See `docs/security/SCORECARD.md` for the OpenSSF score posture. --- ## In-shell one-liner for ongoing verification If you intend to install or update from a release tag, add this to your shell startup (already in `dot_config/shell/*` for users who run `chezmoi apply`): ```sh verify-dot-release() { local tag="${1:-$(gh release view --json tagName --jq .tagName \ --repo sebastienrousseau/dotfiles)}" local tmp tmp="$(mktemp -d)" ( cd "$tmp" \ && gh release download "$tag" --repo sebastienrousseau/dotfiles \ --pattern 'dotfiles-sbom.*' \ && cosign verify-blob \ --certificate dotfiles-sbom.spdx.json.pem \ --signature dotfiles-sbom.spdx.json.sig \ --certificate-identity-regexp '^https://github.com/sebastienrousseau/dotfiles/' \ --certificate-oidc-issuer https://token.actions.githubusercontent.com \ dotfiles-sbom.spdx.json \ && slsa-verifier verify-artifact dotfiles-sbom.spdx.json \ --provenance-path dotfiles-sbom.spdx.json.intoto.jsonl \ --source-uri github.com/sebastienrousseau/dotfiles \ --source-tag "$tag" ) local rc=$? rm -rf "$tmp" return $rc } ``` Usage: ```sh verify-dot-release # verify latest verify-dot-release v0.2.502 # verify specific tag ``` --- ## If verification fails 1. **Don't install.** Stop the bootstrap script. `^C` any in-flight `chezmoi apply`. 2. **Compare assets**. The release page shows file sizes if yours don't match what's on <https://github.com/sebastienrousseau/dotfiles/releases>, you downloaded from a man-in-the-middle. 3. **Report**: open an issue and email `security@sebastienrousseau.com` (encrypted to the WKD-published GPG key fingerprint `55AFAD364FD9DB3819E61F0C8D688FAFA9144693`). Acknowledgement SLA: 72 hours per `.github/SECURITY.md`. --- ## See also - `.github/SECURITY.md` coordinated disclosure policy. - `docs/security/KEY_ROTATION.md` disclosure-key rotation procedure. - `docs/security/SCORECARD.md` OpenSSF Scorecard posture. - `docs/operations/HARD_AUDIT_2026.md` Part 7 the GPG key generation + WKD publication record. - [Sigstore Cosign docs](https://docs.sigstore.dev/cosign/signing/overview/) - [SLSA verifier docs](https://github.com/slsa-framework/slsa-verifier)