---
title: Sign the limits, not the purchase
description: AP2 is named for payments, but Alan from Google calls it what it is, delegated user authority. Notes on that part of the AGNTCon + MCPCon livestream, the flight ticket that got approved five times and never bought, and how AP2's open and closed mandates let you sign the limits once and walk away.
date: 2026-10-28
tags: AI agents, agent authorization, AP2, agentic commerce, A2A
---

If your agent asks for your thumbprint every time it's about to act, you're not delegating, you're babysitting. AP2, the Agent Payments Protocol, fixes that with a mandate: you sign the limits once, on a screen no agent controls, and the agent acts later inside them without you. Whoever it hands the mandate to can check, cryptographically, that it stayed inside the lines. It was built for shopping, but as Alan from Google put it on stage, it really is delegated user authority, and it's broadly applicable.

That line comes from the last conversation of the day-two livestream at AGNTCon + MCPCon North America, October 23, a tour of Google's pile of agent protocols. It's about two minutes long, and it names a problem I have with every agent I run.

## Payments was the hardest test, not the point

Alan is a product manager at Google who helped with A2A and with MCP adoption inside Google, and he sits on the technical steering committee of the Agentic AI Foundation. He also worked in payments at Google for six years, which is where AP2 comes from.

His take on the name: it's poorly named. The host summed up the idea as "I as a human put my thumbprint on my phone to say, yes agent, go do this on my behalf." Alan's answer: "That's effectively a mandate. It's used for purchases because we were like, what's the hardest problem that we can do right now?" Then: "But that delegation of authority is valuable in a lot of other contexts."

Payments makes a good first test because money has a built-in judge. A refund or a chargeback is a dispute about whether you really meant it, so in his words "you have to force the delegation so that it's provable." He calls AP2 the strategic piece, and he's honest that it'll take a long time to spread. Its sibling, UCP, the Universal Commerce Protocol, is the tactical one: the conventions of online shopping (cart, inventory, shipping options) as small modules over MCP and A2A, usable today.

<figure class="fd-fig ap ap-f1" aria-labelledby="ap1-cap" data-desc="Two readings of AP2. By its name, the Agent Payments Protocol: purchases, a payment mandate, the user's thumbprint on a phone, chosen as the hardest problem Google could take on first. By what it is, in Alan's words: delegated user authority, valuable in a lot of other contexts, wherever an agent acts on someone's behalf and the other side needs proof the person meant it. Underneath, his split of the two commerce protocols: AP2 strategic, because refunds and chargebacks force the delegation to be provable, and slow to spread; UCP tactical, the conventions of online shopping over MCP and A2A, available now.">
<div class="mp-two-row">
<div class="mp-two-card">
<p class="mp-two-who">By its name</p>
<p class="mp-two-name">Payments</p>
<p class="mp-two-line">The Agent Payments Protocol</p>
<p class="mp-two-line">Your thumbprint on your phone</p>
<p class="mp-two-line">Picked as the hardest problem to start with</p>
</div>
<p class="mp-two-vs">vs</p>
<div class="mp-two-card mp-two-peter">
<p class="mp-two-who">By what it is</p>
<p class="mp-two-name">Delegated authority</p>
<p class="mp-two-line">"Valuable in a lot of other contexts"</p>
<p class="mp-two-line">Any time an agent acts on your behalf</p>
<p class="mp-two-line">And the other side needs proof you meant it</p>
</div>
</div>
<p class="mp-strip"><b>AP2</b><span>Strategic: disputes force the delegation to be provable. Slow to spread.</span></p>
<p class="mp-strip"><b>UCP</b><span>Tactical: cart, inventory and shipping as modules over MCP and A2A. Works today.</span></p>
<figcaption id="ap1-cap">The quotes are from the stream. The split between the two protocols is Alan's.</figcaption>
</figure>

## Approving every moment loses the flight

