Skip to content

test bundles: DSSE-with-hashedrekord on Rekor v2#371

Merged
loosebazooka merged 3 commits into
sigstore:mainfrom
codysoyland:dsse-hashedrekord-test-bundles
May 27, 2026
Merged

test bundles: DSSE-with-hashedrekord on Rekor v2#371
loosebazooka merged 3 commits into
sigstore:mainfrom
codysoyland:dsse-hashedrekord-test-bundles

Conversation

@codysoyland

@codysoyland codysoyland commented May 13, 2026

Copy link
Copy Markdown
Member

Summary

Regenerates the four rekor2-dsse-* fixtures so the suite has end-to-end test coverage for the DSSE-with-hashedrekord client behaviour described in sigstore/architecture-docs#63.

For DSSE envelopes the tlog entry is now a hashedrekord whose data digest is Hash(PAE(payloadType, payload)) — the same bytes the DSSE signature covers — rather than a dsse/intoto entry over the whole envelope. The architecture-docs spec change scopes this proposal to Rekor v2 only, so these bundles are signed against staging Sigstore (staging Fulcio + staging Rekor v2) and their tlog entries are kind=hashedrekord/0.0.2, replacing the prior dsse/0.0.2 entries. Each dir still ships its staging trusted_root.json; once production has a Rekor v2 instance the custom trust root can be removed.

The four scenarios:

Dir Outcome
rekor2-dsse-happy-path valid; must verify
rekor2-dsse-mismatch-sig_fail same cert, same PAE, but envelope.sig != tlog.sig (a second valid signature of the same PAE was swapped in) — exercises §4.4.1 #2 (signature-equality)
rekor2-dsse-mismatch-envelope_fail same cert, envelope swapped for one covering a different payload, so Hash(PAE(envelope)) != tlog.digest — exercises §4.4.1 #1 (digest-equality)
rekor2-dsse-invalid-sig_fail envelope.sig was made by an unrelated key and does not verify under the bundle's certificate

In every _fail dir the RFC3161 TSA timestamp's messageImprint is over the swapped-in envelope signature (not the original tlog signature), so the timestamp check passes and the bundle fails only for the labelled reason.

