Docs / AP2
Guarding Google AP2 payment mandates
AP2 (the Agent Payments Protocol) gives agent commerce a mandate chain — Intent, Cart, Payment — that records what a user authorized. The moment of truth is the agent signing the PaymentMandate. @countersign/ap2 checks your spend policy at exactly that moment.
The guard
import { parseAp2, withAp2Guard, Ap2Denied } from "@countersign/ap2";
const charge = parseAp2(paymentMandate); // Gen-1 or Gen-2 → exact minor-unit amount
if (!charge) throw new Error("malformed mandate");
try {
await withAp2Guard(cs, agentId, charge, async () => signMandate(paymentMandate));
} catch (e) {
if (e instanceof Ap2Denied) audit(e.decision); // deny / needs_approval — do NOT sign
else throw e;
}
Why the parser is strict
- Two spec generations, two amount conventions. Gen-1 mandates carry W3C PaymentRequest amounts (floating-point, major units); Gen-2 carries integer minor units.
parseAp2normalizes both to an exact minor-unit integer using per-currency decimals — including zero-decimal (JPY) and four-decimal (CLF, UYW) currencies. - Truncation is rejected, not tolerated. A float where an integer belongs (a ~100× under-report waiting to happen), a negative, a NaN, or a missing currency parses to
null— the guard never sees a softened number. - Ungoverned assets deny. A fiat-USD mandate under a USDC-only policy is denied by the asset gate — default-deny, not default-shrug.
In MCP clients: the countersign_guard_ap2 tool takes the mandate and returns the decision. And because AP2 is where agents pay agents, this guard is also where governance propagates: the payer checks the payee's spend is governed before money moves.
Honest scope: everything here is testnet-only — no mainnet, no custody, no PII. The hosted sandbox seeds a mock three-backend fleet so you can exercise policy, guard, freeze, and ledger end-to-end; the vendor enforcement described on this page was proven live on real testnet backends. Mainnet follows a third-party security audit.
Try it in 60 seconds — no account, no human
Self-serve key, an isolated sandbox tenant with a three-backend demo fleet, testnet only.
Get a free key → Watch the freeze GitHub