AI agent signature check
Find out whether an AI agent signs its requests, and whose key signed them.
By Emissar. Updated .
1. Create a test link
Give the link to the agent you want to check, for example: "Open this link and tell me what the page says." Each request that reaches it is checked for a Web Bot Auth signature, the way a website could check it. The link works for 24 hours and records up to 20 requests.
2. Requests to your link
This list refreshes every few seconds while the page is open. A request can take up to a minute to appear.
No requests yet. Give the link to your agent and keep this page open.
What a verified signature proves
It proves that a holder of a key published in the signer's key directory signed this request's method, host and path, and its body when the signature covers the body, within the last few minutes. A site can rely on that to tell a signed agent from anything that only copies its User-Agent.
It doesn't prove who operates the agent, whether it acts for the person it says it does, or whether it should be trusted. Those are decisions for the site. Emissar's Verify module makes them for businesses behind Front Door: known providers, each business's own allow and block lists, history, and an allow, ask-for-more-proof or refuse verdict.
A request without a signature proves nothing either way. Most AI agents don't sign yet, and some sign only part of their traffic.
Agents that sign their requests
These agents publish keys that the check recognizes by name. Any other agent that signs under the draft's rules is checked too, and shown by the host that publishes its keys.
| Agent | Operator | Keys published at | Notes |
|---|---|---|---|
| ChatGPT Work cloud browser | OpenAI | chatgpt.com | OpenAI's help center says ChatGPT Work's cloud browser signs its outbound requests as https://chatgpt.com. Its key directory gives each key an expiry about a week ahead. |
| Google-Agent | agent.bot.goog | Google calls this experimental and signs only some Google-Agent requests, so an unsigned Google-Agent request is normal. Its keys are named by short ids instead of thumbprints; Emissar accepts that for Google-Agent only. | |
| Cloudflare Browser Run | Cloudflare | web-bot-auth.cloudflare-browser-rendering-085.workers.dev | Hosted browsers that many companies' agents run in. Cloudflare signs every Browser Run request, so a valid signature proves the request came from Browser Run, not which customer's agent sent it. |
| Browserbase | Browserbase | www.browserbase.com | Hosted browsers for agents. Signing is in beta and switched on per customer, so most Browserbase traffic is unsigned. A valid signature proves the request came from a Browserbase session, not which customer's agent sent it. |
| EmissarBot | Emissar | emissar.ai | Emissar's crawler. Emissar's free tools don't sign. |
What the check requires
The profile of draft-ietf-webbotauth-httpsig-protocol that Emissar's Front Door enforces, applied to every request that reaches your link.
| Rule | What passes | Source |
|---|---|---|
| Signature fields | Signature and Signature-Input, with one signature tagged web-bot-auth. Signatures with another tag are ignored, as the draft says. | draft §5.2, §5.4 |
| Freshness | created and expires are required. created may be at most 5 minutes old and at most a minute in the future, and expires must not have passed. | draft §5.2, §6.9 |
| What it covers | @authority (or @target-uri) and the Signature-Agent header must be covered. When content-digest is covered too, the digest must match the body, and the result says the body is covered. | draft §5.2; RFC 9530 |
| Who signed | Signature-Agent names the signer's https origin. The key is looked up in the key directory at /.well-known/http-message-signatures-directory on that origin. | draft §5.5 |
| Which key | keyid must be the key's JWK SHA-256 thumbprint. One exception, for Google-Agent only: its keys are named by short ids, and the id must match exactly. | draft §5.5; RFC 7638 |
| Algorithm | Ed25519, ECDSA P-256 and P-384, and RSA-PSS. HMAC is refused. The algorithm must agree with the key. | RFC 9421 §3.3; draft §6.4 |
How it works
- The signature check is the same code that checks callers at Emissar's Front Door. Everything in the request is checked before anything is fetched.
- To find the key, Emissar fetches the signer's key directory: https only, public domain names on port 443, no redirects, 5 seconds, 64 KB and at most 50 keys. Directories are cached for up to an hour, as their Cache-Control allows.
- EmissarBot's own key is built in, so its signatures are checked without fetching emissar.ai.
- Your link answers every request with a short page stating the result, so an agent can read the result back to you.
- Each link records up to 20 requests. Later requests still get their result page but aren't recorded. Creating links is rate limited per IP address, like the other tools.
API
The page uses these public endpoints. A test link accepts any method, so you can also send it a signed POST with a body.
# Create a test link (kept for 24 hours)
curl -s -X POST https://emissar.ai/api/tools/agent-check
# Open it the way an agent would (this request is unsigned)
curl -s https://emissar.ai/agent-check/LINK_ID
# Read the requests recorded on it
curl -s https://emissar.ai/api/tools/agent-check/LINK_IDSign your own agent's requests
Generate an Ed25519 key, publish its public half in a key directory at /.well-known/http-message-signatures-directory on your agent's own domain, and sign each request with the components above. How EmissarBot signs walks through its headers and key directory as a worked example, and the Web Bot Auth and HTTP Message Signatures entries explain the terms. Then send your agent to a test link here to confirm a site can verify it.
Limitations
- It sees only what reaches emissar.ai. An agent that won't open unfamiliar links, or that signs only some of its requests, can look unsigned here and signed elsewhere.
- A verified signature from an agent not in the table above is shown by the host that publishes its keys. That host's owner controls the key, but nothing more about it is known.
- The check reads only signatures tagged
web-bot-authwith key directories. Other ways agents identify themselves, such as IP ranges or mutual TLS, aren't checked. - Key directories must follow the draft: served from the signer's origin without a redirect, as a key set. Shopify's isn't:
shopify.comredirects towww.shopify.com, which serves a single key, so Shopify's signatures show as couldn't-check here. - Anyone with your link can send requests to it, and anyone with the results address can read them, until the link expires.
Privacy
For each request to your link we store the time, the method, the User-Agent it sent, its Signature-Agent header and the result of the check, including the key's thumbprint and the components it covered. We don't store IP addresses, other headers or request bodies. Links and their requests are deleted automatically 24 hours after the link is created.
As with any request to this site, Cloudflare processes IP addresses to deliver and protect it. Details are in the trust center and the privacy policy.
Related
- How agent identity gets verified, for how signatures fit with Agent Cards and credentials.
- Know your agent, for what sites do with a verified signature.
- Agent Card validator, which verifies the other kind of agent signature: a signed Agent Card.
Sources
- RFC 9421: HTTP Message Signatures
- draft-ietf-webbotauth-httpsig-protocol: HTTP Message Signatures for automated traffic (IETF Web Bot Auth working group)
- RFC 9530: Digest Fields (Content-Digest)
- RFC 7638: JSON Web Key (JWK) Thumbprint
- OpenAI: ChatGPT Work cloud browser
- Google: Google-Agent
- Cloudflare: Cloudflare Browser Run
- Browserbase: Browserbase