install.sh: verify release attestation via gh CLI#984
Merged
Conversation
Anchors the downloaded SHA256SUMS file to its GitHub Actions build-provenance attestation (already produced by release.yml via actions/attest-build-provenance) before reading checksums from it. This closes a gap where the SHA256SUMS file is trusted purely on the basis of its GitHub release URL — a release-page-write compromise could otherwise swap both the binary and its sums entry together. Behavior: - If gh CLI is available and authenticated, the attestation is verified with --owner tw93 --deny-self-hosted-runners. A mismatch is fatal and the install aborts. - If gh is unavailable or unauthenticated, the installer falls back to the existing sha256-only verification (no behavior change for current users). - MOLE_REQUIRE_ATTESTATION=1 turns the soft check into a hard requirement: missing gh becomes an install failure. Verifying SHA256SUMS is sufficient because the binary's sha256 is then anchored to that attested file by verify_release_asset_checksum in the line below.
Owner
|
@AilfredBitworth Thanks for this. Decisions on your three open questions:
Marking ready and merging. |
Contributor
Author
|
Awesome! Glad I could help. I look forward to using this MCP. |
tw93
added a commit
that referenced
this pull request
May 29, 2026
…endent The release attestation gate added this cycle (PR #984) had zero coverage, so add tests for verify_release_attestation's 2/0/1 return codes (via a PATH gh stub, since the exec'd binary bypasses function mocks) and for the policy gate in verify_release_asset_checksum. The same gate also broke the two happy-path checksum tests on any host with an authenticated gh: they run `gh attestation verify` against synthetic fixtures and fail. Stub verify_release_attestation to the gh-unavailable return so those tests exercise the checksum-only path regardless of host gh state. CI without gh masked this.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Adds optional GitHub Actions build-provenance attestation verification to
install.sh. Anchors the downloadedSHA256SUMSfile to the attestation already produced byrelease.yml(viaactions/attest-build-provenance@v4) before reading checksums from it.Motivation
Today the installer trusts
SHA256SUMSpurely because it was fetched from the release URL. A compromise that gains GitHub release-asset write access can swap the binary and the sums entry together, and the current sha256 gate accepts it. The release workflow already mints Sigstore attestations coveringSHA256SUMSand the binaries, butinstall.shdoesn't consume them. This wires that signal in.Verifying
SHA256SUMSis sufficient: the per-binary sha256 is then anchored to that attested file by the existingverify_release_asset_checksumflow.Behavior
ghCLI available + authenticated → attestation is verified with--owner tw93 --deny-self-hosted-runners. Mismatch is fatal; install aborts.ghunavailable or unauthenticated → falls back to existing sha256-only verification. No behavior change for current users.MOLE_REQUIRE_ATTESTATION=1→ turns the soft check into a hard requirement. Missingghbecomes an install failure. For users who want fail-closed semantics.Why a soft default
Most macOS users won't have
ghinstalled, and breaking the install path for them would be a worse trade than the current state. The opt-in env var lets security-conscious users (and CI environments) lock it down without forcing a new dependency on everyone.Test plan
bash -n install.sh— cleanghinstalled and authenticated → see "Verified (sha256 + attestation)" success linegh→ falls back to existing behavior (silent), install succeedsMOLE_REQUIRE_ATTESTATION=1andghuninstalled → install fails fast with clear errorNotes
Drafting because I'd like a maintainer's read on:
--owner tw93is the right scoping (vs.--repo tw93/Mole, which is stricter but breaks if you ever fork-and-rename).MOLE_SKIP_ATTESTATION=1).--verbose.Found while doing an external security audit of Mole. Audit verdict was already ACCEPTABLE / risk LOW — the project is unusually well-hardened for its category. This is one of two minor defense-in-depth items.