Web Bot Auth is an IETF draft that lets a bot or agent prove who it is with a cryptographic signature on each request, instead of a User-Agent string anyone can copy. It is built on HTTP Message Signatures (RFC 9421). OpenWAF Browsers signs the requests of every browser by default.
What a signed request carries
Chrome's own headers and User-Agent are unchanged. Three headers are added:
Signature-Agent: "https://browsers.openwaf.dev"
Signature-Input: sig1=("@authority" "signature-agent");created=1761732000;keyid="…";alg="ed25519";expires=1761732300;nonce="…";tag="web-bot-auth"
Signature: sig1=:…:| Header | Meaning |
|---|---|
Signature-Agent | Who signs: the origin https://browsers.openwaf.dev, where the public key is published. |
Signature-Input | What is signed and how: the host of the request (@authority) and the Signature-Agent header, an Ed25519 key (alg="ed25519"), the key id (its RFC 7638 JWK thumbprint), a creation time, an expiry 5 minutes later, a random nonce and the tag web-bot-auth. |
Signature | The Ed25519 signature over those components. |
The headers are added inside the browser to every HTTP and HTTPS request it makes: page loads, frames, subresources, fetch and XHR. WebSocket connections and requests made internally by service workers may not carry them.
Key directory
The public key is published as a JSON Web Key Set at:
https://browsers.openwaf.dev/.well-known/http-message-signatures-directoryIt is served with the media type application/http-message-signatures-directory+json:
{"keys": [{"kty": "OKP", "crv": "Ed25519", "x": "…", "kid": "…"}]}The kid matches keyid in Signature-Input.
Verify it on your site
A site that wants to recognise OpenWAF Browsers, to allow it, rate-limit it separately or simply count it:
- Read
Signature-Agentand check it is"https://browsers.openwaf.dev". - Fetch the key directory (cache it; it rarely changes) and pick the key whose
kidequalskeyid. - Rebuild the signature base from
@authority(the request's host, lowercase, without a default port), theSignature-Agentvalue and theSignature-Inputparameters, as RFC 9421 describes, and verify the Ed25519 signature. - Reject it if
expiresis in the past, or ifcreatedis too far in the future. Optionally remember nonces to refuse replays.
Libraries that implement Web Bot Auth verification do steps 2 to 4 for you. Sites behind OpenWAF already check Web Bot Auth signatures as one of the bot verification methods of AI Crawl Control.
A valid signature tells you the request came from a browser run by OpenWAF Browsers. It does not tell you which customer runs it, and it does not mean the request is welcome: what to do with it is your decision.
Turn it off
We recommend keeping it on. A signed request is honest about being automated, so sites can let it in on purpose instead of guessing, and a site that blocks it has made a clear choice you should respect. Some sites will treat signed agents better than anonymous traffic.
If you have a reason to turn it off:
For one browser: start it with
"webBotAuth": false:curl -sS -X POST https://browsers.openwaf.dev/v1/browsers \ -H "X-API-Key: $OPENWAF_BROWSERS_KEY" -H "Content-Type: application/json" \ -d '{"webBotAuth": false}'As the organization's default: an admin turns off Web Bot Auth in Browsers → Settings, sends
PATCH /v1/orgs/{org}/browsers/settingswith{"web_bot_auth": false}, runsopenwaf-cloud ctl browsers settings --web-bot-auth off --reason "…", or uses thebrowser_settingsMCP tool. New browsers are then unsigned unless they ask for"webBotAuth": true.
Turning signing off does not make a browser stealthy: it is still unmodified Chrome with its own User-Agent, from OpenWAF's addresses. See what it is not.