SWAgent Pass
Early release

Sites block anonymous agents. Give yours a passport.

Airlines, banks and marketplaces are turning AI agents away because they cannot tell a helpful assistant from abuse. Agent Pass is the honest fix: your agent signs each request with a key it controls, the site checks who is calling, and decides what that agent may do. No disguises, no fake browsers.

The line we hold: this does not get an agent past a block it was not invited through. It gives sites a standard way to say yes to agents that identify themselves, and gives agent builders something concrete to ask sites for. It uses Web Bot Auth, an open IETF draft that Cloudflare documents support for.

How it works

1. The agent signs

Each request carries three headers: Signature-Agent (where its public key lives), Signature-Input and Signature (an Ed25519 signature over the host and the key location, valid for minutes, with a one time nonce).

2. The site verifies

It fetches the agent's key directory, matches the key, checks the signature, the time window and that the nonce was never seen. Then it applies its own rules: read only, rate limits, or a licence.

3. The site stays in control

Unidentified traffic gets a clear machine readable 403 that says how to identify. Identified agents get what the site decides. A site can revoke any agent at any time.

Live demo

A stand in "site" at /demo/protected runs the real verifier. The demo agent below signs with a real Ed25519 key. Press a button and read the actual headers and response.

Add it to your stack

Agent side: sign requests

import { signRequest } from "./webbotauth.js"; // /webbotauth.js, plain WebCrypto, no dependencies const headers = await signRequest("https://shop.example/prices", "https://my-agent.example", privateJwk); const res = await fetch("https://shop.example/prices", { headers });

Host your public key at https://my-agent.example/.well-known/http-message-signatures-directory as a JWKS (content type application/http-message-signatures-directory+json). This demo's own directory is here.

Site side: verify

import { verifyRequest } from "./webbotauth.js"; const v = await verifyRequest({ authority: url.host, headers }, { getDirectory, seenNonce }); if (!v.ok) return new Response(JSON.stringify({error:"agent_not_identified"}), {status:403});

Or call the hosted check: POST /api/verify with {"url":"...","headers":{...}}. Policy summary at /api/v1/policy. Source for both functions is one file: /webbotauth.js.

Limits you should know