All bundles use the sigstore-conformance/extremely-dangerous-public-oidc-beacon workflow identity (the suite's default in test/client.py), so no per-dir identity/issuer overrides are needed.

Related: sigstore/architecture-docs#63

@Hayden-IO Hayden-IO requested a review from loosebazooka May 13, 2026 22:00
@loosebazooka

Copy link
Copy Markdown
Member

Might be worth splitting into v1 and v2 changes. At least we can get the v2 changes in?

@loosebazooka

Copy link
Copy Markdown
Member

I'll test the v2 changes against the sigstore-java impl for now though.

@Hayden-IO

Copy link
Copy Markdown
Collaborator

I thought in the sigstore-go meeting we had discussed doing this only for Rekor v2?

+1 to splitting these. I don't think we should pursue this change in Rekor v1 if it's a breaking change to verification. We will have to test this and conformance is the easiest way to do so. But I assume it will be a breaking change because clients won't know to construct the PAE as the artifact, either when comparing it to the hash digest in the canonicalized body or if the client reconstructed the leaf hash themselves.

I want to avoid having a divergent signing path with a flag to control how signing is done for v1, that's just more technical debt we have to keep track of.

@loosebazooka

Copy link
Copy Markdown
Member

the v2 tests are working as expected in sigstore-java (on my branch).

I think we need to get this into sigstore-python first maybe? (or xfail on the self test... we've done this before as long as there was confirmation that they work)? @jku

@loosebazooka

Copy link
Copy Markdown
Member

also cosign-nightly is gonna be mad if it can't handle these new tests.

@loosebazooka

Copy link
Copy Markdown
Member

otherwise lgtm

@codysoyland codysoyland changed the title test bundles: DSSE-with-hashedrekord on Rekor v1 and v2 test bundles: DSSE-with-hashedrekord on Rekor v2 May 14, 2026
@Hayden-IO

Copy link
Copy Markdown
Collaborator

Can we create a PR to xfail these tests with Cosign before this lands?

@codysoyland

Copy link
Copy Markdown
Member Author

I have a PR for sigstore-python here: sigstore/sigstore-python#1776

@jku

jku commented May 25, 2026

Copy link
Copy Markdown
Member

I'll have a look at sigstore-python today but I have not problem with xfails being added for the selftest client (as long as someone has tested the cases with another compliant client).

@jku

jku commented May 25, 2026

Copy link
Copy Markdown
Member

I can make a release of the current state of conformance if that makes it easier for clients. We can make another one when this merges

jku pushed a commit to sigstore/sigstore-python that referenced this pull request May 26, 2026
* verify, rekor: encode DSSE as hashedrekord for Rekor v2

Implements rekor-v2-spec §6.1.4: DSSE envelope entries are submitted
and verified as hashedrekord/0.0.2 with digest = Hash(PAE(payloadType,
payload)) and signature.content = envelope.signatures[0].sig.

This is vibecoded — a maintainer should take a closer look at
correctness, especially the hash-algorithm dispatch in
_hash_for_key_details and the entry-body reconstruction in
_validate_hashedrekord_v002_dsse_entry_body. Passes the draft
conformance tests in sigstore/sigstore-conformance#371.

Related spec change: sigstore/architecture-docs#63

Signed-off-by: Cody Soyland <cody.soyland@chainguard.dev>

* verify: fix lint (import order, format, quoted annotation)

Signed-off-by: Cody Soyland <cody.soyland@chainguard.dev>

* Add Envelope.pae() helper

Replace cross-module `_pae` imports in the Rekor v2 producer and DSSE
hashedrekord verifier with a public `Envelope.pae()` method. Addresses
review feedback on #1776: drops the cross-module use of a private symbol
and lets the hashedrekord-for-DSSE docstring read as `Hash(envelope.pae())`.

No behavior change.

Signed-off-by: Cody Soyland <cody.soyland@chainguard.dev>

* Drop dsse/0.0.2 verifier path; replace staging test fixture

Rekor v2 will not support the dsse entry type — DSSE envelopes are
encoded as hashedrekord/0.0.2 (rekor-v2-spec §6.1.4). Remove the
now-orphaned dsse/0.0.2 dispatch branch and `_validate_dsse_v002_entry_body`
function. The dsse/0.0.1 path stays for Rekor v1 legacy bundles.

Replaces `test/assets/a.dsse.staging-rekor-v2.txt.sigstore.json` with the
`rekor2-dsse-happy-path` fixture from the sigstore-conformance
`dsse-hashedrekord-test-bundles` branch, so the staging DSSE verification
test now exercises hashedrekord/0.0.2 end-to-end.

Addresses review feedback on #1776.

Signed-off-by: Cody Soyland <cody.soyland@chainguard.dev>

* key_details: centralize algorithm registry; use for DSSE prehash

Replace the inline hash-for-key-details mappings in verifier.py and the
hardcoded SHA-256 in client_v2.py with a single algorithm registry table
in key_details.py, matching the spec at architecture-docs/algorithm-registry.md.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Cody Soyland <cody.soyland@chainguard.dev>

* key_details: fix HashAlgorithm for pure Ed25519

HASH_ALGORITHM_UNSPECIFIED doesn't exist in sigstore_models; use None
instead, since _get_prehash already rejects algorithms with no prehash.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Cody Soyland <cody.soyland@chainguard.dev>

* key_details: narrow None check so mypy sees non-None hash_algorithm

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Cody Soyland <cody.soyland@chainguard.dev>

* conformance: bump sigstore-conformance to v0.0.28

Signed-off-by: Cody Soyland <cody.soyland@chainguard.dev>

---------

Signed-off-by: Cody Soyland <cody.soyland@chainguard.dev>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…d-DSSE bundles

The four rekor2-dsse-* fixtures were re-signed against staging Sigstore
so their tlog entries use kind=hashedrekord/0.0.2 with
Hash(PAE(payloadType, payload)) as the recorded digest, instead of the
previous dsse/0.0.2 entries that committed to the whole envelope. This
matches the encoding described in the architecture-docs PR
sigstore/architecture-docs#63 and exercised by
the corresponding sigstore-go signing/verification changes.

Adds four new dsse-with-hashedrekord-* fixtures covering the same matrix
on Rekor v1 (kind=hashedrekord/0.0.1, signed against production Sigstore
Public Good with sigstore-go's experimental hashedrekord-over-DSSE flag
enabled), replacing the two pre-existing dsse-with-hashedrekord/ and
dsse-with-hashedrekord_fail/ dirs.

The four scenarios per family are:

  *-happy-path                : valid bundle, must verify
  *-mismatch-sig_fail         : same cert, same PAE, but envelope.sig
                                != tlog.sig (a second valid signature
                                of the same PAE was swapped in)
  *-mismatch-envelope_fail    : same cert, envelope swapped for one
                                covering a different payload so
                                Hash(PAE(envelope)) != tlog.digest
  *-invalid-sig_fail          : envelope.sig was made by an unrelated
                                key and does not verify under the
                                bundle's certificate

All bundles use the sigstore-conformance/extremely-dangerous-public-oidc-beacon
workflow identity (the suite's default in test/client.py). The rekor v2
bundles ship a custom trusted_root.json (the staging trust root); the
rekor v1 bundles use the default production trust root.

Signed-off-by: Cody Soyland <cody.soyland@chainguard.dev>
The architecture-docs spec change scopes the dsse-hashedrekord proposal
to Rekor v2 only and drops the Rekor v1 bridge feature paragraph. These
fixtures covered the v1 bridge encoding (kind=hashedrekord/0.0.1 whose
data.hash = SHA256(PAE(payloadType, payload))) and no longer correspond
to a supported wire format. The rekor2-dsse-* fixtures (v2 path) remain.

Signed-off-by: Cody Soyland <cody.soyland@chainguard.dev>
@codysoyland codysoyland force-pushed the dsse-hashedrekord-test-bundles branch from 9badc81 to a486574 Compare May 26, 2026 15:36
@jku

jku commented May 26, 2026

Copy link
Copy Markdown
Member

we can upgrade the selftest client even without a sigstore-python releases:
sigstore @ git+https://github.com/sigstore/sigstore-python.git@603eeb3d4f6064917926fdaacc832790cbc9a609 in selftest-requirements.txt should work

(I see we've forgotten to update version in there the last time something like this happened, oops)

Signed-off-by: Cody Soyland <cody.soyland@chainguard.dev>

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Cody Soyland <cody.soyland@chainguard.dev>
@jku

jku commented May 27, 2026

Copy link
Copy Markdown
Member

Is this ready to go? I think we could merge this so clients could easily test against main branch -- we could still hold off releasing new conformance until the main clients have their implementations ready.

@codysoyland codysoyland marked this pull request as ready for review May 27, 2026 14:30
@codysoyland

Copy link
Copy Markdown
Member Author

Is this ready to go? I think we could merge this so clients could easily test against main branch -- we could still hold off releasing new conformance until the main clients have their implementations ready.

Yeah, it should be good to go now. I just ran it against my local branch of sigstore-go again and it passes.

@loosebazooka loosebazooka merged commit 21533cd into sigstore:main May 27, 2026
5 checks passed

@jku jku left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm, thanks for all your work on this

@codysoyland codysoyland deleted the dsse-hashedrekord-test-bundles branch May 28, 2026 13:31
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.

4 participants