Skip to content

Restore the SBOM predicate when re-attesting a release - #32

Merged
DeliriumPulse merged 1 commit into
mainfrom
restore/release-sbom-attestations
Aug 7, 2026
Merged

Restore the SBOM predicate when re-attesting a release#32
DeliriumPulse merged 1 commit into
mainfrom
restore/release-sbom-attestations

Conversation

@DeliriumPulse

Copy link
Copy Markdown
Collaborator

The org transfer orphaned every attestation on v0.2.36 through v0.2.39. Each of
those digests originally carried three predicates: SLSA build provenance, a
CycloneDX SBOM, and GitHub's own in-toto release/v0.2 statement. The recovery
workflow restored one, so today each digest carries exactly one attestation
while evidence/attestation-v0.2.38.txt in the data room still describes three.

This adds the SBOM predicate to attest-release.yml, mirroring the step
release.yml runs for a normal release, and extends the reproduction gate to
cover it: the rebuilt SBOM must match the SBOM the release published, or the job
attests nothing. It also skips any predicate the digest already carries, so
re-dispatch does not leave duplicate provenance behind.

What this deliberately does not do

No synthesized in-toto release/v0.2 predicate. That statement is issued by
GitHub at publication time and signed by https://dotcom.releases.github.com
(O=GitHub, Inc., CN=Attester), not by any workflow identity. These releases are
already published and immutable, so the platform will not reissue it. Emitting a
lookalike from Actions would be a different claim wearing the same predicate type.

No fix for the signer identity. The surviving provenance on these four names
attest-release.yml@refs/heads/main, because that is what built it. Verification
that pins --signer-workflow .../release.yml --source-ref refs/tags/vX fails for
them and will keep failing. That is the honest result, and it is being documented
in the data room rather than disguised.

Practical consequence

publish-npm.yml runs the strict form in its verify job, so an npm publish of
v0.2.36 through v0.2.39 would fail there. Nothing is blocked today: npm serves
0.2.41, attested natively, and only the newest version is ever published.

Verified before this change

version attestations predicates plain verify strict verify
v0.2.36 - v0.2.39 1 provenance exit 0 exit 1
v0.2.40, v0.2.41 3 provenance, cyclonedx, in-toto release exit 0 exit 0

The org transfer orphaned every attestation on v0.2.36 through v0.2.39. Each
of those digests originally carried three predicates: SLSA build provenance,
a CycloneDX SBOM, and GitHub's own in-toto release/v0.2 statement. This
workflow restored one, so the four releases now carry provenance and nothing
else, while the data room still describes all three.

Adds the SBOM predicate, mirroring the step release.yml runs for a normal
release, and extends the reproduction gate to cover it: the rebuilt SBOM must
match the SBOM the release published, or the job attests nothing. The SBOM is
deterministic (uuid v5 serial, no build timestamp), so a rebuild of the tagged
source reproduces it byte for byte.

Also skips any predicate the digest already carries. Re-signing a claim that
is already on record adds noise, not evidence, and it would have left these
four with a duplicate provenance.

Two things this deliberately does not do.

It does not emit an in-toto release/v0.2 predicate. That statement is issued
by GitHub at publication time and signed by https://dotcom.releases.github.com,
not by a workflow identity, and these releases are already published and
immutable. A lookalike signed by Actions would be a different claim wearing
the same predicate type.

It does not and cannot make these four pass verification that pins
--signer-workflow to release.yml at the tag. The provenance names
attest-release.yml@refs/heads/main, because that is what built it. The
difference is permanent and documented rather than papered over.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@DeliriumPulse
DeliriumPulse merged commit cf022d7 into main Aug 7, 2026
9 checks passed
@DeliriumPulse
DeliriumPulse deleted the restore/release-sbom-attestations branch August 7, 2026 17:28
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.

1 participant