The open standard and reference implementation for proving that an AI agent's purchase
stayed within the user's signed mandate, verifiable offline by a merchant, an issuer, or
the buyer, with no trust in any network. Ships as the @axiorank/audit-verify npm package
(MIT, zero dependencies).
- Specs: COMMERCE.md (Commerce Conformance Seal + Reputation + mandate), SEAL.md (Agent Action Seal).
- Reference verifier: this repo. Conformance test vectors:
src/vectors.json. - Learn more: https://axiorank.com/agent-commerce-conformance
Independently verify AxioRank audit receipts, commerce conformance seals, and agent reputation credentials offline, with nothing but a public key. No AxioRank account, no API call, no trust in AxioRank.
A receipt proves three things about a single governed action:
- Membership. The audit row is in the sealed RFC 6962 Merkle tree (an inclusion proof).
- Integrity. That tree's root was signed by the log (an Ed25519 signed tree head).
- Provenance. Who or what authorized the action, as a signed delegation chain (operator who approved, the agent key, the upstream trace step).
This package re-implements the verification primitives (JCS canonicalization, RFC 6962 Merkle, Ed25519) in about 200 lines with zero dependencies, so you can read all of it in a few minutes and trust nothing else.
npm install @axiorank/audit-verifyRequires Node 18 or newer.
import { verifyReceipt } from "@axiorank/audit-verify";
// `jwks` is a key you pinned out of band (see "Trust model" below).
const result = verifyReceipt(receipt, jwks);
if (result.ok) {
console.log("verified");
} else {
console.error(`failed: ${result.reason}`, result.checks);
}# Verify against a key you pinned and stored alongside your records.
npx @axiorank/audit-verify receipt.json --jwks key.json
# ✓ leaf hash
# ✓ inclusion proof
# ✓ signed tree head
# ✓ delegation provenance
#
# VERIFIEDExit code is 0 when verified, 1 when verification fails, 2 on a usage error.
An Agent Action Seal is a portable, signed proof-of-governance an agent carries and presents at the moment it acts, before the audit window seals. Verify one the same way:
npx @axiorank/audit-verify seal ./seal.json --jwks key.json
# ✓ seal format
# ✓ seal signature
# ✓ embedded provenance
# ✓ provenance binds to action
# ✓ human approver signature
# ✓ freshness (within window)
#
# VERIFIEDIn code, use verifyPassport(seal, jwks) (the function name is the stable protocol API).
The full format is documented in SEAL.md. Once the audit window seals, upgrade
the Seal to a full Merkle inclusion receipt with verifyReceipt.
When an AI agent makes a purchase on a person's behalf, a Commerce Conformance Seal proves
the purchase stayed within the user or issuer's signed mandate (a spend cap, an allowed set
of merchants and categories, a currency, a time window). It is an Action Seal carrying a
signed commerce block, so a merchant, an issuer, or the buyer can all check it offline,
without trusting any network:
import { verifyCommerceSeal } from "@axiorank/audit-verify";
// Without the mandate: confirms the seal is genuine and reports its signed verdict.
const r = verifyCommerceSeal(seal, jwks);
// r.checks.commerce === true, seal.commerce.inScope === true | false
// With the mandate (pinned out of band): also confirms the seal references that exact
// mandate and that the in-scope verdict is not a lie.
const r2 = verifyCommerceSeal(seal, jwks, { mandate });
// r2.checks.mandateBinding -> the seal is bound to THIS mandate
// r2.checks.inScopeHonest -> the signed verdict is not refuted by re-running the mandateevaluateMandate(purchase, mandate) and mandateHash(mandate) are exported so you can
re-run the conformance check yourself. AxioRank consumes the mandate (for example an AP2
Intent Mandate); it does not issue it.
A receipt is only as trustworthy as the key you check it against. For genuine independence, pin the public key out of band: fetch it once from https://app.axiorank.com/api/v1/audit/public-key, confirm the kid, and store that key with your records. Then verify every receipt against the pinned key.
The package ships a fetchJwks() convenience that pulls the live JWKS, but fetching the key from the same party that issued the receipt is not independent verification. Use it for tooling, never as your trust anchor.
A verified receipt proves the action is in a signed, append-only log and was authorized as the provenance chain states, and that the record was not altered after sealing. It does not, on its own, protect against a split-view attack (a malicious operator showing different signed histories to different parties); that requires gossiping signed tree heads to an external witness. Pin tree heads over time (GET /api/v1/audit/checkpoints/{seq}) to detect a retroactive edit yourself.
MIT