Receipt verifier

Verify a receipt yourself.

Paste a receipt. Your browser recomputes its hash and its checks root, checks the signature against our published key, and asks our server one question: is this hash in the ledger? The receipt holds no agent output, so there is nothing sensitive to paste.

Also prove which text it is about (optional)

A receipt commits to the output with a salted hash. If you hold the original output and the receipt_salt returned with it, the commitment can be checked here — locally, nothing is uploaded.

Checks 1–3 run on this device. Only the hash is sent for the ledger check.
Waiting
Nothing checked yet

Paste a receipt or load the sample.

  1. Structure

    Required fields are present and the version is supported.

  2. Hash

    The SHA-256 of the canonical body equals hash.

  3. Checks root

    Rebuilt from the public ruleset and the listed findings.

  4. Signature

    Ed25519 over the hash, against the key we publish.

  5. Ledger anchor

    The hash is recorded in the issuer's append-only ledger.

  6. Commitment

    Optional: the receipt is about the text you supplied.

How it works

Four checks you can repeat.

01 · hash

The body is its own fingerprint

Remove hash and signature, serialise what is left as canonical JSON (RFC 8785) and take the SHA-256. One changed character gives a different result.

02 · checks root

The findings have to add up

The ruleset is public. Every rule not listed in findings passed, so the root over all results can be rebuilt by anyone — a removed finding breaks it.

03 · signature

Only the issuer could sign it

Receipts from the API carry an Ed25519 signature over the hash. The public key is at /.well-known/agentgate-keys.json.

04 · anchor

It sits in a chain

Each receipt names the one before it. The ledger lookup confirms this hash holds a place in that sequence — so a receipt cannot be quietly dropped later.

Verify offline, in a dozen lines

You do not need this page. The format is documented and the checks use nothing beyond SHA-256 and Ed25519, both in every standard library.

Receipt format reference

What a valid receipt proves: that AgentGate evaluated a specific text with a specific ruleset at a specific time and reached that verdict. What it does not prove: that the text was true, that it was the text finally sent, or that the system as a whole is compliant.
verify.mjs
import { createHash, createPublicKey, verify } from "node:crypto";

// RFC 8785 canonical JSON: sorted keys, no whitespace
const canon = (v) => Array.isArray(v) ? `[${v.map(canon)}]`
  : v && typeof v === "object"
    ? `{${Object.keys(v).sort().map((k) => `${JSON.stringify(k)}:${canon(v[k])}`)}}`
    : JSON.stringify(v);

const { hash, signature, ...body } = receipt;
const digest = "sha256:" + createHash("sha256").update(canon(body)).digest("hex");
console.log("hash ok:", digest === hash);

const jwks = await (await fetch("https://agengate.com/.well-known/agentgate-keys.json")).json();
const key = createPublicKey({ key: jwks.keys.find((k) => k.kid === signature.kid), format: "jwk" });
console.log("signature ok:", verify(null, Buffer.from(hash), key, Buffer.from(signature.sig, "base64url")));