Summary
gale's dependency attestation check shells out to gh attestation verify <archive> --repo <repo> (internal/attestation/attestation.go:154).
The --repo flag makes gh fetch the attestation bundle from the
GitHub API, which requires authentication (GH_TOKEN) even for
public repos. When no token is present, the verify fails and gale
falls back to building the dependency from source.
In CI this is expensive and fragile: a Rust dependency (rust) falls
back to a full rustc source build, whose vendored tree fills the
runner disk and the job dies with no space left on device.
Observed in gale-recipes CI
Build of difftastic (a Rust recipe), build-chunk.yml:
warning: binary install for rust@1.96.0 failed: attestation:
attestation verification failed: gh: To use GitHub CLI in a GitHub
Actions workflow, set the GH_TOKEN environment variable.
Error: installing build deps: install dep "rust": build from source:
... extract rustc-1.96.0-src/.../bad-2-index-4.xz:
no space left on device
Same signature has hit btop, difftastic, hyperfine, just across
the republish batches — every time a Rust dep cache-misses and the
attestation can't be verified.
Root cause
The token is needed only to fetch the attestation from the GitHub
API, not for the Sigstore cryptographic verification itself (that is
offline-capable). This is a recognized gh CLI limitation:
Proposed fix
gale already pushes each artifact's attestation to GHCR as an OCI
referrer, and gh attestation verify can read it from the registry
instead of the API — anonymously for public packages, no token:
--bundle-from-oci — "When verifying an OCI image, fetch the
attestation bundle from the OCI registry instead of from GitHub."
--bundle <path> — verify against a bundle on disk.
Switch the dep-attestation call from the --repo (GitHub-API) path to
the OCI/bundle path. gale already has a VerifyOCI alongside the
VerifyFile/--repo path it currently uses for deps.
Payoff:
- No token required anywhere. Fixes both the privileged
build-chunk.yml
and the deliberately contents: read-only verify.yml (which must
not be granted packages:).
- Preserves the full supply-chain guarantee — still verifies the
Sigstore attestation, just fetches it from GHCR rather than the API.
- Eliminates the source-build fallback, so the disk never fills.
Implementation note
--bundle-from-oci is documented against an OCI image subject
(oci://…), whereas the current code verifies the extracted local
archive via VerifyFile. So the fix is either: verify the GHCR ref
directly (existing VerifyOCI), or fetch the bundle from GHCR and pass
--bundle for the local file. That choice decides which flag applies.
References
Related
Summary
gale's dependency attestation check shells out to
gh attestation verify <archive> --repo <repo>(internal/attestation/attestation.go:154).The
--repoflag makesghfetch the attestation bundle from theGitHub API, which requires authentication (
GH_TOKEN) even forpublic repos. When no token is present, the verify fails and gale
falls back to building the dependency from source.
In CI this is expensive and fragile: a Rust dependency (
rust) fallsback to a full
rustcsource build, whose vendored tree fills therunner disk and the job dies with
no space left on device.Observed in gale-recipes CI
Build of
difftastic(a Rust recipe),build-chunk.yml:Same signature has hit
btop,difftastic,hyperfine,justacrossthe republish batches — every time a Rust dep cache-misses and the
attestation can't be verified.
Root cause
The token is needed only to fetch the attestation from the GitHub
API, not for the Sigstore cryptographic verification itself (that is
offline-capable). This is a recognized
ghCLI limitation:gh attestation verifyshould be able to work without token / authentication cli/cli#11803 —gh attestation verifyshould work without token / authgh attestation downloadProposed fix
gale already pushes each artifact's attestation to GHCR as an OCI
referrer, and
gh attestation verifycan read it from the registryinstead of the API — anonymously for public packages, no token:
--bundle-from-oci— "When verifying an OCI image, fetch theattestation bundle from the OCI registry instead of from GitHub."
--bundle <path>— verify against a bundle on disk.Switch the dep-attestation call from the
--repo(GitHub-API) path tothe OCI/bundle path. gale already has a
VerifyOCIalongside theVerifyFile/--repopath it currently uses for deps.Payoff:
build-chunk.ymland the deliberately
contents: read-onlyverify.yml(which mustnot be granted
packages:).Sigstore attestation, just fetches it from GHCR rather than the API.
Implementation note
--bundle-from-ociis documented against an OCI image subject(
oci://…), whereas the current code verifies the extracted localarchive via
VerifyFile. So the fix is either: verify the GHCR refdirectly (existing
VerifyOCI), or fetch the bundle from GHCR and pass--bundlefor the local file. That choice decides which flag applies.References
gh attestation verifymanual: https://cli.github.com/manual/gh_attestation_verifygh attestation verifyshould be able to work without token / authentication cli/cli#11803, Feature Request: gh attestation download: Remove authentication requirement to increase adoption cli/cli#12030Related