Skip to content

rekor v2: remove dsse entry type; define DSSE envelope handling via hashedrekord#63

Merged
Hayden-IO merged 6 commits into
sigstore:mainfrom
codysoyland:rekor-v2-dsse-as-hashedrekord
May 19, 2026
Merged

rekor v2: remove dsse entry type; define DSSE envelope handling via hashedrekord#63
Hayden-IO merged 6 commits into
sigstore:mainfrom
codysoyland:rekor-v2-dsse-as-hashedrekord

Conversation

@codysoyland

@codysoyland codysoyland commented May 8, 2026

Copy link
Copy Markdown
Member

This PR removes dsse entry type support from the Rekor v2 spec requirements. DSSE-envelope bundles MUST be uploaded as a HashedRekord whose digest is Hash(PAE(payloadType, payload)) and whose signature equals the DSSE envelope's signature.

The canonical description lives in a new rekor-v2-spec §6.1.4 DSSE Envelopes; references from client-spec, rekor-spec, and the algorithm registry redirect there.

Also fixes pre-existing duplicate section numbering in rekor-v2-spec.md.

@codysoyland codysoyland force-pushed the rekor-v2-dsse-as-hashedrekord branch from b83e236 to ca5f635 Compare May 8, 2026 21:58

@loosebazooka loosebazooka 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.

I think this looks good, maybe we don't explicitly call our rekorv1 yet?

@Hayden-IO @kommendorkapten might have some thoughts here.

Comment thread rekor-spec.md Outdated
Comment thread rekor-v2-spec.md Outdated
…ashedrekord

Remove dsse entry type support from the Rekor v2 spec requirements.
DSSE-envelope bundles MUST be uploaded as a HashedRekord whose digest
is Hash(PAE(payloadType, payload)) and whose signature equals the DSSE
envelope's signature.

The canonical description lives in a new rekor-v2-spec §6.1.4 DSSE
Envelopes; references from client-spec, rekor-spec, and the algorithm
registry redirect there.

Also fixes pre-existing duplicate section numbering in rekor-v2-spec.md.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Cody Soyland <cody.soyland@chainguard.dev>
@codysoyland codysoyland force-pushed the rekor-v2-dsse-as-hashedrekord branch from ca5f635 to bac99ad Compare May 13, 2026 18:38
Signed-off-by: Cody Soyland <cody.soyland@chainguard.dev>

@Hayden-IO Hayden-IO left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Overall LGTM, thanks for making these updates

Comment thread client-spec.md Outdated
Comment thread rekor-spec.md Outdated
Comment thread algorithm-registry.md Outdated
Comment thread rekor-v2-spec.md Outdated
- Drop intoto from client-spec verifier-support sentence.
- Remove Rekor v1 bridge-feature paragraph; scope to v2 only.
- Move externalized-prehash constraint from algorithm-registry to
  rekor-v2-spec §6.1.4.
- Add verifier-identity check to §6.1.4 verifier requirements.

Signed-off-by: Cody Soyland <cody.soyland@chainguard.dev>
@codysoyland codysoyland force-pushed the rekor-v2-dsse-as-hashedrekord branch from 23b5f54 to 76ad603 Compare May 14, 2026 16:07
codysoyland added a commit to codysoyland/sigstore-go that referenced this pull request May 14, 2026
Implements the encoding proposed in sigstore/architecture-docs#63
(rekor-v2-spec §6.1.4): on Rekor v2, DSSE envelopes are uploaded as a
hashedrekord whose digest covers Hash(PAE(payloadType, payload)), with
the hash derived from the signing algorithm. Rekor v1 behavior is
unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Cody Soyland <cody.soyland@chainguard.dev>
Comment thread rekor-v2-spec.md Outdated
…t spec

§6.1.4 becomes a content-agnostic "Verifier Requirements" section covering
both leaf-recomputation and canonicalized-body verification. The DSSE PAE
digest construction moves to client-spec §4.4 since it is a client concern.

Addresses Hayden-IO review feedback on PR #63.

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

@Hayden-IO Hayden-IO left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Looks good, just two small comments! Thanks!

Comment thread rekor-v2-spec.md Outdated
Comment thread rekor-v2-spec.md Outdated
- Clarify that the leaf hash is the input used to verify the
  inclusion proof, not something the proof itself references.
- Rekor records only the leaf certificate, not a chain.

Signed-off-by: Cody Soyland <cody.soyland@chainguard.dev>
@codysoyland codysoyland force-pushed the rekor-v2-dsse-as-hashedrekord branch from af5e23f to 5a2dd91 Compare May 14, 2026 22:15
Hayden-IO
Hayden-IO previously approved these changes May 14, 2026

