Skip to main content

🚀 Beta: All Pro and Team features are free. Install on GitHub →

Portable Proof of Authorization

Verify it yourself. Without trusting CodeRifts.

Every CodeRifts verdict can carry a cryptographically signed proof that an API change was authorized before execution. The proof travels with the change. Anyone verifies it with the public key alone — no CodeRifts API, no account, no server call required for the signature check.

An authorization proof, not a receipt

A CodeRifts chain_receipt is a portable, verifiable proof that a specific contract-changing action was authorized, bound to a signed fingerprint of that decision, and checkable by anyone — another agent, CI, a merge gate, a deployment system — before the action runs.

The chain is simple:

Intent → Authorize → Proof → Verify → Execute → Evidence

No verified proof, no contract mutation.

Check a receipt in one command

The open-source verifier fetches the public key from the published attestation endpoint (or uses a pinned key / key registry) and checks the Ed25519 signature over the receipt’s own signed bytes. If it passes, the verdict provably came from the holder of the CodeRifts signing key. You do not have to take our word for it.

Exact usage from the public receipt-verifier README and source headers (node verify.js, python3 verify.py).

Node (zero dependencies, Node ≥ 20)

# Get a receipt (action-verdict needs no API key), then verify.
# Public key is discovered from the attestation endpoint automatically.
RECEIPT=$(curl -s -X POST https://app.coderifts.com/api/v1/action-verdict \
  -H 'Content-Type: application/json' \
  -d '{"action_type":"tool_call","provenance":{"channel":"ci_manifest","issuer_trust":"trusted"},"tool":{"name":"get_customer","capabilities":["read"]},"memory":{"op":"read","namespace":"working","staleness_hours":1}}' \
  | node -e "let s='';process.stdin.on('data',d=>s+=d).on('end',()=>process.stdout.write(JSON.parse(s).chain_receipt))")

node verify.js "$RECEIPT"

# Offline (no network): pin a PEM, or resolve by kid from the key registry
node verify.js "$RECEIPT" --key pub.pem --kid 2026-07-k1
node verify.js "$RECEIPT" --keys https://app.coderifts.com/.well-known/coderifts-keys.json

Python 3.10+ (pip install cryptography)

RECEIPT=$(curl -s -X POST https://app.coderifts.com/api/v1/action-verdict \
  -H 'Content-Type: application/json' \
  -d '{"action_type":"tool_call","provenance":{"channel":"ci_manifest","issuer_trust":"trusted"},"tool":{"name":"get_customer","capabilities":["read"]},"memory":{"op":"read","namespace":"working","staleness_hours":1}}' \
  | python3 -c "import sys,json;print(json.load(sys.stdin)['chain_receipt'])")

python3 verify.py "$RECEIPT"

python3 verify.py "$RECEIPT" --key pub.pem --kid 2026-07-k1
python3 verify.py "$RECEIPT" --keys https://app.coderifts.com/.well-known/coderifts-keys.json

Exit codes: 0 valid, 1 invalid, 2 usage error. Default key discovery URL: https://app.coderifts.com/api/v1/attestation/public-key (override with --fetch).

What the proof guarantees

Grounded in the frozen public contract (RECEIPT_FORMAT.md). Where the format version or live status taxonomy is narrower than a marketing claim, the page states the measured boundary.

1. What it proves

The Ed25519 signature covers a frozen, pipe-delimited byte string: key id, verdict fingerprint (fp), previous-link hash, caller, and issuance time. Envelope v2+ also signs an evidence-registry field; v3+ a Change-IR hash; v4 adds expires_at and a decision body hash (bh). The independent verifier confirms the signature over those signed bytes. It treats fp as an opaque binding — it does not recompute the fingerprint from a verdict payload (out of scope for the receipt verifier). Full decision-envelope rebind is available on v4 via --envelope.

2. Who can verify

Anyone with the public key (or the append-only key registry). No API key, no CodeRifts account. A successful signature check proves authenticity of the signed binding. It is not, by itself, a gate saying “execute this action now” — merge, deploy, and runtime gates still compose the receipt with operation match, fingerprint match, and allow-class execution_action. CodeRifts states this explicitly: a valid signature is authenticity, not a complete authorization decision.

3. What it’s bound to

Every envelope version binds the opaque verdict fingerprint fp inside the signed bytes. v4 also binds the RFC 8785-canonical decision envelope via bh (re-checkable with --envelope; mismatch → body_hash_mismatch). Audience and environment mismatch statuses exist in the taxonomy but are dormant until the matching check inputs are supplied — a missing binding is never treated as a match. A proof for one signed fingerprint does not authorize a different change.

4. How long it is valid

On v4 envelopes, expiry is signed into the proof as expires_at. The verifier compares it to now: authentic but past expiry returns VERIFIED_EXPIRED (not a green pass). Earlier envelope versions (v1–v3) do not carry a signed expiry field — freshness for those is judged by the gate that consumes the receipt, not by an in-token clock field.

5. How it is invalidated

Key rotation is append-only: retired keys stay in /.well-known/coderifts-keys.json. A receipt signed while a key was live remains trustworthy after retirement (RETIRED_KEY_VALID_AT_ISSUE); a receipt timed at or after retired_at is rejected. If the key registry or attestation endpoint cannot be reached when discovery is required, the status is REGISTRY_UNREACHABLE (fail closed on discovery, not a silent pass). A supersession status exists in the taxonomy but is currently dormant (no check input defined yet in the public format) — this page does not claim live automatic supersession enforcement.

6. Replay-resistant binding

The signature covers the exact reconstructed signed bytes. Altering any signed field invalidates the signature. On v4, re-checking against a local copy of the decision envelope (--envelope) requires the body hash to match bh — a genuine token cannot be slid onto a different decision body. Chain mode additionally requires each non-genesis prev to equal sha256: of the previous token string.

Honest limit: a valid signature is authenticity of the signed binding, not a complete authorization decision. CodeRifts says so — and the independent verifier is designed to prove only what the frozen format actually signs.

A frozen, public contract

The byte format is frozen. For a given envelope version the field order and separators of the signed byte-string never change. New fields are only ever appended under a new envelope version. The chain lives in the request/response; nothing is stored server-side for independent verification.

Why portable proof matters for AI agents

When an agent changes a contract, “it said it checked” is not evidence. A portable proof is — it binds authorization material to a signed fingerprint of the exact change, survives handoff between agents and systems, and is verifiable independently before execution.

That is the difference between a tool that reports and a layer that authorizes.