Manav.id
Agents ยท 17 min read

Anyone can claim to be your agent. Nothing currently stops them.

Agent traffic arrives at your server carrying a name. The name is a string in a header, and strings are free. Web Bot Auth fixes half of this properly, and the half it does not fix is the half where the money is.

The Tuesday where the traffic is polite and wrong

Picture an operations engineer at a mid-size retailer, mid-morning, coffee going cold. Something in the checkout funnel is off. Conversion looks fine, gross merchandise value looks fine, but the dispute queue has doubled in six weeks and the disputes are strange. They are not the usual pattern of stolen cards hammering a category. They are single, well-formed purchases, at sane hours, from accounts with real order histories, and the cardholder in each case says some version of the same thing: I did not buy that.

She pulls the request logs for a sample of the disputed orders. They look beautiful. Each one arrives with a user agent string naming a well known shopping assistant. Each one hits the API in the right order, respects the rate limit, sets the right headers, and completes the purchase in a way that would make an integration engineer proud. There is no burst, no rotation through a residential proxy pool, no headless browser fingerprint sticking out at an odd angle. The traffic is polite.

So she checks whether the traffic is real, which is where the afternoon disappears. The assistant's operator publishes an IP range. Some of the requests are in it. Some are not, but the operator's documentation says egress can come from cloud regions that are not enumerated. The user agent string is documented publicly, which means it is also documented publicly for everyone else, including whoever wants to type it into a script. She checks reverse DNS on a few addresses and gets a hosting provider. She checks her bot management vendor's score, and the score says the traffic is probably automated and probably fine, which is exactly what a score says.

By the end of the day she has a spreadsheet, a hypothesis, and no fact. The hypothesis is that some of this traffic is the real assistant acting for real customers, and some of it is something else wearing the same name. She cannot tell which is which, and neither can anyone else in the building, because nothing in the request was ever designed to answer that question.

Short answer: A website cannot currently verify that an AI agent is really acting for a specific customer. User agent strings and IP ranges are claims, not proofs. Web Bot Auth, built on HTTP Message Signatures (RFC 9421), does prove cryptographically which software sent a request, which is real progress. It says nothing about whether a human authorized the action. Verifying both requires the agent's signature plus a delegation chain back to the customer's own key.

What does an AI agent actually show you when it arrives?

Strip away the marketing and an agent request is an HTTP request. What it carries about its own identity, in the general case, is a short list.

It carries a user agent string, which is a self-declared name. This is the oldest identity mechanism on the web and it has never been anything other than a courtesy. Any client can send any string. The convention that crawlers identify themselves honestly worked for two decades because the incentive to lie was small: a search crawler that lied gained nothing, and a scraper that lied was usually trying to look like a browser, not like a crawler.

It arrives from an IP address, which is a fact about the network path, not about the sender's identity. Operators of large agents publish address ranges so that servers can allowlist them. That helps, and it fails in both directions. It fails open when an operator's egress moves, when it uses shared cloud infrastructure, or when the published list is stale. It fails closed when a legitimate agent runs from a customer's own device or a region not on the list.

It may appear on a published list, a crawler directory or a verified bot program run by a content delivery network. Being listed proves that a name was registered by someone. It does not prove that the request in front of you came from the party who registered it.

The pattern across all three is the same, and once you see it you cannot stop seeing it. Every one is a claim: a statement that costs nothing to produce and nothing to copy. The server accepts it because there is no cheaper option, and everyone involved has quietly agreed to pretend a claim is a proof.

The hotel wristband problem

Think of an all-inclusive resort where guests wear a paper wristband. The wristband is not identification. It is a token that says the wearer is entitled to the buffet. It works because forging one is socially awkward rather than technically hard, and because the worst outcome is that somebody eats a free lunch.

Now imagine the same wristband entitles the wearer to charge purchases to a room. The wristband has not changed. Its forgery cost has not changed. What changed is the value of forging it, and the moment that value crosses the cost, the wristband stops being a courtesy and becomes an attack surface. That transition is where agent identity is right now.

Why is this different from the old bot problem?

The industry has been managing automated traffic for twenty years and has a mature toolkit for it: rate limiting, challenge pages, behavioural scoring, IP reputation, device signals. Imperva's annual bad bot reporting has for several years put automated traffic at roughly half of all requests on the web, so nobody in the field is surprised by the existence of bots. The reasonable question is why this needs a new answer at all.

