Skip to content

Commit e86bf5e

Browse files
cynarlabclaude
andcommitted
fix(release): replace SLSA reusable-workflow provenance with actions/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>
1 parent 74c73b5 commit e86bf5e

1 file changed

Lines changed: 48 additions & 19 deletions

File tree

‎.github/workflows/release.yml‎

Lines changed: 48 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -378,21 +378,51 @@ jobs:
378378
if-no-files-found: error
379379

380380
provenance:
381-
name: Generate SLSA provenance
381+
name: Generate build provenance attestation
382382
needs: npm-publish
383+
runs-on: ubuntu-latest
383384
permissions:
384-
actions: read # read the release-artifacts workflow artifact
385-
id-token: write # sign the provenance (sigstore)
385+
id-token: write # sign the attestation (sigstore)
386+
attestations: write # persist it to the GitHub Attestations API
386387
contents: read
387-
# SLSA reusable workflows must be referenced by version tag, not commit SHA:
388-
# slsa-verifier resolves the trusted builder identity from the tag, and the
389-
# generator refuses to run from a mutable/unknown ref. Scorecard's
390-
# Pinned-Dependencies check exempts slsa-framework/slsa-github-generator.
391-
uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@v2.1.0
392-
with:
393-
base64-subjects: ${{ needs.npm-publish.outputs.hashes }}
394-
provenance-name: multiple.intoto.jsonl
395-
upload-assets: false # create-release attaches it together with the tarballs
388+
# Uses actions/attest-build-provenance (a plain composite action) rather than
389+
# slsa-framework/slsa-github-generator's reusable workflow: this org has
390+
# "Write permissions for workflows" disabled, and GitHub validates a calling
391+
# job's permissions against that policy at PARSE TIME for external reusable
392+
# *workflow* calls specifically -- even read-only-looking permission sets on
393+
# such a job made the whole run fail with startup_failure before any job
394+
# (even unrelated ones) could start. A normal action inside a normal job
395+
# (like npm-publish's existing id-token: write) isn't subject to that check.
396+
steps:
397+
- name: Download release artifacts
398+
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
399+
with:
400+
name: release-artifacts
401+
path: release-artifacts
402+
403+
- name: Generate attestation
404+
id: attest
405+
uses: actions/attest-build-provenance@0f67c3f4856b2e3261c31976d6725780e5e4c373 # v4.1.1
406+
with:
407+
subject-path: release-artifacts/*.tgz
408+
409+
# The bundle is a JSON-serialized Sigstore bundle wrapping an in-toto
410+
# statement -- genuinely valid under both extensions Scorecard's
411+
# Signed-Releases probes scan release assets for (releasesAreSigned:
412+
# .sigstore.json; releasesHaveProvenance: .intoto.jsonl).
413+
- name: Name provenance files for release assets
414+
run: |
415+
cp "${{ steps.attest.outputs.bundle-path }}" multiple.intoto.jsonl
416+
cp "${{ steps.attest.outputs.bundle-path }}" multiple.sigstore.json
417+
418+
- name: Upload provenance files
419+
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
420+
with:
421+
name: provenance
422+
path: |
423+
multiple.intoto.jsonl
424+
multiple.sigstore.json
425+
if-no-files-found: error
396426

397427
create-release:
398428
name: Create GitHub Release
@@ -421,10 +451,10 @@ jobs:
421451
name: release-artifacts
422452
path: release-artifacts
423453

424-
- name: Download SLSA provenance
454+
- name: Download provenance attestation
425455
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
426456
with:
427-
name: multiple.intoto.jsonl
457+
name: provenance
428458
path: provenance
429459

430460
- name: Generate changelog
@@ -491,13 +521,12 @@ jobs:
491521
fi
492522
493523
# Create the release using GitHub CLI, attaching the npm tarballs and
494-
# their SLSA provenance (verify with:
495-
# slsa-verifier verify-artifact <tarball> \
496-
# --provenance-path multiple.intoto.jsonl \
497-
# --source-uri github.com/debugmcp/mcp-debugger)
524+
# their build provenance attestation (verify with:
525+
# gh attestation verify <tarball> --repo debugmcp/mcp-debugger)
498526
gh release create "${{ github.ref_name }}" \
499527
--title "Release ${{ steps.changelog.outputs.VERSION }}" \
500528
--notes-file release_notes.md \
501529
$PRERELEASE_FLAG \
502530
release-artifacts/*.tgz \
503-
provenance/multiple.intoto.jsonl
531+
provenance/multiple.intoto.jsonl \
532+
provenance/multiple.sigstore.json

0 commit comments

Comments
 (0)