@kommendorkapten kommendorkapten 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.

Thanks!

@Hayden-IO

Copy link
Copy Markdown

@loosebazooka any other comments?

@loosebazooka

Copy link
Copy Markdown
Member

oh, I'll take one last look

Comment thread rekor-v2-spec.md Outdated
Co-authored-by: Appu <appu@google.com>
Signed-off-by: Cody Soyland <codysoyland@gmail.com>
@Hayden-IO Hayden-IO merged commit d4da33e into sigstore:main May 19, 2026
1 check passed
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>
codysoyland added a commit to codysoyland/sigstore-conformance that referenced this pull request May 26, 2026
…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>
codysoyland added a commit to codysoyland/sigstore-go that referenced this pull request May 26, 2026
Implements the encoding proposed in sigstore/architecture-docs#63
(rekor-v2-spec §6.1.4): on Rekor v2, DSSE envelopes are uploaded as a
hashedrekord whose digest covers Hash(PAE(payloadType, payload)), with
the hash derived from the signing algorithm. Rekor v1 behavior is
unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Cody Soyland <cody.soyland@chainguard.dev>
codysoyland added a commit to codysoyland/sigstore-go that referenced this pull request May 27, 2026
Implements the encoding proposed in sigstore/architecture-docs#63
(rekor-v2-spec §6.1.4): on Rekor v2, DSSE envelopes are uploaded as a
hashedrekord whose digest covers Hash(PAE(payloadType, payload)), with
the hash derived from the signing algorithm. Rekor v1 behavior is
unchanged.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Signed-off-by: Cody Soyland <cody.soyland@chainguard.dev>
loosebazooka pushed a commit to sigstore/sigstore-conformance that referenced this pull request May 27, 2026
* test/assets: regen rekor v2 DSSE bundles and add rekor v1 hashedrekord-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>

* test/assets: remove rekor v1 dsse-with-hashedrekord fixtures

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>

* Update selftest pin for DSSE-with-hashedrekord support

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>

---------

Signed-off-by: Cody Soyland <cody.soyland@chainguard.dev>
Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
jku added a commit to jku/sigstore-rust that referenced this pull request May 28, 2026
This is based on sigstore/architecture-docs#63
* With Rekor v2 DSSE envelopes are supported via Hashedrekord entries
  instead of a dedicated dsse entry
* digest is Hash(PAE(payloadType, payload))
* Signature is the DSSE envelope signature

This commit removes all support for the "dsse 0.0.2" entry type: this seems
ok as rekor v2 signing was never deployed in production.
* When signing with rekor v2, build a "hashedrekord 0.0.2" entry with digest
  and signature as described above
* When verifying hashedrekord, compute hash depending on bundle content
* When matching hashedrekord signatures, use envelope signatures when appropriate
* When verifying rekor entry consistency, accept a DSSE envelope with a
  "hashedrekord 0.0.2" entry

Testing:
* Implement a few new verification tests

Signed-off-by: Jussi Kukkonen <jkukkonen@google.com>
wolfv pushed a commit to sigstore/sigstore-rust that referenced this pull request May 29, 2026
* conformance: Use main HEAD for testing

The new DSSE-as-hashedrekord tests have not yet been released

Signed-off-by: Jussi Kukkonen <jkukkonen@google.com>

* Rekor2: Support DSSE via Hashedrekord entries

This is based on sigstore/architecture-docs#63
* With Rekor v2 DSSE envelopes are supported via Hashedrekord entries
  instead of a dedicated dsse entry
* digest is Hash(PAE(payloadType, payload))
* Signature is the DSSE envelope signature

This commit removes all support for the "dsse 0.0.2" entry type: this seems
ok as rekor v2 signing was never deployed in production.
* When signing with rekor v2, build a "hashedrekord 0.0.2" entry with digest
  and signature as described above
* When verifying hashedrekord, compute hash depending on bundle content
* When matching hashedrekord signatures, use envelope signatures when appropriate
* When verifying rekor entry consistency, accept a DSSE envelope with a
  "hashedrekord 0.0.2" entry

Testing:
* Implement a few new verification tests

Signed-off-by: Jussi Kukkonen <jkukkonen@google.com>

* sign: Only allow 1 signature in DSSE envelope

As per specification

Signed-off-by: Jussi Kukkonen <jkukkonen@google.com>

---------

Signed-off-by: Jussi Kukkonen <jkukkonen@google.com>
@codysoyland codysoyland deleted the rekor-v2-dsse-as-hashedrekord branch June 5, 2026 14:09
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