Skip to content

feat(REQ-27): from_sigstore_bundle — ingest cosign/Sigstore bundles (#260) - #264

Open
avrabe wants to merge 1 commit into
mainfrom
feat/req-27-from-sigstore-bundle
Open

feat(REQ-27): from_sigstore_bundle — ingest cosign/Sigstore bundles (#260)#264
avrabe wants to merge 1 commit into
mainfrom
feat/req-27-from-sigstore-bundle

Conversation

@avrabe

@avrabe avrabe commented Aug 21, 2026

Copy link
Copy Markdown
Contributor

Closes the ingestion half of #260: wsc could only verify artifacts it signed itself — SigstoreBundle can emit wsc signatures but nothing converted an existing cosign bundle back into a KeylessSignature. varve already ships cosign bundles (keyless, GitHub-OIDC).

Change

KeylessSignature::from_sigstore_bundle(json) parses both wire shapes:

  • Legacy rekorBundle JSON (cosign v2.4.x — varve's v0.28.0 shape).
  • Protobuf bundle.sigstore.dev/v0.3+json envelope.

Verified against two REAL fixtures (committed)

  • legacy_rekorbundle_keyless.json — varve v0.28.0's actual public bundle. Internally consistent (body digest = sha256(SHA256SUMS.txt)).
  • protobuf_v0.3_localkey.json — real cosign --new-bundle-format output.

Faithful extraction, non-vacuously tested:

  • module_hash read from the hashedrekord body's spec.data.hash.value, never recomputed — the negative control flips one hex char and asserts the extracted hash changes.
  • integratedTime (unix int) → RFC3339 (the form verify_cert_chain parses; confirmed cert-chain and body-binding both accept the ingested varve bundle).
  • v0.3 requires a Fulcio cert; a raw-public-key bundle is rejected with a specific error, proven on the real v0.3 fixture.
  • Round-trip fidelity test preserves signature/module_hash/cert-chain/rekor fields.

⚠️ Known limitation → completed by REQ-28 (#231, the verify half)

cosign emits ECDSA signatures in ASN.1 DER (varve's is 71 bytes, 3045…), but the offline verifier's verify_crypto uses P256Signature::from_slice (fixed 64-byte P1363), so it rejects an ingested DER signature today. Making the verifier accept DER (from_der fallback) + handling the empty Rekor uuid on the offline path is REQ-28's scope — that's where "verify an ingested cosign bundle offline" completes. This PR is the faithful ingestion half; it does not claim the ingested bundle fully verifies (and no test says so).

Evidence

wsc lib 610 pass/3 ignored; sigstore_bundle 7 pass; vacuous-oracle gate clean.

Part of the v0.12.0 varve-interop line (plan #261). Refs #260, #231.

🤖 Generated with Claude Code

…260)

varve (#260) already produces cosign bundles (keyless, GitHub-OIDC) but wsc could
only verify artifacts it signed itself — SigstoreBundle can emit wsc signatures
but nothing converts an existing cosign bundle back into a KeylessSignature.

Adds KeylessSignature::from_sigstore_bundle(json) parsing BOTH wire shapes:
- Legacy `rekorBundle` JSON (cosign v2.4.x — what varve's v0.28.0 ships):
  {base64Signature, cert, rekorBundle:{SignedEntryTimestamp, Payload}}.
- Protobuf `bundle.sigstore.dev/v0.3+json` envelope (verificationMaterial +
  messageSignature + tlogEntries).

Faithful extraction (verified against two REAL fixtures committed here):
- module_hash is read from the hashedrekord body's spec.data.hash.value, never
  recomputed; the negative-control test flips one hex char and asserts the
  extracted hash changes.
- integratedTime (unix int) -> RFC3339, the form RekorEntry documents and
  verify_cert_chain parses (confirmed: cert-chain + body-binding both accept the
  ingested varve bundle).
- v0.3 requires a Fulcio certificate; a raw-public-key (non-keyless) bundle is
  rejected with a specific error, proven on a real cosign v0.3 bundle.

Round-trip fidelity test: from_sigstore_bundle -> from_keyless_signature ->
to_json -> from_json preserves signature, module_hash, cert chain and rekor
fields (uuid/inclusion_proof intentionally empty for legacy — documented).

KNOWN LIMITATION → REQ-28 (#231, the verify half): cosign emits ECDSA
signatures in ASN.1 DER (varve's is 71 bytes, 3045…), but the offline
verifier's verify_crypto uses P256Signature::from_slice (fixed 64-byte P1363),
so it currently rejects an ingested DER signature. Making the verifier accept
DER (from_der fallback) and handling the empty Rekor uuid on the offline path
is REQ-28's scope — that is where "verify an ingested cosign bundle offline"
completes. from_sigstore_bundle here is the faithful ingestion half.

Fixtures: legacy = varve v0.28.0 public release; v0.3 = real cosign
--new-bundle-format output (see fixtures README).

Tests: wsc lib 610 pass/3 ignored; sigstore_bundle 7 pass.

Refs: #260, #231
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012aR3Md1h46K9wAUWMQiESH
@codecov

codecov Bot commented Aug 21, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 42.04947% with 164 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
src/lib/src/signature/keyless/format.rs 42.04% 164 Missing ⚠️

📢 Thoughts on this report? Let us know!

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