Skip to main content

regent-httpsig

Verify and sign AI agent HTTP traffic in Python — the way OpenAI signs and Cloudflare verifies. RFC 9421 · Web Bot Auth · AAuth

OpenAI's agents cryptographically sign every HTTP request they make. Cloudflare, AWS WAF and Google verify those signatures. This library brings both sides of that handshake to Python: verify signed agents hitting your API, and sign your own agent's traffic so bot walls recognize it.

pip install regent-httpsig

Verify: know which AI agent is calling — in 5 lines

from fastapi import FastAPI
from regent_httpsig import HttpsigVerifier
from regent_httpsig.fastapi import attach, SignatureDep, VerifiedSignature

app = FastAPI()
attach(app, HttpsigVerifier())

@app.post("/v1/orders")
async def create_order(sig: VerifiedSignature | None = SignatureDep):
    if sig:
        print(sig.agent)    # "https://chatgpt.com"
        print(sig.keyid)    # RFC 7638 key thumbprint
    ...

No FastAPI? The core has no framework dependencies:

verifier = HttpsigVerifier()
sig = await verifier.verify(method, url, headers)   # VerifiedSignature | None

Verification is enrichment by default: no Signature header costs nothing, a bad signature yields None, and nothing ever raises on untrusted input. Use regent_httpsig.fastapi.RequiredSignatureDep when a signature must be present — the 401 tells the agent exactly how to sign.

Sign: get your agent past bot walls

from regent_httpsig import EgressSigner

signer = EgressSigner(seed=os.environ["AGENT_KEY_SEED"],
                      signature_agent="https://myagent.example")
headers = signer.sign("POST", url, {"content-type": "application/json"})
resp = httpx.post(url, json=body, headers=headers)

Generate a key and the ready-to-publish /.well-known/ files in one command:

regent-httpsig keygen --agent https://myagent.example --out ./well-known/

Publish the directory at https://myagent.example/.well-known/http-message-signatures-directory and every Web Bot Auth verifier on the internet can now identify your agent.

What exactly is verified

Check Status
RFC 9421 Appendix B.2.6 Ed25519 vector (byte-exact) ✅ in CI
Web Bot Auth draft -05 A.2.2 — sf-dictionary Signature-Agent covered with ;key= ✅ in CI¹
Web Bot Auth A.2.3 — legacy sf-string form (what OpenAI ships in production) ✅ in CI
Sign → verify roundtrip (fresh keys, full pipeline) ✅ in CI
AAuth identity-mode roundtrip (aa-agent+jwt + cnf.jwk proof of possession) ✅ in CI
Tampered request / expired signature / wrong directory key rejected ✅ in CI

¹ The signature bytes printed in the draft's own A.2.2 example do not verify over the draft's own signature base (the legacy A.2.3 vector and RFC 9421 B.2.6 both do, so the defect is in the example, not the canonicalization). Ed25519 is deterministic, so our test pins the vector re-signed with the same RFC test key over the same byte-exact base — reported upstream.

Both dialects, one verifier

  • Web Bot Auth (draft-meunier-web-bot-auth-architecture): key discovery via {Signature-Agent}/.well-known/http-message-signatures-directory. Both wire forms of Signature-Agent are accepted — the current sf-dictionary and the legacy bare sf-string OpenAI actually sends.
  • AAuth (draft-hardt-oauth-aauth-protocol, identity-based mode): the agent carries a JWT agent_token in Signature-Key; the issuer's JWKS verifies the token, the token's cnf.jwk verifies the request signature. Install with pip install 'regent-httpsig[aauth]'. For a full-protocol AAuth implementation (both roles, all token types) see christian-posta/aauth-python-library — this library is the thin relying-party verifier that handles both dialects.

Security model (what a naive implementation gets wrong)

The verifier fetches key directories from attacker-nameable origins — whoever signs a request chooses its Signature-Agent. regent-httpsig ships with the guard rails on:

  • SSRF protection by default: https-only, every resolved IP must be public (catches 169.254.169.254, loopback, private ranges, DNS names mapping to internal services), redirects never followed, responses size-capped.
  • Bounded caching: per-instance TTL cache with eviction — a keyid-spam attack can't grow memory; failures are negative-cached so a dead origin can't be used to slow you down.
  • A valid signature proves key possession — not trustworthiness. VerifiedSignature.trusted reflects only your configured allow-list; deciding whether to trust a key is your policy layer's job.

Known sharp edges of the underlying ecosystem, already handled: the upstream http-message-signatures library cannot resolve RFC 9421 ;key= dictionary members (we provide the component resolver), it looks up header names case-sensitively while ASGI frameworks lowercase them (we wrap), and it forgets to declare typing_extensions (we declare it).

Configuration

from regent_httpsig import HttpsigConfig, HttpsigVerifier

verifier = HttpsigVerifier(HttpsigConfig(
    trusted_agents=frozenset({"https://chatgpt.com", "https://operator.openai.com"}),
    max_age_hours=25,       # reject signatures created earlier than this
    cache_ttl=600,          # key-directory cache seconds
))

Pass your app's shared client to reuse its pool: HttpsigVerifier(http_client=my_async_client).

Honest limitations

  • Web Bot Auth and AAuth are IETF drafts (RFC 9421 itself is a final standard). We track the drafts; breaking draft changes land as minor releases while we're 0.x.
  • Ed25519 only for now — it's what the agent ecosystem ships.
  • Body coverage (content-digest) is verified when covered by the signature, but this library does not require it; decide per-route whether you need it.

Related projects

cloudflare/web-bot-auth (TypeScript/Rust) · christian-posta/aauth-python-library (full AAuth protocol) · pyauth/http-message-signatures (the RFC 9421 primitive this builds on)


Built and battle-tested in production by Regent Protocol — runtime control and identity for AI agents. Apache-2.0.

Release files for regent-httpsig 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for regent-httpsig 0.1.0
File Size Uploaded
regent_httpsig-0.1.0.tar.gz 24.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for regent-httpsig 0.1.0
File Interpreter ABI Platform
regent_httpsig-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 48.5 kB

Release files / regent_httpsig-0.1.0.tar.gz

Download URL regent_httpsig-0.1.0.tar.gz
Size 24.8 kB
Tags Source
SHA-256 checksum
How to use checksums
5829c334347d86d819149fc1a2a45f2b1b6f030a0f566be1ae3a2e324c2dff5c
BLAKE2b-256 checksum
How to use checksums
ec43eb5e12fce68134cdcafbb87d92a4f73336aa17d43ddb915f7edd03e94b5b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 17, 2026.

Transparency log

Release files / regent_httpsig-0.1.0-py3-none-any.whl

Download URL regent_httpsig-0.1.0-py3-none-any.whl
Size 23.7 kB
Tags Python 3
SHA-256 checksum
How to use checksums
630c49b8b9b4c52233db1c568052111db52d1d86d392db1550fcdf440eaa7723
BLAKE2b-256 checksum
How to use checksums
ee281831606627aa2b3d50ea956ad69f086f74d493f57cb3fb910aadbfeb20b6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 17, 2026.

Transparency log

Release history Release notifications | RSS feed

0.6.0

2 release files

0.5.1

2 release files

0.5.0

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

0.1.1

2 release files

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page