Amazon and Meta spent this month arguing in public about an AI agent that would not say who it was. Visa's Trusted Agent Protocol proposes the fix: the agent signs its identity into the request itself, using RFC 9421 HTTP Message Signatures, the same mechanism as Web Bot Auth. A store either reads that signature or it cannot tell a named shopping agent from a scraper using its name.
So we tested it. We took a random 300-store sample of the 1,102 Shopify storefronts in our September study and sent each one the same request twice over: once carrying a real Ed25519 signature identifying us, once carrying nothing. Our public key is published, so any of these merchants can check their own logs and confirm the request was ours.
What we found
- Not one store in 295 treated an identified agent better than an anonymous one. Zero. The signature changed nothing anywhere.
- Not one store in 295 declares a policy for signed identity in robots.txt, llms.txt or agents.md. Where stores name agents at all, they name user-agent strings, which any client can copy.
- 97% served the signed request normally, so sending one is safe today. It is simply ignored.
- 3% gate anonymous agents behind bot management, with no way for a legitimate agent to identify itself past the gate.
- Two stores refused our signed requests while serving anonymous ones in the same burst. Both sit behind the same bot-management vendor. We could not separate the signature from our own accumulated request reputation as the cause, so we are not naming them.
The honest reading is not that these merchants did something wrong. It is that the infrastructure to treat agents differently has not arrived, while the agents have. Every store in this sample is one rule away from being able to say "this one is Amazon's, let it through faster, and challenge everything that will not identify itself." None of them can say it today.
What a signed agent request actually looks like
There is no mystery to it. Three headers, the third of which is covered by the signature so it cannot be swapped:
signature-agent: "https://agentshoppable.com"
signature-input: sig1=("@method" "@authority" "@path" "signature-agent");created=..;expires=..;keyid="<JWK thumbprint>";alg="ed25519";tag="web-bot-auth"
signature: sig1=:<base64>:
The verifier fetches the key directory at the URL in signature-agent, finds the key whose thumbprint matches keyid, rebuilds the signature base from the request it actually received, and checks the signature. If the method, host, path or claimed identity differs at all from what was signed, it fails. That is the whole mechanism, and it is why a signature is worth something where a user-agent string is not.
How we tested it, and what we refused to claim
A signature test is easy to get wrong, because a store's bot protection can refuse the second request of a burst for reasons that have nothing to do with the signature. So the probe sends four requests per path in the order unsigned, signed, signed, unsigned: the two anonymous controls bracket the two signed requests, each signature is freshly minted so a refusal cannot be a replay rejection, and a difference counts only if both controls agree with each other and both signed requests agree with each other. Anything else is reported as untestable rather than as a finding about the merchant.
The guard earned its keep
An earlier run of this sample, using a weaker three-request order, produced two stores that appeared to refuse signed requests cleanly. We could not reproduce either once the same vendor began challenging our address outright — at which point even our unsigned requests were refused, which meant the original ordering could not separate the signature from where the request sat in the burst. Those two are in the published data, unnamed, and the aggregate numbers do not depend on them. We rewrote the probe before publishing rather than after.
Each store was tested on two surfaces: its catalog endpoint and one product page. Transport failures disqualify a probe outright — a network fault of ours is never reported as a merchant's behaviour.
What this means if you run a store
- Nothing is broken today. 97% of stores serve signed requests without incident. You do not have an outage; you have an absence.
- If you run bot protection, you currently cannot make an exception for a legitimate agent. Your gate sees a client with no browser fingerprint and treats Amazon's shopping agent exactly like a scraper. That is the thing to fix first, and it is a rule at your edge, not a change to your store.
- State a policy where a machine can read it. robots.txt, llms.txt or agents.md. Naming user-agent strings is better than nothing, but any client can send any user-agent; a signature is checkable.
- Decide it deliberately. Whichever way you go — admit identified agents, rate-limit them, or refuse them — the default is currently deciding for you.
Per-store results, CC BY 4.0: identity-2026-09.csv. Sample of 300 drawn with a fixed seed from the 1,102 stores in the September study; 295 were still reachable Shopify storefronts on 28 September 2026. Method notes in the data README. Our own policy for agents that identify themselves is at /agents.md.
Can an agent shop your store?
The same engine that produced these numbers runs against your storefront, including the identity checks. Free, about a minute, one test cart created and cancelled.
Scan my store