The answer is that the consequence of a wrong decision has changed category.

A scraper that gets through costs you bandwidth, some database load, and possibly the commercial value of your content. It is a cost line. You mitigate it with statistics, and statistics are the right tool, because being wrong on any single request is cheap. Blocking a real user occasionally is annoying. Letting a scraper through occasionally is a rounding error.

An agent that gets through transacts. It buys something, cancels something, changes a shipping address, redeems a balance, opens a support ticket that moves money, or accepts terms on someone's behalf. Each of those is a discrete event with a dollar value and a person attached to it. Being wrong on a single request is no longer a rounding error; it is a chargeback, a refund, an angry customer, and in aggregate a liability question nobody has settled. We wrote about the dispute side of this in the chargeback evidence problem for agentic purchases, and it is the same root cause seen from the finance team's chair.

So the shift is not that bots got smarter. It is that the decision you are making about them changed from should I serve this content to should I execute this instruction. Probabilistic tools are appropriate for the first question and structurally inadequate for the second. You do not want a score on whether to move money. You want a fact.

What does Web Bot Auth actually prove?

Here is the good news, and it deserves to be stated properly rather than as a throat-clearing exercise before a pitch.

Web Bot Auth is a serious piece of engineering that solves a real problem correctly. It builds on RFC 9421, HTTP Message Signatures, a published IETF standard that defines how to sign selected components of an HTTP request: the method, the target path, specific headers, a content digest, a timestamp, a nonce. The sender signs those components with a private key. The receiver fetches the corresponding public key and verifies the signature. If it verifies, the receiver knows two things with certainty: the request was produced by a holder of that private key, and the signed components were not modified in transit.

Cloudflare has driven adoption of this pattern for agent and crawler traffic, publishing the approach and the directory mechanics on its engineering blog. Reported interest and adoption span payment networks and platforms including Visa, Mastercard, Shopify and Vercel, which is a meaningful signal because those are exactly the parties who will bear the cost when agent traffic goes wrong.

What this replaces is important. It replaces a claim with a proof. Before Web Bot Auth, "I am assistant X" was a string. After it, "I am assistant X" is a signature that only assistant X's key could have produced. That is a genuine improvement and every server that handles agent traffic should support it. Nothing in the rest of this article argues otherwise.

What a signed agent request looks like

Concretely, the request carries something along these lines. The exact component set varies by profile, and the shape is what matters here.

POST /api/v1/checkout HTTP/1.1
Host: shop.example.com
Content-Digest: sha-256=:qq7mMRbGPTAOTnMEAcHOJ5Lp6VqOTNfkq0k5Zx3sAJ0=:
Signature-Input: sig1=("@method" "@authority" "@path" \
    "content-digest" "signature-agent");\
    created=1789012345;keyid="assistant-x-2026-03";alg="ed25519"
Signature: sig1=:Zx9K2mBq7v1sVQ0oP4tR8eLwN3cYhJgU6dF5aS2iM1nX...:
Signature-Agent: "https://assistant-x.example/.well-known/http-message-signatures-directory"

Your server fetches the key directory named in Signature-Agent, finds the key with the matching keyid, verifies the signature over the listed components, and now has a cryptographic fact: this request came from assistant X. Not a guess. A fact.

So what does Web Bot Auth not prove?

Read the fact again, slowly, because the gap lives inside it.

This request came from assistant X.

That is the entire claim. It is a claim about software. It contains no assertion whatsoever about a human being. Specifically, it does not tell you:

Consider the attack that this leaves completely open, and note that it involves no forgery of any kind. An attacker phishes a customer's credentials for the agent platform, or steals the session, which is a thoroughly solved problem from the attacker's side, as we covered in the piece on session theft and adversary in the middle kits. The attacker then logs into the real assistant, as the real customer, and tells it to buy things and ship them elsewhere.

Every request that follows is generated by the genuine assistant, signed with the genuine platform key, from the genuine IP range, at a sane rate, with impeccable headers. Web Bot Auth verifies perfectly, because there is nothing wrong with the agent. The agent is behaving correctly. It is doing exactly what it was told by someone holding the customer's credentials.

