Skip to content

feat(cli): offline receipt verification with a local public key#833

Merged
jithinraj merged 5 commits into
mainfrom
feat/offline-verify-public-key
Jun 10, 2026
Merged

feat(cli): offline receipt verification with a local public key#833
jithinraj merged 5 commits into
mainfrom
feat/offline-verify-public-key

Conversation

@jithinraj

@jithinraj jithinraj commented Jun 10, 2026

Copy link
Copy Markdown
Member

Summary

Adds an offline verification path to peac verify: --public-key <path> verifies a receipt JWS against a local public Ed25519 JWK or single-key JWKS with no network access. The existing network verification path is unchanged when the flag is omitted. Public surface change: adds the CLI flag peac verify --public-key <path>. No package exports, wire format, schema, signing, or registry changes.

Scope

  • packages/cli/src/index.ts (verify command option + offline branch)
  • packages/cli/src/lib/public-key.ts (new key loader)
  • packages/cli/tests/public-key.test.ts (new key-loader tests)
  • packages/cli/tests/verify-public-key-cli.test.ts (new command wiring tests)

Explicitly not changed: verifyReceipt network resolution, verifyLocal semantics, any published package other than the CLI.

Changes

  • peac verify <jws> --public-key <path> reads a bare public Ed25519 JWK or a single-key JWKS file and verifies via verifyLocal (signature plus declared receipt structure), entirely offline.
  • The key loader fails closed: it rejects files containing private key material (d), multi-key or empty JWKS, non-Ed25519 keys, and missing or malformed x values. Byte conversion reuses the canonical jwkToPublicKeyBytes from @peac/crypto. Error messages never echo key material.
  • File reads in the verify command are bounded via the existing fd-bound snapshot helper: public-key files at 16 KiB and receipt files at 512 KiB. Oversized files, directories, and missing paths are rejected with user-safe messages that do not echo paths or content.
  • Works directly with generated samples:
npx @peac/cli samples generate -o ./peac-samples
npx @peac/cli verify ./peac-samples/valid/basic-record.jws --public-key ./peac-samples/bundles/sandbox-jwks.json

Validation

  • CLI test suite: 286 passed, including the key-loader acceptance and rejection matrix, an error-hygiene check, and command wiring tests that spawn the built CLI with timeouts and temp-dir cleanup (valid sample verifies; tampered record, private-key file, oversized key file, directory key path, missing key path, oversized receipt file, and directory receipt path all fail non-zero).
  • End-to-end against the built CLI: generated samples verify offline (exit 0); a tampered JWS fails with E_INVALID_SIGNATURE (exit 1); a private-key file is rejected (exit 1); invalid samples fail closed (exit 1); omitting the flag exercises the unchanged network path.
  • tsc --noEmit, Prettier, and whitespace checks pass.

@jithinraj
jithinraj merged commit 578ac57 into main Jun 10, 2026
23 checks passed
@jithinraj
jithinraj deleted the feat/offline-verify-public-key branch June 10, 2026 08:59
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