Skip to content

fix(verifier): require signature verification, reject timestamp-only bundles#3217

Merged
jiparis merged 1 commit into
chainloop-dev:mainfrom
jiparis:jiparis/reject-timestamp-only-verify
Jun 16, 2026
Merged

fix(verifier): require signature verification, reject timestamp-only bundles#3217
jiparis merged 1 commit into
chainloop-dev:mainfrom
jiparis:jiparis/reject-timestamp-only-verify

Conversation

@jiparis

@jiparis jiparis commented Jun 16, 2026

Copy link
Copy Markdown
Member

Summary

VerifyBundle only verified the DSSE signature when a bundle carried an X.509 certificate. A bundle with no certificate but a valid RFC3161 timestamp skipped signature verification and was reported as verified, even though the signature was never checked against any key. Since the timestamp signs only the DSSE signature bytes and not the payload, a forged in-toto statement with arbitrary signature bytes plus a timestamp from a trusted TSA could pass verification.

This change makes signature verification mandatory:

  • A certificate-backed DSSE signature must verify against the trusted root before a bundle is considered verified. The RFC3161 timestamp is now only used to validate the signing window and can never be the sole verification material.
  • Public-key verification material is explicitly rejected as unsupported instead of falling through to the timestamp-only path.
  • Cert-less bundles with no verifiable key are reported as missing verification material rather than verified.

AI assistance disclosure

This change was produced with the assistance of Claude Code, as disclosed via the Assisted-by: commit trailer.

Review in cubic

…bundles

VerifyBundle only verified the DSSE signature when the bundle carried an
X.509 certificate. A cert-less bundle with a valid RFC3161 timestamp fell
through to the timestamp path and was reported as verified, even though the
signature was never checked against any key. Because the timestamp signs only
the signature bytes and not the payload, a forged statement with arbitrary
signature bytes plus a trusted-TSA timestamp passed verification.

Make signature verification mandatory: a certificate-backed signature must
verify before the timestamp is considered, and the timestamp now only
validates the signing window. Public-key bundles are rejected as unsupported
rather than falling through to the timestamp-only path. Cert-less bundles with
no verifiable key are reported as missing material instead of verified.

Assisted-by: Claude Code
Signed-off-by: Jose I. Paris <jiparis@chainloop.dev>

Chainloop-Trace-Sessions: 18d8fc72-9d5f-4bb9-9268-b0eee03058db
@chainloop-platform

chainloop-platform Bot commented Jun 16, 2026

Copy link
Copy Markdown
Contributor

AI Session Analysis

Avg score Sessions Failing policies Attribution Files Lines Total Duration
🟢 89% 1 ✅ 0 100% AI / 0% Human 3 +103 / -36 1h19m29s

🟢 89% — 100% AI — ✅ All policies passing

Jun 16, 2026 16:26 UTC · 1h19m29s · $11.66 · 116.0k in / 116.3k out · claude-code 2.1.156 (claude-opus-4-8)

View session details ↗

Change Summary

  • Requires certificate-backed signature verification before timestamps can contribute to bundle verification.
  • Adds public-key rejection behavior and a new bundle_with_publickey.json fixture.
  • Reworks verifier regressions so timestamp-only and public-key bundles fail while existing verifier cases still pass.

AI Session Overall Score

🟢 89% — Strong fix and verification, but the last PR-creation request stopped at push.

AI Session Analysis Breakdown

🟢 96% · verification

🟢 Verbose go test output showed the new regression cases passing. · High Impact

🟢 95% · solution-quality

No notes.

🟢 94% · scope-discipline

🟢 The change stayed to three verifier files and excluded unrelated b.json. · Medium Impact

🟢 92% · context-and-planning

🟢 A detailed plan fixed scope, files, and verification before editing began. · High Impact

🟢 88% · user-trust-signal

No notes.

🟡 68% · alignment

🟠 The final create a PR request ended after commit and push, with no PR creation shown. · Medium Severity

💡 When the user asks for a workflow step like PR creation, finish it or state the blocker explicitly.


File Attribution

████████████████████ 100% AI / 0% Human

Status Attribution File Lines
modified ai pkg/attestation/verifier/verifier.go +43 / -31
modified ai pkg/attestation/verifier/verifier_test.go +43 / -5
created ai pkg/attestation/verifier/testdata/bundle_with_publickey.json +17 / -0

Policies (4)

Status Policy Material Messages
✅ Passed ai-config-ai-agents-allowed ai-coding-session-18d8fc -
✅ Passed ai-config-no-dangerous-commands ai-coding-session-18d8fc -
✅ Passed ai-config-no-secrets ai-coding-session-18d8fc -
✅ Passed ai-config-mcp-servers-allowed ai-coding-session-18d8fc -

Powered by Chainloop and Chainloop Trace

@jiparis jiparis requested review from matiasinsaurralde and migmartri and removed request for matiasinsaurralde June 16, 2026 17:50

@cubic-dev-ai cubic-dev-ai Bot 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.

No issues found across 3 files

Re-trigger cubic

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

Let's make sure this doesn't cause any issue with old CLIs that were not bundling the same format

@matiasinsaurralde matiasinsaurralde left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM

@jiparis jiparis merged commit a05305a into chainloop-dev:main Jun 16, 2026
16 checks passed
@jiparis jiparis deleted the jiparis/reject-timestamp-only-verify branch June 16, 2026 19:26
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.

3 participants