AIDR 0.2.1 · open source · RFC 9421
Anyone can type a User-Agent.Nobody can copy a private key.
AIDR gives each real agent its own key and an accountable organisation behind it. Every request is signed, and any server can check it offline.
The problem
Everything a scraper sends can be copied, except one thing
| What your server sees | Can a scraper copy it? |
|---|---|
| User-Agent string | Yes. It's a text field. |
| IP address | Often. Agents run on the same shared cloud and serverless ranges scrapers use. |
| A real agent's signed headers | Yes, once. Each nonce is single-use, so the copy is refused. |
| The agent's private key | No. It's made on the agent's machine and never sent. |
Live, in this tab
Run the handshake
Real Ed25519 keys and real RFC 9421 signatures, made by your browser's WebCrypto. Then try to cheat.
The private key is created non-extractable and never leaves this tab. To keep the demo small, the verifier trusts this tab's public key directly; the real one also checks the agent's 15-minute credential from the registry and the revocation list. The Explorer runs those checks.
Architecture
Who talks to whom
The registry is never asked about a single request, and keeps no record of where an agent goes. If the revocation list goes 11 minutes without a refresh, verifiers refuse agents instead of trusting stale data.
Install
Five lines on the server, a few in the agent
Requests without agent headers pass straight through, unless you mark a route verified-only. People are never affected.
import { aidr } from '@evoliv/aidr-verifier'; app.use(aidr({ issuer: 'https://api.evolivcore.com', publicOrigin: 'https://api.example.com', mode: 'verified-only', verifiedOnlyPaths: ['/api/.*'] })); // req.aidr.status: 'anonymous' | 'verified'; req.agent names the agent and its company
from aidr_agent import Agent from aidr_agent.langchain import aidr_http_tools agent = Agent.load_or_enroll("research-01", audiences=["https://api.example.com"]) tools = aidr_http_tools(agent) # http_get / http_post, every request signed
Also: Go and Python verifiers; plugins for Cloudflare Workers, Amazon API Gateway, Kong and WordPress; LlamaIndex and Vercel AI SDK tools; and one setting that speaks Web Bot Auth in Cloudflare's format.
Before you ask
The questions we expect in the comments
Does this stop scraping?
No. It lets you tell an accountable agent from anonymous traffic. Unsigned requests you handle as you do today: rate-limit, challenge or block. What changes is that you can stop punishing the agents that identify themselves.
Why not mTLS?
TLS usually ends at a CDN or load balancer, so the app behind it never sees the client certificate. A signature over the HTTP message survives proxies, and each one carries a single-use nonce and a timestamp, so a captured request can't be sent again.
Isn't a registry just a central point of control?
It is the one central piece, and today one operator runs it. It issues credentials and a signed revocation list; it is never called per request. Every line that decides whether an agent gets in is open source (Apache-2.0), and the Node, Python and Go verifiers must agree on one public test suite.
How does this relate to Web Bot Auth?
AIDR works with it. Same foundation, RFC 9421 signatures, and one setting makes AIDR agents sign in Cloudflare's Web Bot Auth format. What AIDR adds: a verified organisation behind each key, revocation everywhere in about two minutes, and a tamper-evident audit trail. RFC 9421 is a published standard; Web Bot Auth is still an IETF draft.
Does it work for agents I run at home?
Yes. The key is generated on your machine and the signature doesn't depend on your IP. The agent is enrolled under an organisation that proved it owns a domain, because that is what a site owner gets to see.