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¶
# 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 |
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-regexpenforces it). - The signing OIDC token was issued by GitHub Actions (the
--certificate-oidc-issuerenforces 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.mdfor 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):
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:
If verification fails¶
- Don't install. Stop the bootstrap script.
^Cany in-flightchezmoi apply. - 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.
- Report: open an issue and email
[email protected](encrypted to the WKD-published GPG key — fingerprint55AFAD364FD9DB3819E61F0C8D688FAFA9144693). 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.mdPart 7 — the GPG key generation + WKD publication record.- Sigstore Cosign docs
- SLSA verifier docs