Poppy: The Personal Agent Protocol
Poppy inverts who the agent belongs to — and the whole cost of that inversion lands on your session model, not on your JSON file.
Every agent protocol that shipped in the last eighteen months asks how a buyer's agent pays you. The Personal Agent Protocol — "Poppy", announced by Sierra and Meta on 6 October 2026 — asks something no merchant integration has had to answer before: how does a stranger's agent sign in as one of your customers? Answering it costs you a session that begins with nobody in it and acquires an identity mid-flight, a pseudonym you are structurally forbidden from joining with anyone else's, and an authorization check that can no longer live where you put it. The discovery file takes an afternoon. The session model is the project.
Step 1What actually shipped, and how fast it is still moving.
Sierra and Meta announced Poppy on 6 October 2026 and published a draft of the specification on 9 October, alongside a set of design partners that third-party trackers counted at roughly 35 companies. It is a draft, and it is moving at draft speed: SDK releases dated 18 October describe themselves as targeting draft 0.2, while published examples have already carried a protocol_version of 0.3. All of those numbers are a month old as of late October 2026, and at least one of them will be wrong by the time you read this.
That is not a complaint, it is the first engineering instruction. A protocol in its first month has no stable version number to code against, so do not code against one. Poppy's own answer — and the reason this essay treats it as a well-designed draft rather than an unfinished one — is that the authoritative statement of what a company supports is the discovery document it serves, not the revision string in the spec you happened to read. Read the document at request time, branch on the fields it contains, and treat an unrecognised protocol_version as a reason to re-read rather than to abort. That is the same feature-test discipline covered in capability discovery and negotiation, and Poppy is the strongest argument for it yet: this is a protocol where the version bumped twice in nine days.
Step 2The well-known file points the other way round.
A company that supports Poppy publishes a JSON document at /.well-known/poppy.json. It declares how an agent starts a session, which sign-in methods and scopes the company offers, and which routes are available — a conversational endpoint, a set of APIs, or a website session the agent drives directly.
Compare that with the well-known file the agent ecosystem already had. A2A's agent card at /.well-known/agent.json says I am an agent, here is what I can be asked to do — see agent cards and discovery. Poppy's document says I am a company, here is how someone else's agent may act here on behalf of one of my users. The direction of the advertisement is reversed, and that single reversal is what makes Poppy a different kind of standard rather than another dialect of the same one. An agent card is a service description. A poppy.json is an admissions policy.
The practical consequence shows up immediately in how you version it. A service description can afford to be generous, because the worst case of over-advertising a capability is a failed call. An admissions policy that over-advertises is a security finding: every route you list is a route a third party will drive with your own customer's authority attached. List the narrowest set you have actually hardened, and treat adding a route to that file as a change that needs the same review as shipping a public API — which, as of the moment you publish it, is what it is.
Step 3The session starts signed out, and that is the load-bearing decision.
Here is the mechanic that reorganises your backend. In Poppy an agent opens a session before anyone has proved who they are, and sign-in attaches a company account to that already-running session afterwards. The agent can browse, ask, price and plan as an anonymous visitor, and then — if the user approves it — become a known customer in the middle of the same conversation.
Almost every authenticated API you have ever built does the opposite. It authenticates at connection setup, mints a token that encodes the principal, and then lets every downstream handler assume a principal exists because the connection could not have been established without one. Poppy breaks that assumption at the only place it was ever load-bearing: your authorization check cannot live at session construction, because at session construction there is no one to authorize.
# the shape Poppy forces: principal is a property of the turn, not the socket session = poppy.open(company="acme.example") # no user yet. legitimately. session.ask("do you ship to Lisbon?") # anonymous route: must work grant = session.sign_in(scopes=["poppy:read"]) # identity arrives mid-session def handle(action, session): # WRONG: session.user was captured when the socket opened # RIGHT: re-read the principal and the grant on every action principal = session.principal_now() if principal is None and action.needs_identity(): raise NeedsSignIn(action.required_scopes) return policy.check(principal, grant, action).run()
Two bugs follow from getting this wrong, and they fail in opposite directions. Capture the principal once and an action taken after sign-out — or after a different account signs in on the same session — executes with a stale identity; that is the confused-deputy shape described in confused deputy. Refuse to serve anything until sign-in and you have broken the protocol's whole premise, because the anonymous phase is where a personal agent does most of its work and the user has no reason to hand over an account to ask about shipping times.
Step 4Two scopes, a reserved prefix, and why that pushes risk down to the action.
Poppy's standard permission vocabulary is deliberately tiny: poppy:read and poppy:write. Sign-in grants whichever of them the user approved, and the poppy: prefix is reserved — you may not mint poppy:refunds or poppy:transfer. Companies express anything finer as custom scopes under their own naming, and published examples do exactly that, pairing poppy:read with a domain scope such as addresses.
It is worth being precise about what a two-value standard vocabulary can and cannot carry, because the temptation is to read it as an oversight. It is not. A standard scope set has to mean the same thing at every company that publishes it, and "write" is the most that can mean the same thing at a retailer, a bank and an airline simultaneously. Any attempt to standardise poppy:purchase across those three would either be so vague as to be unreviewable or so specific as to be wrong for two of them.
What it does mean is that the grant cannot express risk, so the action has to. A single poppy:write covers updating a delivery address and cancelling a subscription, and the user who approved it was shown one checkbox. If your policy layer reads the scope and stops, you have just given every write the ceiling of your most dangerous write. The fix is the one this site argues for throughout: score the operation, not the grant, and let the score decide whether it runs, needs a confirmation, or is refused outright — risk-scored permissions and auto-approval and allowlists both work unchanged on top of a coarse grant, and a coarse grant is the only kind you are going to get.
A useful audit question for an existing product: list every mutation your public surface exposes, then ask which of them you would be comfortable running on the strength of one checkbox labelled "allow this agent to make changes". Everything on the uncomfortable list needs its own gate below the scope check, and it needed one before Poppy existed.
Step 5The per-company pseudonym is a privacy property with an engineering bill.
A Poppy session carries a user identifier that is stable at one company and different at every other, so two companies cannot discover that they are talking to the same person by comparing the identifiers their agents presented. That is a real and uncommon privacy design — it makes cross-company correlation a thing the protocol structurally does not supply, rather than a thing a policy document asks everyone not to do.
It also deletes a key you are probably using. Three systems break in predictable ways. Identity resolution: you cannot use the agent-side identifier as a global customer key, because it is not one; it joins to your own account only, and only after sign-in. Fraud and abuse scoring: cross-merchant reputation signals about a specific end user are unavailable through this channel by construction, which means your velocity checks and your device signals have to carry the weight that shared identity used to. Support and dispute handling: when a customer calls to ask why their address changed, the artefact that connects a human to an action is the sign-in event, not the session — so log the grant, its scopes, its time, and the action ids taken under it, as described in delegated access and consent records.
And one asymmetry worth naming, because it is easy to feel more protected than you are. The pseudonym stops companies correlating a user across each other. It does nothing to stop the agent correlating, since the agent is the one party that holds every pseudonym at once and knows which human they belong to. Poppy moves the join from the merchant side to the agent side; whether that is an improvement depends entirely on who you think should hold it, which is the question the principal-agent problem is about and not one a specification can settle.
Step 6There is no payment story, and that is the tell.
The draft covers identity, sign-in, sessions and scopes. Payment is named as future work. Read next to the protocols it is filed beside, that absence is the most informative thing in the document.
Of the four standards a commerce team is now asked to evaluate, three are about the instrument. The Agentic Commerce Protocol (OpenAI and Stripe, released under Apache 2.0 on 29 September 2025, versioned spec 2026-04-17) carries a Delegated Payment Spec in which a one-time token is minted with a maximum chargeable amount and an expiry and handed to the merchant. The Universal Commerce Protocol (Google and Shopify, announced 11 January 2026) has the merchant publish its capabilities and reaches AP2 for mandates. AP2 itself is not a commerce protocol at all but an authorization layer that models intent, cart and payment as verifiable credentials — see AP2 and agent commerce. Each of them has to answer "who may be charged, and up to how much", because each of them assumes the agent is a buyer.
Poppy has no answer because it never makes that assumption. It is the only one of the four in which the agent is the user's delegate rather than the platform's buyer, and a delegate has no instrument of its own to present. The payment gap is not an unfinished chapter; it is where the protocol stops, correctly, at the edge of a question that needs an instrument holder. The four-way layer map and the decision of which to implement first is the argument in three of them answer how an agent pays.
If you are deciding what to build this quarter: publish poppy.json last, not first. Do the three things it exposes you to, in order — make every read route work for an unauthenticated session, move the authorization check from session setup to the individual action, and put a risk gate under poppy:write so a single approved checkbox cannot reach your most dangerous mutation. A company that has done those three is one file away from supporting Poppy, and is also measurably safer against the third-party agents already logging in as your users without any protocol at all.