From 177f80b69a8bce2c814ed9677597a6d6ce485492 Mon Sep 17 00:00:00 2001 From: Ben Limmer Date: Fri, 29 May 2026 11:28:00 -0600 Subject: [PATCH] fix: publish verifiable build provenance for releases A friend ran our installer past a due-diligence agent, which flagged it as risky: it couldn't find the source repo, checksums.txt offers no protection against a malicious publisher (the same release controls both the binary and the checksums), and the binary's behavior/telemetry were undisclosed in the script it read. Close the verifiable-trust gaps: - release.yml attests every release artifact with GitHub build provenance (Sigstore-signed, recorded in a public transparency log), verifiable with `gh attestation verify`. Stronger than checksums.txt: it ties each archive to this repo, commit, and workflow run. - analyze.sh links the source repo and discloses the privacy posture and how to verify what it downloads. - README documents provenance verification. Reputation/age and the inherent "trust an opaque binary" tradeoff can't be engineered away; this closes the parts that can be. --- .github/workflows/release.yml | 12 +++++++++++- README.md | 10 ++++++++++ scripts/analyze.sh | 16 ++++++++++++++++ 3 files changed, 37 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 036ad64..6bb6747 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -20,7 +20,8 @@ jobs: timeout-minutes: 30 permissions: contents: write # create/update the GitHub Release and upload artifacts - id-token: write # OIDC: assume the AWS release role for signing secrets + id-token: write # OIDC: assume the AWS release role for signing secrets + sign provenance + attestations: write # publish Sigstore build-provenance attestations for the artifacts steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: @@ -55,3 +56,12 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} GORELEASER_CURRENT_TAG: ${{ github.ref_name }} + + # Build provenance: a Sigstore-signed attestation binding every release + # archive (each file listed in checksums.txt) to this repo, commit, and + # workflow run, recorded in a public transparency log. Verify a download + # with: gh attestation verify --repo contextbridge/patchwave-analysis + - name: Attest build provenance + uses: actions/attest-build-provenance@a2bbfa25375fe432b6a289bc6b6cd05ecd0c4c32 # v4.1.0 + with: + subject-checksums: dist-release/checksums.txt diff --git a/README.md b/README.md index d752abc..bcd9ac1 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,16 @@ To turn it off, set any of these: - `DO_NOT_TRACK=1` - `CONTEXTBRIDGE_TELEMETRY_DISABLED=1` +## Verify what you're running + +The tool is open source (this repo, MIT) and its binaries are built from it by GitHub Actions. Every release archive ships with [GitHub build provenance](https://docs.github.com/actions/security-guides/using-artifact-attestations-to-establish-provenance-for-builds) — a Sigstore-signed attestation, recorded in a public transparency log, that ties the artifact to the source commit and workflow that built it. Verify a download with: + +```sh +gh attestation verify patchwave-analysis_darwin_arm64.tar.gz --repo contextbridge/patchwave-analysis +``` + +macOS binaries are also signed and Apple-notarized. + ## Contributing Development setup, testing, and the release workflow live in [`CONTRIBUTING.md`](./CONTRIBUTING.md). diff --git a/scripts/analyze.sh b/scripts/analyze.sh index fe55c42..043612d 100644 --- a/scripts/analyze.sh +++ b/scripts/analyze.sh @@ -2,6 +2,12 @@ # # analyze.sh — download and run patchwave-analysis as a one-off. # +# Source Code: +# https://github.com/contextbridge/patchwave-analysis +# This wrapper only fetches a release binary built from that repo by GitHub +# Actions; what the binary reads and sends is documented in the README's "What +# it reads from GitHub" and "Telemetry & privacy" sections. +# # Usage (interactive — it prompts you through everything, no flags needed): # bash -c "$(curl -fsSL https://patchwave.ai/analyze.sh)" # @@ -16,9 +22,19 @@ # on stdin instead of a terminal, so the CLI's TTY gate refuses to run and asks # you to re-run it interactively (it does not hang). # +# Privacy: the binary reads from api.github.com and writes its report to a local +# temp dir — nothing leaves your machine unless you choose to share the report. +# It sends anonymous usage and crash telemetry only (never org or repo names, +# tokens, report contents, or your hostname); disable it with DO_NOT_TRACK=1. +# # Auth is the CLI's job: it reads GITHUB_TOKEN, then GH_TOKEN, then `gh auth # token`. Export a token first, or be logged in via the gh CLI. # +# Verify the binary yourself: macOS release binaries are signed and Apple- +# notarized, and every release archive carries GitHub build provenance you can +# check with `gh attestation verify` — see the README's "Verify what you're +# running" section. +# # Env vars: # PW_VERSION pin to a release tag (e.g. v0.1.0) instead of the latest release