Skip to content

Normalize signer env handling and harden receipt signing/health behavior#9

Merged
GsCommand merged 1 commit intomainfrom
codex/patch-server.mjs-for-signing-and-health-checks
Feb 20, 2026
Merged

Normalize signer env handling and harden receipt signing/health behavior#9
GsCommand merged 1 commit intomainfrom
codex/patch-server.mjs-for-signing-and-health-checks

Conversation

@GsCommand
Copy link
Contributor

Motivation

  • The runtime must accept both new CL_* env names and legacy aliases for signer identity and keys and produce properly-signed receipts.
  • Startup should not crash on malformed/missing signer config but instead expose health and error details while keeping endpoints responsive.
  • /health and /describe must reflect signer status and include kid / canonical_id and full proof fields when signing succeeds.

Description

  • Normalized environment inputs so SIGNER_ID is read from CL_RECEIPT_SIGNER or RECEIPT_SIGNER_ID, SIGNER_KID from CL_KEY_ID or SIGNER_KID, and CANONICAL_ID from CL_CANONICAL_ID with fallback to CANONICAL_ID_SORTED_KEYS_V1 when missing, and added support for RECEIPT_SIGNING_* key aliases and RECEIPT_SIGNING_PUBLIC_KEY_PEM_B64.
  • Enhanced PEM handling helpers and validators (normalizePemLoose, getPrivatePem, validatePrivateKeyPem, getPublicPemFromEnv, validatePublicKeyPem) to accept escaped single-line PEM, base64-encoded PEM, raw 32-byte public key (CL_PUBLIC_KEY_B64) -> SPKI PEM, and to validate keys with crypto without throwing on boot.
  • Introduced a non-fatal boot signer state (signerBootState) that collects validation errors and maybeEnableDevAutoKeys() still provides dev keys when enabled, and the server no longer crashes on invalid signer config.
  • Ensured makeReceipt() always invokes signReceiptEd25519Sha256(...) with normalized fields including signer_id, kid, canonical_id, and privateKeyPem when a valid private key is present so metadata.proof.hash_sha256 and metadata.proof.signature_b64 are populated.
  • Updated error handling so signature failures return a structured error receipt from respondSigningError() (including metadata.proof with null hash/signature) instead of crashing, and preserved /verify usage of verifyReceiptEd25519Sha256 with allowedCanonicals: [CANONICAL_ID] and existing ENS checks.
  • Added kid, canonical_id, and signer_errors to /health and made signer_ok reflect validated signer readiness rather than raw env presence.

Testing

  • Ran static check with node --check server.mjs which succeeded.
  • Verified server with no signer env by starting PORT=18080 node server.mjs and confirmed /health returns signer_ok: false with kid and canonical_id present and signer_errors populated.
  • Generated an Ed25519 keypair and exported CL_RECEIPT_SIGNER, CL_KEY_ID, CL_CANONICAL_ID, CL_PRIVATE_KEY_PEM and CL_PUBLIC_KEY_B64, started PORT=18082 node server.mjs, and confirmed /health showed signer_ok: true and a POST /describe/v1.0.0 returned metadata.proof.hash_sha256 and metadata.proof.signature_b64 populated.

Codex Task

@GsCommand GsCommand merged commit 24d2ccf 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