On June 30, AWS quietly shipped something more important than another benchmark: a Web Bot Auth preview inside Amazon Bedrock AgentCore Browser, built with Cloudflare, Akamai, and HUMAN Security. The pitch is simple—sign your agent's requests with a private key, publish the public key at a well-known URL, and sites can wave you through without a single CAPTCHA. Meanwhile, the other half of the industry is still shipping custom Chromium forks that spoof navigator.webdriver and rotate residential proxies to look human. Both approaches are chasing the same goal. Only one of them survives the next detection update.
Fingerprint spoofing is a game you can only tie, never win—every signal you fake is a signal a detector can eventually check twice. A cryptographic signature is different in kind: without the private key, there's nothing to fake. That's why Cloudflare, Fingerprint, and now AWS are converging on the same primitive—HTTP Message Signatures (RFC 9421), the spec underneath Web Bot Auth. Here's what's actually inside a signed request, and how to verify one yourself.
The three pieces
A signed agent identity is just three things: an Ed25519 keypair, a public directory, and a signature over specific parts of each request.
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey
from cryptography.hazmat.primitives import serialization
private_key = Ed25519PrivateKey.generate()
public_key = private_key.public_key()
raw_public = public_key.public_bytes(
encoding=serialization.Encoding.Raw,
format=serialization.PublicFormat.Raw,
)
The public key gets published at /.well-known/http-message-signatures-directory as a JWK, keyed by a keyid. Any site your agent visits can fetch it, cache it, and check requests against it—no handshake, no shared secret.
Signing a request
RFC 9421 doesn't sign the whole request—it signs a chosen set of components (method, authority, and a digest of the body are typical), wrapped in a Signature-Input header:
import time, base64
def build_signature_base(method: str, authority: str, created: int) -> str:
return (
f'"@method": {method}\n'
f'"@authority": {authority}\n'
f'"@signature-params": ("@method" "@authority");'
f'created={created};keyid="agent-key-01";alg="ed25519"'
)
created = int(time.time())
base = build_signature_base("GET", "example.com", created)
signature = private_key.sign(base.encode())
headers = {
"Signature-Input": f'sig1=("@method" "@authority");created={created};keyid="agent-key-01";alg="ed25519"',
"Signature": f"sig1=:{base64.b64encode(signature).decode()}:",
}
Every field a verifier needs—which components were signed, which key, when—travels in plaintext headers. Nothing is hidden; the trust comes from the math, not obscurity.
Verifying it on the receiving end
If you run a site and want to let signed agents through, verification is the mirror image: fetch the claimed key from its directory, rebuild the same signature base, check it against the raw Signature bytes.
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey
from cryptography.exceptions import InvalidSignature
def verify_request(public_key_bytes: bytes, base: str, sig_b64: str) -> bool:
pub = Ed25519PublicKey.from_public_bytes(public_key_bytes)
try:
pub.verify(base64.b64decode(sig_b64), base.encode())
return True
except InvalidSignature:
return False
A request that passes this check didn't just look legitimate—it was signed by a key you can trace back to a named agent operator. That's a strictly stronger guarantee than "the fingerprint looked human this time."
Where Anchor fits
This is also why we signed Anchor up for Cloudflare's Verified Bots program and Fingerprint's Authorized AI Agent Detection ahead of this: every Anchor session already signs outbound traffic under our published key, so sites that check for Web Bot Auth see a verified agent, not a guess. If you're building your own signer against a non-Anchor stack, the code above is the whole mechanism—there's no vendor lock-in to the standard itself.
Stealth still buys you a few quarters. Signed identity is the thing detection vendors are building toward, and it doesn't decay the way a fingerprint patch does.
Start a free Anchor session and see your agent's traffic verified by default, or read the Anchor documentation to wire signing into your own stack.



