Skip to content

fix(release): replace SLSA reusable-workflow provenance with actions/attest-build-provenance#176

Merged
debugmcpdev merged 1 commit into
mainfrom
fix/release-provenance-attest
Jul 9, 2026
Merged

fix(release): replace SLSA reusable-workflow provenance with actions/attest-build-provenance#176
debugmcpdev merged 1 commit into
mainfrom
fix/release-provenance-attest

Conversation

@debugmcpdev

Copy link
Copy Markdown
Collaborator

Summary

The provenance job added in #164 (slsa-framework/slsa-github-generator's reusable workflow) broke the v0.23.0 release: pushing the tag produced a hard startup_failure with zero jobs scheduled — not even unrelated ones like build-and-test.

Root cause

This org has "Write permissions for workflows" disabled (actions/permissions/workflow reports default_workflow_permissions: read; a PUT to write returns 409 "disabled by the organization"). GitHub validates a job's requested permissions against that policy at parse time, specifically for jobs that call an external reusable workflow (uses: owner/repo/.github/workflows/x.yml@ref) — even a bare-minimum such job with modest permissions triggered the same whole-run startup_failure. A normal composite action inside a normal job isn't subject to that check — proven by npm-publish's existing id-token: write step, which has worked in every prior release.

Diagnosed on a throwaway branch (deleted, never merged) by elimination: removing the job let build-and-test run; a bare-minimum reusable-workflow-call reproduced the failure in isolation; swapping to a composite action ran clean.

Fix

Replace the SLSA reusable-workflow call with actions/attest-build-provenance (a plain composite action, GitHub's own native build-provenance attestation — v4 is officially a thin wrapper on actions/attest). Same permission shape as npm-publish (id-token: write, now attestations: write instead of contents: write).

Its bundle-path output is a JSON-serialized Sigstore bundle wrapping a real in-toto statement — genuinely valid under both extensions OpenSSF Scorecard's Signed-Releases probes scan release assets for (confirmed by reading the actual probe source): releasesAreSigned wants .sigstore.json/.sig/.asc/etc.; releasesHaveProvenance wants .intoto.jsonl. Uploaded as both — same file content, not fabricated duplicates.

Verification

  • actionlint clean.
  • Dispatched the full redesigned workflow via workflow_dispatch with a deliberately-invalid ref input (so even if jobs ran, nothing could actually publish): all six jobs correctly scheduled this time (no startup_failure) — build-and-test failed on the poisoned ref as expected, and every downstream job (including the new provenance job) shows skipped, exactly matching needs: semantics with zero side effects to npm/PyPI/Docker Hub.
  • Isolated the provenance job alone in an earlier diagnostic run: it completed success, generating a real attestation.

🤖 Generated with Claude Code

…attest-build-provenance

The provenance job added in #164 (slsa-framework/slsa-github-generator's
generator_generic_slsa3.yml reusable workflow) failed the v0.23.0 release
with a hard startup_failure -- zero jobs scheduled, not even unrelated
ones like build-and-test.

Root-caused via a throwaway diagnostic branch (deleted): this org has
'Write permissions for workflows' disabled repo-wide
(actions/permissions/workflow reports default_workflow_permissions:
read, and PUT to write returns 409 'disabled by the organization').
GitHub validates a job's requested permissions against that policy at
PARSE TIME specifically for jobs that call an external reusable
*workflow* (uses: owner/repo/.github/workflows/x.yml@ref) -- even a
bare-minimum such job with read-only-looking permissions triggered the
same startup_failure. Confirmed by elimination: removing the job let
build-and-test run; a bare bones version of the same reusable-workflow
call reproduced the failure in isolation; a normal composite action
inside a normal job (matching npm-publish's already-working
id-token: write pattern) ran successfully.

Fix: actions/attest-build-provenance is a plain composite action, not a
reusable workflow, so it isn't subject to that check -- same permission
scopes (id-token: write, now attestations: write instead of contents),
same normal-job shape npm-publish already uses successfully. Its
bundle-path output is a JSON-serialized Sigstore bundle wrapping a real
in-toto statement, genuinely valid under both extensions OpenSSF
Scorecard's Signed-Releases probes scan release assets for
(releasesAreSigned: .sigstore.json; releasesHaveProvenance:
.intoto.jsonl) -- uploaded as both, not fabricated duplicates.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@codecov

codecov Bot commented Jul 9, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@debugmcpdev debugmcpdev merged commit 092377d into main Jul 9, 2026
14 of 15 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants