Skip to content

Support non-legacy receipt signature verification#217

Merged
GsCommand merged 1 commit into
mainfrom
claude/audit-protocol-infrastructure-vF6oo
May 13, 2026
Merged

Support non-legacy receipt signature verification#217
GsCommand merged 1 commit into
mainfrom
claude/audit-protocol-infrastructure-vF6oo

Conversation

@GsCommand
Copy link
Copy Markdown
Contributor

Summary

This PR adds support for verifying receipts using direct canonical string signatures in addition to the existing legacy hash-based verification. It introduces a new signature verification mode that signs the canonical payload directly instead of its SHA256 hash.

Key Changes

  • New verification function: Added verifyCanonicalSignature() to verify signatures against the canonical string directly using Ed25519
  • Dual-mode verification: Implemented logic to detect and handle both legacy (hash-based) and new (canonical-based) signature verification modes
    • Legacy mode: Verifies SHA256 hash of canonical payload (existing behavior)
    • New mode: Verifies canonical string directly (new behavior)
  • Flexible proof structure: Updated proof extraction to support both nested (receipt.metadata.proof) and flat (receipt.signature) structures
  • Schema validation updates:
    • Changed expected algorithm from ed25519-sha256 to ed25519 in runtime metadata validation
    • Updated canonical field name handling to accept both canonical and canonicalization
  • Final verification logic: Modified the ok result to only require hashMatched in legacy mode, allowing new mode receipts to pass without hash validation
  • CI/CD: Added GitHub Actions workflow for automated testing
  • Configuration: Added .env.example with runtime base URL

Implementation Details

  • The verification mode is determined by the presence of hash_sha256 in the proof metadata (isLegacyMode flag)
  • Signature validation now conditionally calls either verifyHashHexSignature() or verifyCanonicalSignature() based on the mode
  • All other validation checks (schema, canonicalization, key ID, signer) remain consistent across both modes
  • The change is backward compatible - existing legacy receipts continue to work as before

https://claude.ai/code/session_0112Taq5ne2BieC3hfqjjf3r

…s, CI

- lib/verifyReceipt.js: accept proof.canonical || proof.canonicalization;
  accept sig/kid from signature.* or metadata.proof.*; add verifyCanonicalSignature
  for v1.1.0 raw-bytes path; dual-mode routing by hash_sha256 presence so legacy
  receipts continue to pass; relax schemaValid hash_sha256 requirement
- api/_receipt-model.js: fix proof.alg check ed25519-sha256→ed25519; fix
  canonical field lookup canonical_id→canonicalization
- .github/workflows/ci.yml: new CI running npm test on push/PR
- .env.example: document RUNTIME_BASE_URL
@vercel
Copy link
Copy Markdown

vercel Bot commented May 13, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
commandlayer-commandlayer-org Ready Ready Preview, Comment May 13, 2026 1:58am
commandlayer-org Ready Ready Preview, Comment May 13, 2026 1:58am
commandlayer-org111 Ready Ready Preview, Comment May 13, 2026 1:58am

Request Review

@GsCommand GsCommand merged commit 4ff3a8e into main May 13, 2026
6 checks passed
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