The host's own setup is one I'd have built too. Their agent has access to the 1Password API. When it wants something, say a passport number, it pings the vault and a notification lands on the phone. Tap, approve, done.

Alan's name for that: human present. You authorize this one action, right now. It works, until the task is longer than your attention span.

Then came the flight ticket. You set the agent searching, it does all the work, you step away from the computer. It comes back: "I'm ready to pay for this flight. Do you authorize it?" You thought you authorized it twenty minutes ago. You authorized it five different times, and it never actually bought it. So you authorize again, and now the price isn't available anymore, and the whole workflow starts over.

The blunt verdict on stage: take the agent out of the equation and you could write a script that does that. The agent isn't the slow part. The approval model is.

<figure class="fd-fig ap ap-f2" aria-labelledby="ap2-cap" data-desc="The flight-ticket loop from the stream, in five steps that light up in turn under a big label. One: the agent finds a flight. Two: it asks, do you authorize it, and you approve. Three: you step away from the computer. Four: it comes back and asks again; you had approved five times and it never bought. Five, in red: the price is no longer available and the whole workflow starts over. Underneath, the verdict from the stage: take the agent out of the equation and a script could do this.">
<p class="ea-now ea-say5" aria-hidden="true"><span>The agent finds a flight</span><span>You approve</span><span>You step away</span><span>It asks again</span><span class="ea-no">The price is gone</span></p>
<ol class="ea-rows ea-cyc5 ap-loop" aria-label="The flight ticket, step by step">
<li><b>1</b><span class="ea-who">Search</span><span>The agent does all the work of finding the flight.</span></li>
<li><b>2</b><span class="ea-who">Ask</span><span>"I'm ready to pay. Do you authorize it?" You tap yes.</span></li>
<li><b>3</b><span class="ea-who">Away</span><span>You step away from the computer.</span></li>
<li><b>4</b><span class="ea-who">Ask again</span><span>Five approvals in, it still hasn't bought.</span></li>
<li class="ea-row-no"><b>5</b><span class="ea-who">Gone</span><span>That price isn't available anymore. Start over.</span></li>
</ol>
<p class="mp-strip"><b>The verdict</b><span>Take the agent out and a script could do this.</span></p>
<figcaption id="ap2-cap">The story as it was told on the stream. Five approvals is the number given there; there's no log behind it.</figcaption>
</figure>

## Human present, human not present

The fix Alan described is the other mode, human not present. His example: "Hey, when these sneakers go on sale, if they're in your size, one of your trusted vendors, just buy them."

That sentence holds three limits (the item, your size, a set of shops) and one trigger. You approve it once, before anything happens. The agent then buys at 3 a.m. without waking you, and the shop can still tell that you agreed to exactly this.

Same thumbprint, different moment. In human-present mode you sign the purchase. In human-not-present mode you sign the limits, and the purchase is the agent's job.

<figure class="fd-fig ap ap-f3" aria-labelledby="ap3-cap" data-desc="AP2's two modes side by side. Human present: the agent asks at the moment of the action, you approve this one thing on your phone, like the host's 1Password notification for a passport number; it breaks when the task outlasts your attention. Human not present: you approve limits ahead of time, like Alan's sneakers example, buy them when they go on sale, in your size, from one of your trusted vendors; the agent acts later without asking, and the merchant can still check you agreed. Under both: the same thumbprint, at a different moment.">
<div class="mp-two-row">
<div class="mp-two-card">
<p class="mp-two-who">Human present</p>
<p class="mp-two-name">Sign the act</p>
<p class="mp-two-line">The agent asks right before it acts</p>
<p class="mp-two-line">"Can I read your passport number?"</p>
<p class="mp-two-line">Breaks when the task outlasts you</p>
</div>
<p class="mp-two-vs">vs</p>
<div class="mp-two-card mp-two-peter">
<p class="mp-two-who">Human not present</p>
<p class="mp-two-name">Sign the limits</p>
<p class="mp-two-line">You approve once, ahead of time</p>
<p class="mp-two-line">"These sneakers, on sale, my size, a shop I trust"</p>
<p class="mp-two-line">The agent buys later, without asking</p>
</div>
</div>
<p class="mp-strip"><b>Same thumbprint</b><span>Different moment.</span></p>
<figcaption id="ap3-cap">The two examples are the ones from the stream: the host's vault, Alan's sneakers.</figcaption>
</figure>