The verification passed and the answer was still wrong, because the question was never asked. You verified the pen. You did not verify the person holding it.

The courier analogy, and where it stops

A courier arrives at your loading dock in a marked van, wearing a uniform, carrying a scanner that authenticates to the depot. You are confident about the courier. Verifying the courier is a solved problem and Web Bot Auth is a very good uniform.

The courier hands you a collection note that says: release the pallet. Your confidence in the courier tells you nothing about whether the pallet's owner asked for it to be released. Those are two different questions, answered by two different documents. Every mature logistics operation figured this out long ago, which is why release authority is a signed instruction from the owner rather than a property of the person collecting.

The agent ecosystem has built an excellent uniform and has not yet built the collection note.

Will an agent registry solve it?

The instinctive next move, and the one the market is currently making, is a registry: a directory of approved agents, with identity vetting, a reputation score, and a liability framework attached. Payment networks are building these, as are on-chain proposals such as ERC-8004, and a set of vendors now market Know Your Agent services in the same shape as Know Your Customer.

Registries are useful and they should exist. They are also the wrong layer for this specific problem, for a reason with a long history.

A registry answers is this agent allowed to operate. It is a statement about the software's standing in the world. Certificate authorities answer the equivalent question for websites, and the model works, within known limits: the trust is transitive, it is only as good as the weakest issuer, and compromise at the top is catastrophic because everything below inherits the compromise. A registry of agents inherits every one of those properties. Compromise a platform key or bribe an insider at a listed operator, and the registry now vouches for the attacker with full confidence.

More fundamentally: no registry entry can answer did this human ask for this, because the human is not a party to the registry. The registry knows about vendors. The question is about customers. You cannot answer a question about one population by consulting a directory of a different population, no matter how well maintained the directory is.

This is the contrarian claim of the piece, and it is worth stating flatly. The scalable answer to rogue agents is not a better list of who is allowed to be a bot. It is a receipt from the human each request claims to serve.

How do you verify both halves?

The two questions are independent, so they need two artifacts, and the pleasing part is that they compose without either one changing.

QuestionArtifact that answers itWhat it provesWhat it cannot prove
Which software sent this?RFC 9421 signature (Web Bot Auth)The request came from a holder of the platform's key, unmodifiedAnything about a human
Is this agent allowed to operate?Registry entry or verified bot programSomeone vetted and listed this operatorThat this request reflects a customer's intent
Whose human authorized this?Delegation chain to an enrolled human keyA specific human signed a scope that covers this actionThat the human's judgment was sound
Is the traffic anomalous?Bot management scoreA probability, useful for triageAny fact about a specific request

A delegation is a signed object. The human, using a key on a device they hold, signs a statement naming the agent's key, the actions permitted, the constraints, and the validity window. The agent then signs each action under that delegation. A verifier walks the chain back to the human's key and checks, at every hop, that scope only narrows and never widens, that the chain is not deeper than permitted, that nothing has expired, and that no link has been revoked. The mechanics are covered properly in the delegation chain post, and the wider question of enumerating what your agents may currently do is the authority graph problem.

The composed request

In practice the two artifacts sit side by side. The RFC 9421 headers stay exactly as they are. A delegation header carries the human-anchored chain, or a reference to it plus a per-action signature under it.

POST /api/v1/checkout HTTP/1.1
Host: shop.example.com
Content-Digest: sha-256=:qq7mMRbGPTAOTnMEAcHOJ5Lp6VqOTNfkq0k5Zx3sAJ0=:

# Half one: which software sent this
Signature-Input: sig1=("@method" "@authority" "@path" "content-digest")
Signature: sig1=:Zx9K2mBq7v1sVQ0oP4tR8eLwN3cYhJgU6dF5aS2iM1nX...:
Signature-Agent: "https://assistant-x.example/.well-known/..."

# Half two: whose human authorized it
Delegation: chain="https://receipts.example/d/8fc21a";
    action-sig=:Yb3nQ8xK1pR7vD2wE9tL5mC0aH4jS6uZ...:

The delegation object itself is small and boring, which is the point.

