Follow-up from review of #421 (comment).
Background
#421 makes attestation verification credential-free by publishing the Sigstore bundle
as an attestations.jsonl release asset and verifying it with gh attestation verify --bundle. That only helps releases that carry the asset. Releases published before it
existed — including v0.5.4, which is latest today — still verify through the
GitHub attestations API, where gh always attaches its stored token, so the request
403s under trailofbits SAML enforcement (or exits 4 with no credential at all).
So the reported symptom persists for every user until the next release ships, and
permanently for VERSION=v0.5.x pinned installs.
Observation
The attestations API is readable anonymously. Only gh attaching a token turns public
data into a 403. Fetching the bundle directly and feeding it to --bundle therefore
verifies old releases with no credential. Verified against v0.5.4 with zero
credentials:
curl -fsS ".../repos/trailofbits/coop/attestations/sha256:$D" \
| jq -c '.attestations[].bundle' > b.jsonl
gh attestation verify coop.tar.gz --repo trailofbits/coop --bundle b.jsonl # exit 0
Scope
src/update.rs — serde_json and the HTTP capture helper already exist, so the
fallback in fetch_attestation_bundle could build the bundle itself instead of
handing the API call to gh. That removes the credential-requiring path entirely.
install.sh — costs a jq dependency, so it wants gating on has jq with the
current API path kept as the last resort.
Notes: the unauthenticated API is rate-limited to 60 req/hr/IP, which is fine for a
fallback. Verification strength is unchanged either way — the bundle is signed and
--repo still pins the signer identity, so a substituted bundle fails.
Related: #422 (Option A there is the larger in-process-verification direction; this is
the cheap subset that only changes bundle transport).
Follow-up from review of #421 (comment).
Background
#421 makes attestation verification credential-free by publishing the Sigstore bundle
as an
attestations.jsonlrelease asset and verifying it withgh attestation verify --bundle. That only helps releases that carry the asset. Releases published before itexisted — including
v0.5.4, which islatesttoday — still verify through theGitHub attestations API, where
ghalways attaches its stored token, so the request403s under
trailofbitsSAML enforcement (or exits 4 with no credential at all).So the reported symptom persists for every user until the next release ships, and
permanently for
VERSION=v0.5.xpinned installs.Observation
The attestations API is readable anonymously. Only
ghattaching a token turns publicdata into a 403. Fetching the bundle directly and feeding it to
--bundlethereforeverifies old releases with no credential. Verified against
v0.5.4with zerocredentials:
Scope
src/update.rs—serde_jsonand the HTTP capture helper already exist, so thefallback in
fetch_attestation_bundlecould build the bundle itself instead ofhanding the API call to
gh. That removes the credential-requiring path entirely.install.sh— costs ajqdependency, so it wants gating onhas jqwith thecurrent API path kept as the last resort.
Notes: the unauthenticated API is rate-limited to 60 req/hr/IP, which is fine for a
fallback. Verification strength is unchanged either way — the bundle is signed and
--repostill pins the signer identity, so a substituted bundle fails.Related: #422 (Option A there is the larger in-process-verification direction; this is
the cheap subset that only changes bundle transport).