Skip to content

CONCEPT Cited by 1 source

HTTP Message Signatures (RFC 9421)

HTTP Message Signatures (published as RFC 9421 in 2024) is an IETF standard for attaching one or more cryptographic signatures over a canonical representation of an HTTP request or response, carried in the Signature, Signature-Input, and optionally Signature-Agent headers. The signature is computed over an explicitly-listed set of covered fields — chosen headers, pseudo-headers like @authority / @method / @path, and optional metadata (created / expires / nonce / keyid / alg / tag) — in a canonicalization Cloudflare and any other verifier will reproduce identically on the receive side.

Header shape

Signature-Agent: "https://signature-agent.example.com"
Signature-Input: sig2=("@authority" "signature-agent")
 ;created=1735689600
 ;keyid="poqkLGiymh_W0uP6PZFw-dvez3QJT5SolqXBCW38r0U"
 ;alg="ed25519"
 ;expires=1735693200
 ;nonce="e8N7S2MFd/qrd6T2R3tdfAuuANngKI7LFtKYI/vowzk4lAZYadIX6wW25MwG7DCT9RUKAJ0qVkU0mEeLElW1qg=="
 ;tag="web-bot-auth"
Signature: sig2=:<base64url bytes>:
  • Multiple signatures supported per message via labelled signatures (sig1, sig2, …).
  • Algorithm-agilealg= field carries the signature algorithm; Ed25519, RSA, ECDSA all permitted.
  • Covered fields is an ordered list — any omitted field is not authenticated, so picking them is a security-posture decision.
  • Replay protection via created/expires timestamp window + nonce (random per request).
  • Tag disambiguates the deployment context — different systems using RFC 9421 signatures set different tag values so a signature valid in one context can't be replayed to authenticate in another.

Properties worth knowing

  • Stateless verification on receive. Verifier needs only the signer's public key, the covered fields, the canonicalization algorithm, the timestamp, and the nonce. No server-side state per active client — unlike session cookies / bearer tokens with a server-side session store.
  • Per-request signatures are cheap with Ed25519. Signing and verifying Ed25519 are sub-ms on commodity hardware; RFC 9421 imposes no per-connection state or handshake — just the header overhead and the signature cost.
  • Canonicalization footguns. The covered-field canonicalization is finicky — any intermediary that rewrites a header (adds whitespace, changes case, reorders) breaks the signature. In practice you pick covered fields that intermediaries don't touch (@authority, explicit static headers).
  • Key distribution is out-of-band. RFC 9421 doesn't standardize how the verifier finds keys; deployments typically publish a JWK (RFC 7517) directory at a well-known URL referenced from Signature-Agent or keyid — this is exactly what Cloudflare's Web Bot Auth does.

Canonical wiki instance: Web Bot Auth

Cloudflare's Web Bot Auth uses RFC 9421 to give bots / crawlers a cryptographic identity that origin servers can verify. Every request carries signature-agent pointing at the bot operator's JWK directory + signature-input / signature authenticating the request. Tag is set to web-bot-auth to disambiguate. Downstream feature pay-per-crawl then uses that verified identity to bill the correct crawler.

Seen in

Last updated · 200 distilled / 1,178 read