Skip to content

Comments

Normalize signer env config and stabilize deterministic receipt signing/verification#8

Merged
GsCommand merged 1 commit intomainfrom
codex/implement-deterministic-receipt-signing-fixes
Feb 20, 2026
Merged

Normalize signer env config and stabilize deterministic receipt signing/verification#8
GsCommand merged 1 commit intomainfrom
codex/implement-deterministic-receipt-signing-fixes

Conversation

@GsCommand
Copy link
Contributor

Motivation

  • Ensure every emitted receipt contains metadata.proof.hash_sha256 and metadata.proof.signature_b64 by fixing signer configuration and signing paths.
  • Eliminate confusion between legacy and new env vars by normalizing to a single runtime config object while accepting legacy aliases.
  • Support optional dev-friendly in-memory key generation (DEV_AUTO_KEYS=1) and provide clear ENS TXT output for publishing verifier info.
  • Harden /verify to use env pubkey by default and optionally resolve/validate ENS TXT records for signer binding checks.

Description

  • Added envAny(...)/envFlag(...) and consolidated signer settings into a single runtimeConfig object (signerId, kid, canonicalId, privateKeyPem, privateKeyPemB64, publicKeyRaw32B64, ethRpcUrl).
  • Implemented active key management with activeSigner, getActivePrivatePem(), getActivePublicPem() and optional in-memory keypair generation when DEV_AUTO_KEYS=1, plus console output of temporary PEM (escaped) and ENS TXT lines via printEnsTxtValues().
  • Updated makeReceipt() to always sign via signReceiptEd25519Sha256(...) using runtimeConfig values and to populate both canonical/canonical_id for compatibility with runtime-core expectations.
  • Added normalizeReceiptForRuntimeCoreVerify() and changed /verify to: require signature_b64+hash_sha256 (400 if missing), choose public key from env or ENS (?ens=1), enforce ENS binding on signer_id/kid/canonical, and call verifyReceiptEd25519Sha256(...) with normalized receipt and allowed canonicals.
  • Boot-time validation: replaced direct assert with initializeSignerConfigOrThrow() which enforces required fields, refuses ambiguous keys, and will auto-generate in-memory keys only if DEV_AUTO_KEYS=1 (otherwise fails startup with clear message).
  • Health and debug endpoints updated to reflect active signer/verifier readiness (signer_ok, verifier_ok, signer_source) and debug output avoids printing private key material while reporting presence/length metadata.
  • Added deterministic mint/verify curl examples to README.md for quick local validation.

Testing

  • Ran syntax/check via npm run check (node --check server.mjs) which completed successfully.
  • Performed an end-to-end smoke run with DEV_AUTO_KEYS=1 (start server, POST /describe/v1.0.0, then POST /verify) and confirmed emitted receipt contains kid, canonical_id, hash_sha256, signature_b64 and that /verify returned hash_matches: true and signature_valid: true.

Codex Task

@GsCommand GsCommand merged commit 1ae5353 into main Feb 20, 2026
1 check failed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant