VetoVetoDocs
Concepts

Mandates

The optional, polymorphic authorization an agent presents at checkout — veto · ap2 · acp · none. A Veto-governed agent is simply the highest-trust input, never a requirement.

A mandate is what an agent presents at checkout to prove its spend was authorized. It is optional and polymorphictype ∈ { veto, ap2, acp, none }. A Veto-governed agent is the highest-trust input, never a requirement: your policy decides whether a mandate is needed for a given amount.

interface PresentedMandate {
  type: 'veto' | 'ap2' | 'acp' | 'none';
  token?: string; // compact JWS for `veto`
  raw?: unknown;
}

veto — verified and bound

A compact Ed25519 JWS signed by an issuer whose JWKS you trust (matched by kid). The payload authorizes a specific merchant, amount, and intent:

{
  "iss": "veto",
  "typ": "veto-mandate+jws",
  "sub": "<jti uuid>",
  "exp": 1750003600,
  "decision": "approve",
  "agent_id": "<uuid>",
  "authorization": {
    "merchant": "<merchantId-or-domain>",
    "max_amount": "50.00",
    "currency": "USD",
    "intent": "<text>"
  }
}

Valid + bound ⇒ tier premium when all hold:

  • signature verifies against a trusted JWKS (kid match)
  • decision === "approve"
  • exp > now
  • authorization.max_amount >= cart.total
  • merchant matches your merchant.id or .domainmerchantMatch = true

If any binding fails, a specific reason code fires — MANDATE_INVALID_SIGNATURE, MANDATE_EXPIRED, MANDATE_AMOUNT_INSUFFICIENT, MANDATE_MERCHANT_MISMATCH, or MANDATE_NOT_APPROVED.

ap2, acp — typed stubs

Accepted on the wire so the protocol is forward-compatible, but today they return valid:false with MANDATE_TYPE_UNSUPPORTED. A TODO marks exactly where a real AP2 cart-mandate / ACP token verifier plugs in.

none — no mandate

Legal and first-class, not an error. Trust falls back to reputation alone: standard if the agent is known, cautious if unknown. Use policy to decide whether a none request can clear at a given amount.

Replay protection

A mandate's subject (sub/jti) is single-use. The gate reserves it atomically the moment a mandate verifies valid and has a subject — before capture — so two concurrent settles of one mandate cannot both succeed. A reused subject is MANDATE_REPLAY.

Mandates pair with receipts.

The buyer holds a mandate; on accept, the merchant issues a receipt whose mandateRef points back at the mandate subject. Two signed artifacts pointing at each other are your non-repudiation evidence.