Skip to content

Latest commit

 

History

History
159 lines (110 loc) · 5.34 KB

File metadata and controls

159 lines (110 loc) · 5.34 KB

CommandLayer Runtime

Reference Node.js runtime for CommandLayer Commons verbs. This service executes deterministic verb handlers, signs receipts with Ed25519, and verifies receipts using local keys or ENS-discovered public keys.

What this service does

  • Exposes POST /<verb>/v1.0.0 endpoints for Commons verbs (fetch, describe, format, clean, parse, summarize, convert, explain, analyze, classify).
  • Returns signed receipts containing:
    • deterministic result payloads,
    • execution trace metadata,
    • proof metadata (alg, canonical mode, SHA-256 hash, signature).
  • Exposes POST /verify to verify receipt hash/signature, and optionally validate schema + fetch public key from ENS.
  • Includes schema validator caching, warmup queueing, SSRF protections for fetch, and runtime safety budgets.

API overview

Core routes

  • GET / — service index with links and enabled verbs.
  • GET /health — process/service health and signer readiness.
  • POST /<verb>/v1.0.0 — execute a single verb and return a signed receipt.
  • POST /verify — verify receipt integrity/signature; optional schema and ENS verification.

Debug routes

  • GET /debug/env — effective runtime configuration.
  • GET /debug/enskey — ENS TXT key discovery state.
  • GET /debug/schemafetch?verb=<verb> — computed receipt schema URL.
  • GET /debug/validators — validator cache and warm-queue state.
  • POST /debug/prewarm — queue schema validator warmup.

Quickstart

1) Install dependencies

npm install

2) Generate an Ed25519 keypair (for local signing)

openssl genpkey -algorithm Ed25519 -out private.pem
openssl pkey -in private.pem -pubout -out public.pem

export RECEIPT_SIGNING_PRIVATE_KEY_PEM_B64="$(base64 -w0 < private.pem)"
export RECEIPT_SIGNING_PUBLIC_KEY_B64="$(openssl pkey -in public.pem -pubin -outform DER | tail -c 32 | base64 -w0)"
export RECEIPT_SIGNER_ID="runtime.commandlayer.eth"

macOS note: replace base64 -w0 with base64 | tr -d '\n'.

3) Start the runtime

npm start

Default port is 8080 (override with PORT).

4) Verify startup

curl -s http://localhost:8080/health | jq .

You should see "ok": true and "signer_ok": true.

Example flow

Request a fetch receipt

RECEIPT=$(curl -s -X POST "http://localhost:8080/fetch/v1.0.0" \
  -H "Content-Type: application/json" \
  -d '{
    "x402": {
      "entry": "x402://fetchagent.eth/fetch/v1.0.0",
      "verb": "fetch",
      "version": "1.0.0"
    },
    "source": "https://example.com"
  }')

printf '%s\n' "$RECEIPT" | jq .

Verify the receipt locally

printf '%s' "$RECEIPT" | curl -s -X POST "http://localhost:8080/verify" \
  -H "Content-Type: application/json" \
  -d @- | jq .

Verify with ENS public key lookup

printf '%s' "$RECEIPT" | curl -s -X POST "http://localhost:8080/verify?ens=1" \
  -H "Content-Type: application/json" \
  -d @- | jq .

Verification semantics

POST /verify supports query flags:

  • ens=1 — fetch verifier pubkey from ENS TXT records (cl.sig.pub, cl.sig.canonical, optional cl.sig.kid).
  • strict_kid=1 — when ens=1 and cl.sig.kid exists, require receipt metadata.proof.kid to match ENS cl.sig.kid.
  • refresh=1 — bypass ENS cache and refresh lookup.
  • schema=1 — validate receipt against verb schema.

When VERIFY_SCHEMA_CACHED_ONLY=1 (default), schema validation is edge-safe:

  • if validator is warm: request is fully validated,
  • if validator is cold: service returns 202 with validator_not_warmed_yet and queues async prewarm.

Use POST /debug/prewarm and GET /debug/validators for schema prewarming workflows.

Configuration

Detailed environment variable documentation lives in docs/CONFIGURATION.md.

ENS TXT format (runtime.commandlayer.eth)

  • cl.sig.pub = ed25519:<base64-raw32-ed25519-public-key>
  • cl.sig.canonical = json.sorted_keys.v1
  • cl.sig.kid = v1 (optional compatibility marker; runtime derives receipt kid from pubkey fingerprint)
  • cl.receipt.signer = runtime.commandlayer.eth

Security notes

  • fetch only allows http(s) URLs.
  • SSRF guard blocks localhost/private IP ranges and DNS resolutions to private ranges.
  • Optional host allowlist (ALLOW_FETCH_HOSTS) can strictly bound outbound fetch.
  • Request-level limits are capped by server-side SERVER_MAX_HANDLER_MS.
  • /verify execution is bounded by VERIFY_MAX_MS.

Operational notes

  • Validator/schema caches are in-memory (per process).
  • Prewarm is best-effort and asynchronous.
  • In multi-replica deployments, warm each replica independently.

See docs/OPERATIONS.md for deployment and runbook guidance.

Deterministic signing test commands

# mint
curl -s -X POST http://localhost:8080/describe/v1.0.0 -H "Content-Type: application/json" -d '{"x402":{"verb":"describe","version":"1.0.0","entry":"x402://describeagent.eth/describe/v1.0.0"},"input":{"subject":"CommandLayer","detail_level":"short"}}' | tee receipt.json | jq '.metadata.proof | {kid, canonical_id, hash_sha256, signature_b64}'

# verify env
curl -s -X POST http://localhost:8080/verify -H "Content-Type: application/json" --data-binary @receipt.json | jq .

# verify ens
curl -s -X POST "http://localhost:8080/verify?ens=1" -H "Content-Type: application/json" --data-binary @receipt.json | jq .