## An open mandate, then a closed one

Here's how AP2 actually does it. I read the v0.2 spec, released in April, after the stream. It's short and concrete.

A mandate is a signed digital credential, an SD-JWT, the selective-disclosure flavour of a JSON Web Token. There are two kinds: a checkout mandate (what's being bought, from whom) and a payment mandate (how much, with which card or account). Each comes in two stages.

The open mandate is what you sign. The agent drafts the limits, and a Trusted Surface shows them to you, takes your biometric and signs with your key. The spec says that surface MUST be non-agentic: the model never holds your pen. The open mandate also carries the agent's public key in a `cnf` claim, so it's bound to that one agent. A copy in anyone else's hands is useless.

The closed mandate is what the agent makes later, alone. It finds a real cart, writes the exact transaction, and signs it with its own key, the one named in your open mandate. That signature links the closed mandate back to the open one.

The limits are a list of typed constraints. Version 0.2 defines these:

- On the checkout side: `checkout.allowed_merchants` and `checkout.line_items`, with acceptable products and quantities.
- On the payment side: `payment.amount_range`, `payment.allowed_payees`, `payment.allowed_payment_instruments`, `payment.execution_date`, and the pair for repeat jobs, `payment.agent_recurrence` (say monthly, at most 12 times) with `payment.budget`, a cap on the total.
- Plus `iat` and `exp` on the open mandate, so the whole thing expires.

Stripped down, the payment side of Alan's sneakers would look something like this:

```json
{
  "vct": "mandate.payment.open.1",
  "cnf": { "jwk": "the agent's public key" },
  "constraints": [
    { "type": "payment.amount_range", "currency": "USD", "min": 0, "max": 20000 },
    { "type": "payment.allowed_payees", "allowed": ["one of your trusted shops"] }
  ]
}
```

My favourite line in the spec is the reason open mandates exist at all: "even well-behaving Agents need to have their behavior tightly constrained above what a normal authorization model would require of human users." Nobody gives a human a card that only works at three shops, under two hundred dollars, until Friday. An agent should get exactly that.

<figure class="fd-fig ap ap-f4" aria-labelledby="ap4-cap" data-desc="The chain of three signed objects in AP2, lit in turn under a big label. First, the open mandate: you sign it with your key on a trusted surface that must not be an agent; it holds the limits and the agent's public key in a cnf claim. Second, the closed mandate: the agent signs it later with the key named in the open one; it holds the exact cart and amount. Third, the receipt: the verifier signs it after checking the chain, that the open claims are unchanged, and every constraint. Underneath, the constraint types version 0.2 defines: allowed merchants, line items, amount range, allowed payees, payment instruments, execution date, recurrence and budget, plus an expiry.">
<p class="ea-now ea-say3" aria-hidden="true"><span>You sign the limits</span><span>The agent signs the purchase</span><span>The verifier signs a receipt</span></p>
<div class="ap-chain" aria-hidden="true">
<div class="ea-box ap-c1"><p class="ea-box-k">Open mandate</p><p class="ea-box-n">You</p><p class="ap-key">your key</p></div>
<span class="ap-arr">→</span>
<div class="ea-box ap-c2"><p class="ea-box-k">Closed mandate</p><p class="ea-box-n">The agent</p><p class="ap-key">its key, named in the open one</p></div>
<span class="ap-arr">→</span>
<div class="ea-box ap-c3"><p class="ea-box-k">Receipt</p><p class="ea-box-n">The verifier</p><p class="ap-key">its key</p></div>
</div>
<ol class="ea-rows ap-parts" aria-label="What each signed object holds">
<li><b>1</b><span class="ea-who">Open</span><span>The limits, an expiry, the agent's public key. Signed on a non-agentic Trusted Surface.</span></li>
<li><b>2</b><span class="ea-who">Closed</span><span>The exact cart and amount, bound to the open mandate.</span></li>
<li><b>3</b><span class="ea-who">Receipt</span><span>Success or an error, and a hash of what was checked.</span></li>
</ol>
<p class="mp-strip"><b>Limits in v0.2</b><span>Merchants, items, amount range, payees, instruments, dates, recurrence, budget.</span></p>
<figcaption id="ap4-cap">Redrawn from the spec's flows. The amounts in the code above are the spec's own example values, not a real mandate.</figcaption>
</figure>

## Three checkers, and none of them is you

In human-not-present mode, nobody asks you anything at checkout. Three other parties check instead.

The credential provider (your bank or wallet) gets both payment mandates, open and closed, verifies them and only then issues a payment token. The merchant checks the closed checkout mandate against its current cart and checks that your open limits are met. The merchant's payment processor checks that the mandates inside the token are bound to that exact checkout. Each signs a receipt.

A few rules in there are small and very good:

- An unknown constraint counts as a failure. If a checker doesn't understand one of your limits, it says no rather than skip it.
- After a successful receipt, the agent shrinks the open mandate's scope by what it just spent. That's how a budget holds across repeat purchases.
- The agent must not present overlapping mandates until a receipt comes back with an error. No double spend by racing two shops.
- When a limit can't be settled, the checker returns `unresolved_constraint` and the flow drops back to human present. You get asked, once, about the one thing that's actually new.

That last one is the flight ticket fixed. The agent doesn't come back five times. It comes back when the price moved outside what you signed.

<figure class="fd-fig ap ap-f5" aria-labelledby="ap5-cap" data-desc="Who checks what in AP2's human-not-present flow. One, the credential provider, your bank or wallet: it verifies the open and closed payment mandates, then issues a payment token. Two, the merchant: it checks the closed checkout mandate against the current cart and that the open limits are met. Three, the merchant's payment processor: it checks the mandates inside the token are bound to that checkout. Underneath, two rules: an unknown constraint counts as a failure, and when a limit can't be settled the checker returns unresolved_constraint and the person is asked again, about that one thing.">
<ol class="mp-trio">
<li><p class="mp-trio-n"><b>1</b>Your bank</p><p class="mp-trio-what">Checks both payment mandates, then issues a payment token.</p></li>
<li><p class="mp-trio-n"><b>2</b>The shop</p><p class="mp-trio-what">Checks the closed mandate against its live cart, and your open limits.</p></li>
<li><p class="mp-trio-n"><b>3</b>The processor</p><p class="mp-trio-what">Checks the mandates in the token belong to that exact checkout.</p></li>
</ol>
<p class="mp-strip"><b>Unknown limit</b><span>Counts as a fail, never as a pass.</span></p>
<p class="mp-strip ap-back"><b>Out of bounds</b><span><code>unresolved_constraint</code>: you get asked once, about the new thing.</span></p>
<figcaption id="ap5-cap">The credential provider is the spec's term; your bank or wallet is my shorthand for it.</figcaption>
</figure>

## Every approval in my fleet is human present

Then I looked at my own setup, and it's all the host's 1Password pattern.

My selling agent drives a Chrome on the Mac mini that's logged in to my resale accounts as me. It drafts every buyer reply and waits for my OK in chat before it sends. When I asked an agent to let another agent of mine send SMS from my phone, Claude Code's auto mode refused to apply the config change on its own, because it was a permission grant. It only went through once I approved it by hand. And this note will reach the site the same way. The agent that drafted it can open the pull request, but the merge is my click.

All of that is fine for now. Here's what bugs me after this talk. The logged-in browser carries my whole authority: any listing, any price, any message. My OK is a chat message that nobody downstream can check. The limits live in my head and in a prompt, not in anything signed.

It's the other half of a note I wrote yesterday, on [Chi Wang's DotSpace talk](/notes/agents-carry-requests-not-authority.html). His rule was that an agent carries your request, not your authority. AP2 is how a bounded slice of authority can travel after all: as a signed object with the limits written in, checked by whoever receives it. It's also the same idea as the gateway in my [note on enterprise agents](/notes/hope-isnt-security-enterprise-agents.html), where the keys never enter the sandbox. Here your key never touches the agent; it stays on the Trusted Surface.