{
  "delegationId": "8fc21a",
  "humanKey": "ed25519:9c4b...e17a",
  "delegateKey": "ed25519:2f80...bb31",
  "scope": {
    "actions": ["checkout.purchase"],
    "constraints": {
      "maxAmount": "250.00",
      "currency": "USD",
      "merchants": ["shop.example.com"],
      "shipTo": ["addr_7731"]
    }
  },
  "notBefore": "2026-09-10T08:00:00Z",
  "notAfter":  "2026-09-17T08:00:00Z",
  "maxChainDepth": 2,
  "revocationId": "rv_51c9",
  "signature": "ed25519:..."
}

And the check the merchant runs, in outline:

def authorize(req):
    # 1. Which software? Standard RFC 9421 verification.
    if not verify_http_signature(req):
        return DENY("agent signature invalid")

    # 2. Whose human? Walk the chain offline against a published key.
    chain = fetch_or_read(req.headers["Delegation"])
    if not verify_chain(chain, root=known_human_key(req.account)):
        return DENY("no valid delegation to this account holder")

    # 3. Is THIS action inside what the human actually signed?
    if not scope_covers(chain.scope, req.action, req.amount, req.ship_to):
        return DENY("action outside delegated scope")

    if expired(chain) or revoked(chain):
        return DENY("delegation no longer valid")

    return ALLOW(receipt=chain.receipt_id)

Note what step three does, because it is the step that makes the whole exercise worth the trouble. It is not asking whether the customer is generally comfortable with agents. It is asking whether this purchase, at this amount, to this address, falls inside a boundary the customer signed. An attacker with the customer's platform credentials can instruct the agent all day. Unless they hold the customer's device key, they cannot produce a delegation, and they cannot widen one that exists.

What does this do to the dispute conversation?

The operations engineer from the opening has a second problem she has not reached yet: her chargeback evidence has quietly become worthless. The fields merchants submit in a dispute are device fingerprint, IP address, session history and navigation path. When an agent transacts, every one of those was generated by the agent, so the merchant is submitting a description of software as proof of a human's intent.

A delegation receipt is a different kind of evidence. It was not generated by the merchant, so it is not the merchant's word, and it was signed by the cardholder's own key before the transaction, naming the boundary the cardholder set. An issuer verifies it offline without trusting either party. Whether issuers accept such an artifact is an open question, and the honest answer is that they mostly have not been asked yet. That argument gets settled alongside the human presence gap in AP2 over the next two years.

Who wins the coming policy fight?

There is a three-way argument building about agent traffic and it is worth being honest that all three parties have a legitimate case.

Publishers and merchants want to distinguish agents so they can charge, rate limit or block them, because the economics of an ad-supported or conversion-supported page do not survive a reader who never sees the page. Agent operators want access on behalf of their users, on the view that they are a user's tool no different in principle from a browser. Users want the thing they asked for to happen, without being told the way they chose to browse is illegitimate, and without their agent becoming a new way to be defrauded. All three positions are reasonable.

Most proposals serve one party at the expense of the others. Blocking serves publishers. Open access serves operators. What is interesting about human-anchored delegation is that it is one of the few designs that gives each party something they specifically need. The publisher gets a fact about intent rather than a probability, which is what they actually need for the transactional requests they care about. The operator gets a credential that earns access instead of arguing for it. The user gets a boundary they set themselves, and a receipt when it is used.

It also has a property worth noticing: the human in the chain is a public key, not a name. The merchant learns that a specific accountable party authorized a specific action within limits. It does not learn who they are beyond what the transaction already requires. Anchoring is not identification.

What this does not fix

Five limits, stated plainly, because a control whose limits you do not know is a control you will misapply.

It requires the verifier to adopt it. A delegation nobody checks protects nobody. This is the classic two-sided problem and it will not be solved by argument alone; it will be solved by a small number of high-value verifiers requiring it for a small number of high-value actions, and the rest following the gravity.

Manav has not shipped Web Bot Auth composition. What exists today is delegation chains with offline verification. The header profile described above is a proposal, not a product, and describing it otherwise would be exactly the kind of claim this article is complaining about.

It does nothing about a human who authorizes something harmful. If the customer genuinely signs a delegation for a purchase they later regret, the receipt proves they authorized it. That is the correct outcome, and it is not fraud prevention. Proof of intent is not a substitute for judgment.

It does not cover browse traffic, and should not try. Requiring an anchored delegation for reading a product page would be absurd, expensive and hostile. The design only makes sense at the point of commitment: purchases, transfers, changes to account shape, anything irreversible. Everything else stays exactly as it is.

A compromised human device defeats it. The chain roots in a key on a device. If that device is fully compromised, the attacker signs. The control raises the attacker's cost from "phish a password" to "compromise a specific endpoint", which is a large and worthwhile jump, and it is not infinity.

What to do this week

  1. Count your agent traffic honestly. Segment requests by declared user agent and by whether they carry an RFC 9421 signature. Most teams have never looked and are surprised by the ratio.
  2. Turn on Web Bot Auth verification for the agents that support it. It is the cheapest real improvement available and it is a standard, not a vendor feature.
  3. Write down your commitment endpoints. Not every route. The ones that move money, change an address, redeem a balance, or accept terms. In most systems this is fewer than twenty endpoints and nobody has ever listed them.
  4. Check what your dispute evidence actually contains for orders placed by agents. If every field was generated by the agent, you have found the problem described above, and you have found it before your issuer does.
  5. Ask your agent platform partners what they carry about the user. Not what they know internally. What travels with the request, in a form you can verify without calling them.
  6. Try the composition on one endpoint. The agent demo shows the delegation and verification path, and the docs cover the chain format. One endpoint, one action class, one week.
  7. Decide your fail mode in advance. When a delegation is absent or stale on a commitment endpoint, do you fail open or closed? Decide it deliberately, in daylight, rather than discovering your default during an incident.

Frequently asked questions

What is agent spoofing? Agent spoofing is when a request falsely presents itself as coming from a known AI agent, usually by copying a documented user agent string and, where possible, originating from an address range that looks plausible. Because those identifiers are public and free to copy, the claim costs nothing to make. The point of cryptographic agent identity is to convert that claim into something only the real operator can produce.

Does Web Bot Auth stop rogue agents? It stops impersonation of the agent, which is real and valuable. It does not stop a genuine agent being driven by the wrong person. An attacker who compromises a customer's account on the agent platform produces requests from the real agent, signed with the real key, which verify perfectly. Web Bot Auth answers which software sent the request, not whether a human authorized the action.

How can a website verify that an AI agent is really acting for a customer? Verify two things, not one. First, the agent's request signature under RFC 9421, which proves which software sent it. Second, a delegation chain signed by the customer's own enrolled key, which proves a specific human authorized a specific scope, and that this action falls inside it. Agent identity without human anchoring only tells you which platform signed.

What is Know Your Agent? Know Your Agent describes vendor services and registry programmes that vet agent operators and list them, by analogy with Know Your Customer. It establishes that an operator has standing. It is useful for accountability and liability, and it structurally cannot answer whether an individual request reflects a particular customer's intent, because customers are not parties to the registry.

Will an agent registry solve rogue agent impersonation? Only partially, and it inherits the certificate authority failure modes. A registry vouches for operators, so a compromised platform key or an insider at a listed operator makes the registry vouch for the attacker. Registries are worth building for accountability. They are the wrong layer for proving that a specific human asked for a specific action.

Does adding a delegation check slow down every request? It should not be applied to every request. Verification is a signature check plus a chain walk, typically sub-millisecond and offline against a published key with no callback, but the design intent is to gate commitment endpoints only. Browse and read traffic stays untouched. Anchoring belongs where the action is irreversible.

Sources

  1. RFC 9421, HTTP Message Signatures, IETF. The standard underlying Web Bot Auth.
  2. Web Bot Auth, Cloudflare engineering blog. Approach, key directories, and adoption.
  3. Imperva Bad Bot Report. Annual measurement of automated share of web traffic.
  4. Cloudflare Radar. Public traffic and bot composition data.
  5. Agent Payments Protocol (AP2) specification. Mandate structures for agent-initiated payments.
  6. Visa newsroom. Announcements covering the Trusted Agent Protocol and agent commerce programmes.
  7. Mastercard newsroom. Announcements covering Agent Pay.
  8. Riskified research blog. Consumer sentiment research on agent-initiated purchasing.
Verifying the agent tells you which pen wrote the instruction. It does not tell you whose hand was holding it.