What I haven't done: I haven't run AP2's samples, and v0.2 only defines checkout and payment mandates. Nothing in the spec covers "reply to buyers on this one listing, never below this price, until Sunday". That's the mandate I'd actually want, and nobody gives a format for it yet.

<figure class="fd-fig ap ap-f6" aria-labelledby="ap6-cap" data-desc="My own approvals against an AP2 mandate. My fleet today: a selling agent in a Chrome logged in to my resale accounts as me, drafting every buyer reply and waiting for my OK in chat; Claude Code's auto mode refusing to apply a permission grant until I approved it by hand; this note's pull request opened by an agent and merged only by my click. All of it human present, the limits only in my head and a prompt. A mandate: limits written down and signed once, bound to one agent, checked by whoever receives the action, and expiring on its own. Underneath, the gap: version 0.2 has no mandate for anything but checkout and payment.">
<div class="mp-two-row">
<div class="mp-two-card">
<p class="mp-two-who">My fleet, October 28</p>
<p class="mp-two-name">Ask every time</p>
<p class="mp-two-line">Buyer replies wait for my OK in chat</p>
<p class="mp-two-line">Permission grants: approved by hand</p>
<p class="mp-two-line">Merges: my click</p>
<p class="mp-two-line ap-gone">Limits: only in my head and a prompt</p>
</div>
<p class="mp-two-vs">vs</p>
<div class="mp-two-card mp-two-peter">
<p class="mp-two-who">An AP2 mandate</p>
<p class="mp-two-name">Sign once</p>
<p class="mp-two-line">Limits written down and signed</p>
<p class="mp-two-line">Bound to one agent's key</p>
<p class="mp-two-line">Checked by whoever receives it</p>
<p class="mp-two-line">Expires on its own</p>
</div>
</div>
<p class="mp-strip"><b>The gap</b><span>v0.2 defines checkout and payment mandates only.</span></p>
<figcaption id="ap6-cap">My setup on the day I wrote this. The struck line is what a mandate would replace.</figcaption>
</figure>

## Try it

The AP2 part of the stream is two minutes, starting at 5:19:25. Watch it, then read the agent authorization page of the spec. It's the clearest write-up I've seen of why agents need tighter limits than people.

If you want more:

- [The AP2 moment on the stream](https://youtu.be/eB9I4Ixx2wc?t=19165), Live from AGNTCon + MCPCon North America, day two, October 23, 2026
- [Agent Payments Protocol](https://ap2-protocol.org/), the site, with the [agent authorization](https://ap2-protocol.org/ap2/agent_authorization/) and [flows](https://ap2-protocol.org/ap2/flows/) pages
- [google-agentic-commerce/AP2](https://github.com/google-agentic-commerce/AP2), the spec and samples, Apache 2.0, v0.2.0 since April 2026
- [An agent can carry your request, not your authority](/notes/agents-carry-requests-not-authority.html), Chi Wang's rooms where agents of different owners work together
- [Hope isn't security](/notes/hope-isnt-security-enterprise-agents.html), where the keys never enter the sandbox

If you've signed an open mandate for something that isn't a purchase, tell me what the limits looked like. I'd love to see one for messages.
