HTTP Message Signatures for automated traffic
draft-meunier-webbotauth-httpsig-protocol-01
This document is an Internet-Draft (I-D).
Anyone may submit an I-D to the IETF.
This I-D is not endorsed by the IETF and has no formal standing in the
IETF standards process.
| Document | Type | Active Internet-Draft (individual) | |
|---|---|---|---|
| Authors | Thibault Meunier , Sandor Major | ||
| Last updated | 2026-08-05 | ||
| Replaces | draft-meunier-web-bot-auth-architecture | ||
| RFC stream | (None) | ||
| Intended RFC status | (None) | ||
| Formats | |||
| Stream | Stream state | (No stream defined) | |
| Consensus boilerplate | Unknown | ||
| RFC Editor Note | (None) | ||
| IESG | IESG state | I-D Exists | |
| Telechat date | (None) | ||
| Responsible AD | (None) | ||
| Send notices to | (None) |
draft-meunier-webbotauth-httpsig-protocol-01
Web Bot Auth T. Meunier
Internet-Draft Cloudflare
Intended status: Standards Track S. Major
Expires: 7 February 2027 Google
6 August 2026
HTTP Message Signatures for automated traffic
draft-meunier-webbotauth-httpsig-protocol-01
Abstract
This document describes a protocol for identifying automated traffic
using [HTTP-MESSAGE-SIGNATURES]. The goal is to allow automated HTTP
clients to cryptographically sign outbound requests, allowing HTTP
servers to verify their identity with confidence.
It defines the Signature-Agent header field for in-band key
discovery, a key directory format based on JWKS, and a well-known URI
at which that directory is served.
About This Document
This note is to be removed before publishing as an RFC.
The latest revision of this draft can be found at
https://thibmeu.github.io/http-message-signatures-directory/draft-
meunier-webbotauth-httpsig-protocol.html. Status information for
this document may be found at https://datatracker.ietf.org/doc/draft-
meunier-webbotauth-httpsig-protocol/.
Discussion of this document takes place on the Web Bot Auth Working
Group mailing list (mailto:web-bot-auth@ietf.org), which is archived
at https://mailarchive.ietf.org/arch/browse/web-bot-auth/. Subscribe
at https://www.ietf.org/mailman/listinfo/web-bot-auth/.
Source for this draft and an issue tracker can be found at
https://github.com/thibmeu/http-message-signatures-directory.
Status of This Memo
This Internet-Draft is submitted in full conformance with the
provisions of BCP 78 and BCP 79.
Internet-Drafts are working documents of the Internet Engineering
Task Force (IETF). Note that other groups may also distribute
working documents as Internet-Drafts. The list of current Internet-
Drafts is at https://datatracker.ietf.org/drafts/current/.
Meunier & Major Expires 7 February 2027 [Page 1]
Internet-Draft HTTP Message Signatures for Bots August 2026
Internet-Drafts are draft documents valid for a maximum of six months
and may be updated, replaced, or obsoleted by other documents at any
time. It is inappropriate to use Internet-Drafts as reference
material or to cite them other than as "work in progress."
This Internet-Draft will expire on 7 February 2027.
Copyright Notice
Copyright (c) 2026 IETF Trust and the persons identified as the
document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal
Provisions Relating to IETF Documents (https://trustee.ietf.org/
license-info) in effect on the date of publication of this document.
Please review these documents carefully, as they describe your rights
and restrictions with respect to this document. Code Components
extracted from this document must include Revised BSD License text as
described in Section 4.e of the Trust Legal Provisions and are
provided without warranty as described in the Revised BSD License.
Table of Contents
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 4
2. Motivation . . . . . . . . . . . . . . . . . . . . . . . . . 5
2.1. Objectives and constraints . . . . . . . . . . . . . . . 5
2.2. HTTP layer choice . . . . . . . . . . . . . . . . . . . . 6
3. Conventions and Definitions . . . . . . . . . . . . . . . . . 6
4. Identifiers and Trust Model . . . . . . . . . . . . . . . . . 6
4.1. The Signature-Agent URL is the identifier . . . . . . . . 7
4.2. Rotation . . . . . . . . . . . . . . . . . . . . . . . . 7
4.3. When no URL is sent . . . . . . . . . . . . . . . . . . . 8
4.4. What the URL endorses . . . . . . . . . . . . . . . . . . 8
4.5. Binding a key to a Web origin . . . . . . . . . . . . . . 8
4.6. Out of scope . . . . . . . . . . . . . . . . . . . . . . 9
5. Protocol Overview . . . . . . . . . . . . . . . . . . . . . . 9
5.1. Deployment Models . . . . . . . . . . . . . . . . . . . . 9
5.2. Generating HTTP Message Signature . . . . . . . . . . . . 9
5.2.1. Signature-Agent . . . . . . . . . . . . . . . . . . . 10
5.2.2. Multiple signatures . . . . . . . . . . . . . . . . . 11
5.2.3. Anti-replay . . . . . . . . . . . . . . . . . . . . . 12
5.2.4. Additional headers . . . . . . . . . . . . . . . . . 12
5.2.5. Sending a request . . . . . . . . . . . . . . . . . . 13
5.3. Requesting a Message signature . . . . . . . . . . . . . 13
5.4. Validating Message signature . . . . . . . . . . . . . . 14
5.5. Key Distribution and Discovery . . . . . . . . . . . . . 14
5.5.1. Directory format . . . . . . . . . . . . . . . . . . 16
5.5.2. Key rotation . . . . . . . . . . . . . . . . . . . . 16
Meunier & Major Expires 7 February 2027 [Page 2]
Internet-Draft HTTP Message Signatures for Bots August 2026
5.5.3. Redistributed key material . . . . . . . . . . . . . 17
5.5.4. Signature-Key header . . . . . . . . . . . . . . . . 17
5.6. Session considerations . . . . . . . . . . . . . . . . . 17
6. Security Considerations . . . . . . . . . . . . . . . . . . . 18
6.1. Use of TLS . . . . . . . . . . . . . . . . . . . . . . . 18
6.2. Performance Impact . . . . . . . . . . . . . . . . . . . 18
6.3. Nonce validation . . . . . . . . . . . . . . . . . . . . 18
6.4. Key Compromise Response . . . . . . . . . . . . . . . . . 19
6.5. Shared Secrets Considered Harmful . . . . . . . . . . . . 19
6.6. Key Reuse Considered Harmful . . . . . . . . . . . . . . 19
6.7. Reverse proxy consideration . . . . . . . . . . . . . . . 19
6.7.1. Signature-Agent labeling . . . . . . . . . . . . . . 20
6.8. Server-Side Request Forgery (SSRF) . . . . . . . . . . . 20
6.9. Test and Demonstration Keys . . . . . . . . . . . . . . . 21
6.10. Static Signatures . . . . . . . . . . . . . . . . . . . . 21
6.11. Discovery Failure . . . . . . . . . . . . . . . . . . . . 21
6.12. Unsigned requests . . . . . . . . . . . . . . . . . . . . 22
7. Privacy Considerations . . . . . . . . . . . . . . . . . . . 22
7.1. Public Identity . . . . . . . . . . . . . . . . . . . . . 22
7.2. No Human Correlation . . . . . . . . . . . . . . . . . . 22
7.3. Minimizing Tracking Risks . . . . . . . . . . . . . . . . 22
7.4. Directory content and access patterns . . . . . . . . . . 23
8. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 23
8.1. Well-Known 'http-message-signatures-directory' URI . . . 23
8.2. Media Types . . . . . . . . . . . . . . . . . . . . . . . 23
8.2.1. "application/http-message-signatures-directory+json"
media type . . . . . . . . . . . . . . . . . . . . . 23
9. References . . . . . . . . . . . . . . . . . . . . . . . . . 24
9.1. Normative References . . . . . . . . . . . . . . . . . . 24
9.2. Informative References . . . . . . . . . . . . . . . . . 26
Appendix A. Use cases and what they need . . . . . . . . . . . . 27
Appendix B. Validating the domain binding . . . . . . . . . . . 28
B.1. Possession proof on the directory response . . . . . . . 29
B.2. What the binding attaches to . . . . . . . . . . . . . . 30
Appendix C. Deployment Guidance . . . . . . . . . . . . . . . . 30
C.1. Verifier Outcomes . . . . . . . . . . . . . . . . . . . . 30
C.2. Directory Availability . . . . . . . . . . . . . . . . . 30
C.3. Bounded Directory Fetches . . . . . . . . . . . . . . . . 30
C.4. Cache Behaviour . . . . . . . . . . . . . . . . . . . . . 31
C.5. Negative Caching and Retry . . . . . . . . . . . . . . . 31
C.6. Freshness and Replay . . . . . . . . . . . . . . . . . . 31
C.7. Field compression . . . . . . . . . . . . . . . . . . . . 31
C.8. Directory Response Signature Lifetimes . . . . . . . . . 32
C.9. Rollout and Fallback . . . . . . . . . . . . . . . . . . 32
C.10. Proxies and Intermediaries . . . . . . . . . . . . . . . 32
C.11. CORS . . . . . . . . . . . . . . . . . . . . . . . . . . 33
C.12. Deployment Anti-Patterns . . . . . . . . . . . . . . . . 33
Appendix D. Examples . . . . . . . . . . . . . . . . . . . . . . 33
Meunier & Major Expires 7 February 2027 [Page 3]
Internet-Draft HTTP Message Signatures for Bots August 2026
D.1. Delegation and chaining . . . . . . . . . . . . . . . . . 33
D.2. Multiple signatures with a remote browser . . . . . . . . 33
Appendix E. Test Vectors . . . . . . . . . . . . . . . . . . . . 34
E.1. RSASSA-PSS Using SHA-512 . . . . . . . . . . . . . . . . 34
E.1.1. Signature-Agent absent from the request . . . . . . . 35
E.1.2. Signature-Agent included present on the request . . . 35
E.1.3. Legacy Signature-Agent, sf-string . . . . . . . . . . 36
E.2. EdDSA Using Curve edwards25519 . . . . . . . . . . . . . 37
E.2.1. Signature-Agent absent from the request . . . . . . . 37
E.2.2. Signature-Agent included present on the request . . . 38
E.2.3. Legacy Signature-Agent, sf-string . . . . . . . . . . 39
Appendix F. Implementations . . . . . . . . . . . . . . . . . . 40
F.1. Clients . . . . . . . . . . . . . . . . . . . . . . . . . 40
F.2. Servers . . . . . . . . . . . . . . . . . . . . . . . . . 41
F.3. Test vectors . . . . . . . . . . . . . . . . . . . . . . 41
Acknowledgments . . . . . . . . . . . . . . . . . . . . . . . . . 41
Changelog . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41
Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 44
1. Introduction
Agents are increasingly used in business and user workflows,
including AI assistants, search indexing, content aggregation, and
automated testing. These agents need to reliably identify themselves
to origins for several reasons:
1. Regulatory compliance requiring transparency of automated systems
2. Origin resource management and access control
3. Protection against impersonation
4. Service level differentiation between human and automated traffic
Current identification methods such as IP allowlisting, User-Agent
strings, or shared API keys have significant limitations in security,
scalability, and manageability. This document defines a protocol
enabling agents to cryptographically identify themselves using
[HTTP-MESSAGE-SIGNATURES]. It proposes that every request from bots
be signed by a private key owned by its provider. This way, every
origin can validate the service identifier. Section 4 defines what
that identifier is and what validation it establishes.
Meunier & Major Expires 7 February 2027 [Page 4]
Internet-Draft HTTP Message Signatures for Bots August 2026
2. Motivation
There is an increase in agent traffic on the Internet. Many agents
choose to identify their traffic today via IP Address lists and/or
unique User-Agents. This is often done to demonstrate trust and
safety claims, support allowlisting/denylisting the traffic in a
granular manor, and enable sites to monitor and rate limit per agent
operator. However, these mechanisms have drawbacks:
1. User-Agent, when used alone, can be spoofed meaning anyone may
attempt to act as that agent. It is also overloaded - an agent
may be using Chromium and wish to present itself as such to
ensure rendering works, yet it still wants to differentiate its
traffic to the site.
2. IP blocks alone can present a confusing story. IPs on cloud
plaforms have layers of ownership - the platform owns the IP and
registers it in their published IP blocks, only to be re-
published by the agent with little to bind the publication to the
actual service provider that may be renting infra. Purchasing
dedicated IP blocks is expensive, time consuming, and requires
significant specialist knowledge to set up. These IP blocks may
have prior reputation history that needs to be carefully
inspected and managed before purchase and use.
3. An agent may go to every website on the Internet and share a
secret with them like a Bearer from [OAUTH-BEARER]. This is
impractical to scale for any agent beyond select partnerships,
and insecure, as key rotation is challenging and becomes less
secure as the consumers scale.
Using well-established cryptography, we can instead define a simple
and secure mechanism that empowers small and large agents to share
their identity.
2.1. Objectives and constraints
This protocol has two objectives:
1. Continuity of bot trust, so that an origin can tell it is dealing
with the same party it dealt with before.
2. Optional binding to another anchor, such as a domain.
It works under two constraints:
1. Preserve the simplicity of usage for bots, and the simplicity of
action for websites.
Meunier & Major Expires 7 February 2027 [Page 5]
Internet-Draft HTTP Message Signatures for Bots August 2026
2. Require no pre-established relationship between the two.
The second constraint is what rules out shared secrets and per-site
onboarding. The first is a statement about operational cost on both
ends: a site today greps its logs for an IP address and a User-Agent,
and with this protocol it greps for a handle it can verify.
2.2. HTTP layer choice
This protocol operates solely at the HTTP layer. It allows
signatures to be generated and verified without modifying the
transport layer or TLS stack. It enables flexible deployment across
proxies, gateways, and origin servers, and aligns with existing
tooling and infrastructure that already inspect and manipulate HTTP
headers.
Because the signature is embedded in the request itself, it travels
with the message through intermediaries, preserving end-to-end
verifiability even when requests are forwarded or transformed within
the HTTP layer.
3. Conventions and Definitions
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
"SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and
"OPTIONAL" in this document are to be interpreted as described in
BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all
capitals, as shown here.
The following terms are used throughout this document:
*User* An entity initiating requests through an agent. May be a
human operator or another system.
*Agent* An orchestrated user agent (e.g. Chromium, CURL). It
implements the HTTP protocol and constructs valid HTTP requests
with [HTTP-MESSAGE-SIGNATURES] signatures.
*Origin* An HTTP server receiving signed requests that implements
the HTTP protocol and verifies [HTTP-MESSAGE-SIGNATURES]
signatures. It acts as a verifier of the signature as defined by
[HTTP-MESSAGE-SIGNATURES].
4. Identifiers and Trust Model
This section defines the identifiers produced by this protocol and
what a verifier can conclude from a valid signature.
Meunier & Major Expires 7 February 2027 [Page 6]
Internet-Draft HTTP Message Signatures for Bots August 2026
4.1. The Signature-Agent URL is the identifier
An Agent identifies itself with the HTTPS URL it publishes its keys
at, carried in Signature-Agent (Section 5.2.1). A verifier resolves
that member value (Section 5.5) and checks the signature against the
keys it returns. The identifier is the URL the verifier fetched,
which for a directory member is the well-known URI rather than the
value the client sent. What the verifier ends up with is a pair:
that URL, and a key the URL provides. Origins can log, rate limit,
allowlist, or block the URL the way they do IP addresses and User-
Agent today.
The URL on its own carries nothing. A client picks the value it
sends, so an unresolved Signature-Agent is a claim rather than an
identity. It becomes an identifier once the verifier fetches it and
finds that it provides a key that verifies the request (Section 4.4).
Until then, verifiers MUST NOT attach policy to it.
A valid signature over a resolved URL proves that the request came
from a holder of a key that URL publishes, and that requests with the
same URL come from holders of keys that URL publishes. Section 5.2.3
bounds reuse. It says nothing about who operates the Agent, whether
the Agent is benign, or whether the request is authorized. Those are
origin policy.
Nothing stops an Agent from abandoning a URL and standing up another
one, and the protocol does not try to prevent this. It targets
honest clients that want to be recognised across requests.
4.2. Rotation
Because the identifier is the URL and not the key, an Agent can
rotate keys without losing continuity. It publishes the new key
alongside the old one, then drops the old one (Section 5.5.2). The
URL does not change, so a verifier that recognised it before still
recognises it after. No name and no third party are involved.
keyid selects which key verifies a given request. Verifiers cannot
use it to carry continuity across a rotation, as that value is
derived from the key material.
[SIGNATURE-KEY] takes a different approach, where a long-lived key
signs short-lived delegated keys. Deployments MAY use it. This
document does not define rotation that way.
Meunier & Major Expires 7 February 2027 [Page 7]
Internet-Draft HTTP Message Signatures for Bots August 2026
4.3. When no URL is sent
Signature-Agent is RECOMMENDED but not required. Without it, a
verifier has only the key, and the identifier is the keyid thumbprint
defined in Section 5.2. Verification still works, provided the
verifier already holds that key.
This mode has no rotation. A new key is a new identifier, and the
verifier has no way to connect the two.
4.4. What the URL endorses
Resolving a Signature-Agent URL over TLS establishes that the host
named in the URL served this key set at fetch time. Whoever controls
that URL says this key signs for it. That is what makes the URL
usable as an identifier, and all it gives you. It does not say that
the operator of that URL is honest, or that is is the same party
everyone knows about.
What matters is the association between a URL and the keys published
there. A verifier that already holds the keys does not need to fetch
it. A verifier MUST NOT attribute a request to a Signature-Agent URL
unless it made this ssociation. This can be either by resolving the
URL itself, at request time or ahead of it, or from Section 5.5.3.
Verifiers may refetch a URL to handle up key additions and removals,
bounded by Appendix C.4.
Where a verifier obtains the same pair from more than one source, the
newer pair wins, including when it omits a key that older resolution
included. Pairs are ordered by when they were produced, not when the
verifier obtained them: the created parameter for a directory
response signature (Appendix B), and the time of the fetch for a
directory the verifier resolved itself.
4.5. Binding a key to a Web origin
A well-known URL is a special case of the above. When a Signature-
Agent value resolves through the directory type (Section 5.5), the
identifier is still the URL, but that URL now names a domain rather
than an arbitrary path on one. [WELLKNOWN-URI] reserves the path, so
the domain operator stands behind the key set.
In practice, this is meant to allow additional information to be
carried against a name. That mechanism lives in Appendix B. A
verifier that wants to use this case may also recognise the shape of
the URL and apply those checks itself.
Meunier & Major Expires 7 February 2027 [Page 8]
Internet-Draft HTTP Message Signatures for Bots August 2026
4.6. Out of scope
This protocol does not authenticate human users, does not provide
anonymous authentication, and does not define authorization or
delegation. It does not define how trust is accrued, held, or
exchanged, and it defines no mechanism for one origin to convey an
opinion about an Agent to another. See Section 7.
A client has a choice whether to sign its requests, and an origin has
a choice how it treats signed and unsigned requests. Multiple
factors could influence either decision, but the decisions themselves
are outside the scope of this document.
5. Protocol Overview
+--------+ +---------+ +----------+
| | | | Exchange | |
| | | |<===== Cryptographic =====>| |
| | | | material | |
| User +--- Request -->| Agent | | Origin |
| | | +--- Request + Signature -->| |
| | | |<-------- Response --------+ |
| |<-- Response --+ | | |
| | | | | |
+--------+ +---------+ +----------+
A User initiates an action requiring the Agent to perform an HTTP
request. The Agent constructs the request, generates a signature
using its signing key, and includes it in the request as defined in
Section 3.1 of [HTTP-MESSAGE-SIGNATURES] along with the Signature-
Agent header for discovery of its verification key. Upon receiving
the request, the Origin ensures it has the verification key for the
Agent, validates the signature, and processes the request if the
signature is valid.
5.1. Deployment Models
Signature verification can be performed either directly by origins or
delegated to a fronting proxy. Direct verification by origins
provides simplicity and control. Proxy verification offloads
processing and enables shared caching across multiple origins. The
choice depends on traffic volume and operational requirements.
5.2. Generating HTTP Message Signature
[HTTP-MESSAGE-SIGNATURES] defines components to be signed.
Agents MUST include at least one of the following components:
Meunier & Major Expires 7 February 2027 [Page 9]
Internet-Draft HTTP Message Signatures for Bots August 2026
@authority as defined in Section 2.2.3 of [HTTP-MESSAGE-SIGNATURES]
@target-uri as defined in Section 2.2.2 of [HTTP-MESSAGE-SIGNATURES]
Agents MUST include the following @signature-params as defined in
Section 2.3 of [HTTP-MESSAGE-SIGNATURES]
created as defined in Section 2.3 of [HTTP-MESSAGE-SIGNATURES]
expires as defined in Section 2.3 of [HTTP-MESSAGE-SIGNATURES]
keyid MUST be a base64url JWK SHA-256 Thumbprint as defined in
Section 3.2 of [JWK-THUMBPRINT] for RSA and EC, and in
Appendix A.3 of [JWK-OKP] for ed25519.
tag MUST be web-bot-auth
The signing key is available to the agent at request time.
Algorithms should be registered with IANA as part of HTTP Message
Signatures Algorithm registry.
The creation of the signature is defined in Section 3.1 of
[HTTP-MESSAGE-SIGNATURES].
It is RECOMMENDED that expiry be no more than 24 hours.
The components above bind the signature to an authority, not to a
request. A signature covering @authority alone verifies against any
method, path, or body sent to that authority until it expires, so
anyone who observes one request can reuse it against the same origin
until then. expires bounds how long that lasts; the covered
components bound what it reaches. Agents that want to narrow it
SHOULD also cover @method, and either @path or @target-uri, as
Appendix D.2 does. A signer that omits them remains conformant.
Appendix C.7 covers what that costs on the wire.
No component covers the body. An Agent that needs one MUST send and
cover Content-Digest [DIGEST-FIELDS]. This document does not require
it. Most automated traffic is GET, and a mandatory digest would
force every Agent to buffer request bodies it would otherwise stream.
5.2.1. Signature-Agent
Signature-Agent is a Dictionary Structured Header as defined in
Section 3.2 of [STRUCTURED-HEADERS]. Its member values MUST be
String Items that contain a [URI], whose scheme MUST be https. If
dictionary values are not valid URI-references, the entire header
field MAY be ignored.
Meunier & Major Expires 7 February 2027 [Page 10]
Internet-Draft HTTP Message Signatures for Bots August 2026
Each member carries a type parameter, a Token Item as defined in
Section 3.3.4 of [STRUCTURED-HEADERS], naming the discovery mechanism
that resolves the value to key material. Section 5.5 defines the
types. When type is absent, its value is directory. A verifier that
does not support a type value MUST ignore that member, and MUST NOT
infer the mechanism from the URI path, media type, or response body.
Earlier versions of this protocol defined Signature-Agent as a bare
String, and deployments still send it (Appendix E.1.3). A verifier
MAY accept that form and treat it as a dictionary with a single
member whose key is the label of the signature covering it. Signers
MUST send the dictionary form. The two are distinguishable on the
wire: a String Item begins with a double quote " while a Dictionary
member key does not.
It is RECOMMENDED that the Agent sends requests with Signature-Agent
header, as described in Section 5.2.5. If the header is to be sent,
one of its members MUST be signed as a component as defined in
Section 2.1 of [HTTP-MESSAGE-SIGNATURES]. The Signature-Agent member
identifies where candidate key material can be found. The key used
to verify the signature is selected by the keyid parameter of the
corresponding Signature-Input member.
This results in the following components to be signed
("@authority" "signature-agent";key="sig1")
It is RECOMMENDED that the key matches the signature label.
5.2.2. Multiple signatures
A request MAY contain more than one Web Bot Auth signature. Each
signature is identified by its HTTP Message Signatures label. When
Signature-Agent is present, each signer SHOULD provide a Signature-
Agent member for its label.
A signer MAY cover members from another signature label, which
preserves evidence that another signer contributed to the request. A
signer that covers "signature";key=X MUST also cover "signature-
input";key=X, and MUST cover every component identifier listed in
"signature-input";key=X.
A signature value on its own does not identify the message it was
computed over, which is why Section 7.3.7 of
[HTTP-MESSAGE-SIGNATURES] recommends against signing one. Covering
signature-input is not sufficient: it lists component identifiers,
whose values resolve against whatever message the verifier holds. An
outer signature that named those identifiers without covering them
Meunier & Major Expires 7 February 2027 [Page 11]
Internet-Draft HTTP Message Signatures for Bots August 2026
would still verify after the whole header set was lifted onto a
different message, the ambiguity Section 7.3.7 of
[HTTP-MESSAGE-SIGNATURES] describes. Covering the union addresses
this: the outer signer commits to a message on which the inner
signature is checkable, under which key, and over which validity
window.
A signer that cannot cover one of those components, because it
changed the value the inner signature was computed over, MUST NOT
cover the inner signature member. It signs the request on its own
terms, and the inner signature is left untouched.
Verifiers MUST validate each signature independently against its own
covered components and its own key. An outer signature that covers
an inner one is evidence that those bytes, over that set of
components, were present. It does not make the inner signature
valid, and it does not express authorization, delegation, or consent.
Those meanings are deployment policy, or are carried in separately
signed fields.
5.2.3. Anti-replay
Origins MAY want to prevent signatures from being spoofed or used
multiple times by bad actors and thus require a nonce to be added to
the @signature-params. This is described in Section 7.2.2 of
[HTTP-MESSAGE-SIGNATURES].
Agents SHOULD extend @signature-parameters defined in Section 5.2 as
follows:
nonce base64url encoded random byte array. It is RECOMMENDED to use
a 64-byte array.
Client MUST ensure that this nonce is unique for the validity window
of the signature, as defined by created and expires attributes.
5.2.4. Additional headers
Agents MAY include additional components, such as specific HTTP
headers, in the signature. This can be prompted by the origin
requesting additional headers, as described in Section 5.3, or
initiated by the agent to provide more information within the
signature scope. For example, an agent might include an HTTP header
expressing its intent and sign it.
Origins MAY ignore certain headers at their own discretion, and
request a new signature, as described in Section 5.3.
Meunier & Major Expires 7 February 2027 [Page 12]
Internet-Draft HTTP Message Signatures for Bots August 2026
5.2.5. Sending a request
An Agent SHOULD send a request with the signature generated above.
Updating the overview diagram, the flow looks as follow.
+---------+ +----------+
| | Exchange | |
| |<================================ Cryptographic ===============================>| |
| | material | |
| Agent | | Origin |
| | .-------------------------------------------------------------------. | |
| +-----| GET /path/to/resource |------->| |
| | | Signature: sig=abc== | | |
+---------+ | Signature-Input: sig=("@authority" "signature-agent";key="sig");\ | +----------+
| created=1700000000;\ |
| expires=1700011111;\ |
| keyid="ba3e64==";\ |
| tag="web-bot-auth" |
| Signature-Agent: sig="https://signer.example.com" |
'-------------------------------------------------------------------'
The Agent SHOULD send requests with two headers
1. Signature defined in Section 5.2
2. Signature-Input defined in Section 5.2
As described in Section 5.2.1, it is RECOMMENDED that the Agent also
send the Signature-Agent header. Without it the Agent is identified
by its key alone, with the consequences described in Section 4.3.
5.3. Requesting a Message signature
Section 5 of [HTTP-MESSAGE-SIGNATURES] defines the Accept-Signature
field which can be used to request a Message Signature from a client
by an origin. An Origin MAY choose to request signatures from
clients that did not initially provide them. If requesting, Origins
MUST use the same parameters as those defined by the Section 5.2.
The status code SHOULD be 403 Forbidden as defined in Section 15.5.4
of [HTTP].
Origin MAY request a new signature with tag "web-bot-auth" even if a
nonce is provided, for example if it believes the nonce is a replay,
or if it doesn't store nonces and thus requests new signatures every
time. The status code SHOULD be 429 Too Many Requests as defined in
Section 4 of [HTTP-MORE-STATUS-CODE].
Meunier & Major Expires 7 February 2027 [Page 13]
Internet-Draft HTTP Message Signatures for Bots August 2026
5.4. Validating Message signature
Upon receiving an HTTP request, the origin has to verify the
signature. The algorithm is provided in Section 3.2 of
[HTTP-MESSAGE-SIGNATURES]. Similar to a regular User-Agent check,
this happens at the HTTP layer, once headers are received.
Additional requirements are placed on this validation:
* During step 1 to 3 included, if the Origin fails to parse the
provided Signature, Signature-Input, or Signature-Agent headers,
it MAY respond with status code 400 Bad Request as defined in
Section 15.5.1 of [HTTP].
* During step 4, the Origin MAY discard signatures for which the tag
is not set to web-bot-auth.
* During step 5, the Origin MAY discard signatures for which it does
not know the keyid for the Signature-Agent URL the signature
covers.
* During step 5, if the keyid is not known for that URL, the Origin
MAY fetch key material as indicated by the Signature-Agent header
defined in Section 5.2.1. Fetching key material affects only
whether verification is possible, not what a valid signature means
(Section 4.4).
Key lookup MUST be keyed on the (URL, key) pair, not on the key
alone. A verifier that indexes by keyid alone will verify a request
as coming from one URL that provides a key it learned from another,
and attribute that request to the URL the client asserted. The party
whose URL is asserted cannot detect or stop this: its own directory
is never fetched, so no rotation or removal has any effect.
Origin MAY require the nonce to satisfy certain constraints: be
globally unique using a global nonce store, be unique to a specific
location or time window using a local cache, or no constraint at all.
5.5. Key Distribution and Discovery
This section describes how a verifier resolves a Signature-Agent URL
to key material. Section 4.4 covers what the fetch does and does not
establish.
The reference for discovery is an HTTPS URL, carried in a Signature-
Agent member as defined in Section 5.2.1. The member's type
parameter names how the URL resolves to key material. This protocol
defines three types:
Meunier & Major Expires 7 February 2027 [Page 14]
Internet-Draft HTTP Message Signatures for Bots August 2026
directory The member value MUST be the ASCII serialization of an
origin as defined in Section 6.2 of [ORIGIN], and a verifier MUST
ignore a member carrying anything else (an empty path / MAY be
accepted though). Resolve the HTTP Message Signatures Directory
at the well-known URI registered in Section 8.1, at that origin.
This is the default when no type parameter is present.
jwks_uri Resolve the member value as a direct JWK Set URI.
cimd Resolve the member value as a Client ID Metadata Document
[CIMD] URI. The document then provides key material through jwks
or jwks_uri.
All three types produce an identifier: the URL the verifier resolved,
with any query and fragment discarded. For directory that is the
well-known URI, one per origin. For jwks_uri and cimd it is the
member value; the verifier fetches that value as sent, so the query
is dropped from the identifier and not from the request. Otherwise
one key set would yield an identifier per spelling, and an Agent
could mint them at will.
Identifiers are compared after normalization as described in
Section 6.2.2 of [URI] and Section 6.2.3 of [URI]. Two identifiers
are the same when their normalized forms are equal octet for octet.
The types differ in what additional information the verifier learns
from the URL. TLS authenticates the host but not the path, and
nothing reserves the jwks_uri or cimd path to the host's operator.
The well-known URI is reserved, so directory additionally names a
domain (Section 4.5).
For all types, the key is selected using the keyid parameter in
Signature-Input.
Note: when a JWK set is served at the well-known URI registered in
Section 8.1, JWK MAY carry a kid. In this case, it MUST be set to
the thumbprint defined in Section 5.2, so a verifier selects a key by
matching keyid against kid. Deriving kid from the key material keeps
it globally unique and lets a verifier check the directory's own
labelling rather than trusting it.
jwks_uri and cimd resolve to key sets that may serve other consumers,
where kid is an operator-chosen label. A verifier that cannot match
keyid against kid there computes thumbprints instead.
Signature-Agent: sig1="https://signature-agent.test"
Signature-Agent: sig1="https://signature-agent.test/jwks.json";type=jwks_uri
Signature-Agent: sig1="https://signature-agent.test/card";type=cimd
Meunier & Major Expires 7 February 2027 [Page 15]
Internet-Draft HTTP Message Signatures for Bots August 2026
5.5.1. Directory format
All three types resolve to a JSON Web Key Set (JWKS) as defined in
Section 5 of [JWK]. The alg parameter is restricted to algorithms
registered in the HTTP Signature Algorithms section of
[HTTP-MESSAGE-SIGNATURES-IANA].
The directory MUST be served over HTTPS. A directory served at the
well-known URI registered in Section 8.1 MUST be served with media
type application/http-message-signatures-directory+json.
A verifier SHOULD validate the directory format and reject malformed
entries.
GET /.well-known/http-message-signatures-directory HTTP/1.1
Host: example.com
Accept: application/http-message-signatures-directory+json
HTTP/1.1 200 OK
Content-Type: application/http-message-signatures-directory+json
Cache-Control: max-age=86400
{
"keys": [{
"kty": "OKP",
"crv": "Ed25519",
"kid": "NFcWBst6DXG-N35nHdzMrioWntdzNZghQSkjHNMMSjw",
"x": "JrQLj5P_89iXES9-vFgrIy29clF9CC_oPPsw3c5D0bs",
"use": "sig",
"nbf": 1712793600,
"exp": 1715385600
}]
}
5.5.2. Key rotation
Directory operators SHOULD rotate keys by publishing the old and the
new key together, then removing the old one:
1. Add the new key to the directory before its intended use date
2. Continue to include the old key until its expiration date
3. Remove expired keys from the directory
Meunier & Major Expires 7 February 2027 [Page 16]
Internet-Draft HTTP Message Signatures for Bots August 2026
Removing a key from the directory deactivates it. Verifiers stop
accepting it once their cached copy expires, so the directory's cache
lifetime bounds how long a removed key keeps verifying. Verifiers
SHOULD cache the directory contents and refresh upon expiration, as
described in Appendix C.4.
It is not a revocation mechanism, and this document does not define
any.
5.5.3. Redistributed key material
IP addresses and user-agent have been aggregated and distributed via
lists. This section says what a verifier may conclude from key
material it did not fetch itself. Defining a format for
redistribution is out of scope.
A verifier MUST NOT attribute a request to a Signature-Agent URL on
the basis of redistributed key material unless it carries, for the
key in question, a valid directory response signature as described in
Appendix B whose expires has not passed. Without that proof the
material stays usable for verifying signatures, but it carries no
URL, so the identifier falls back to the key thumbprint
(Section 4.3).
The main requirement is to terminate the TLS connection. A verifier
polling a directory on its own schedule is resolving it. So is a
control plane polling on behalf of the verifiers it serves. None of
these options constitute redistribution. Nor is a list that names
directory URLs rather than embedding keys. For instance, [REGISTRY]
works that way, and the verifier still resolves them.
5.5.4. Signature-Key header
[SIGNATURE-KEY] defines a separate key discovery header for HTTP
Message Signatures. Deployments MAY use it when they need that
model. This protocol uses Signature-Agent as its default discovery
mechanism.
5.6. Session considerations
Per-request signing and verification costs CPU; uncached key
discovery adds latency. For high request rates, an origin can verify
a request-specific signature once and issue a session credential for
later requests. This can amortize asymmetric verification and reduce
bytes, but adds the risks of token theft and replay.
Meunier & Major Expires 7 February 2027 [Page 17]
Internet-Draft HTTP Message Signatures for Bots August 2026
A reused signature already has token semantics until expires. A
session established from one extends that window past expires unless
the credential is bounded to it: no longer-lived, and no wider in
scope than the components the signature covered. Session
establishment and binding are out of scope.
6. Security Considerations
6.1. Use of TLS
We reassess Section 7.1.2 of [HTTP-MESSAGE-SIGNATURES]. Clients
SHOULD use TLS [RFC8446] (https) or equivalent transport security
when making requests with Message signatures. Failing to do so
exposes the Message signature to numerous attacks that could give
attackers unintended access.
This include reverse proxy and their consideration presented in
Section 6.7.
An origin SHOULD refuse Signature headers when communicated over an
unsecured channel.
6.2. Performance Impact
Origins should account for the overhead of signature verification in
their operations. A local cache of public keys reduces network
requests and verification latency. The choice of signing algorithm
impacts CPU requirements. Origins should monitor verification
latency and set appropriate timeouts to maintain service levels under
load. See Section 5.6: a session amortizes that cost by replacing
verification with a bearer credential. Appendix C.7 covers the byte
cost.
6.3. Nonce validation
Clients control the nonce. While Section 5.2.3 mandates that clients
MUST provide a globally unique nonce, it is the origin's
responsibility to enforce it.
Different validation policies have different performance and
operational considerations. Global uniqueness requires a global
nonce store. Some origins may find that their use case can tolerate
sharding on location, timing, or other properties.
Meunier & Major Expires 7 February 2027 [Page 18]
Internet-Draft HTTP Message Signatures for Bots August 2026
6.4. Key Compromise Response
This document defines no revocation. Removing a compromised key from
the directory is the only remedy, and it takes effect at each
verifier on its next refresh, so the key can keep verifying for as
long as Section 5.5.2 allows. The protocol carries no channel back
to verifiers, so an Agent cannot reach them sooner. Signature
lifetimes (Section 5.2) are the only lever that acts faster.
Agents SHOULD remove a compromised key and publish a replacement
immediately. Origins should support rapid key rotation and monitor
for suspicious signature patterns.
6.5. Shared Secrets Considered Harmful
Implementations MUST NOT use shared HMAC defined in Section 3.3.3 of
[HTTP-MESSAGE-SIGNATURES]. Shared secrets break non-repudiation and
make auditing difficult. Each automated client SHOULD use a unique
asymmetric keypair to ensure attribution, support key rotation, and
enable effective rotation if needed.
6.6. Key Reuse Considered Harmful
Implementations SHOULD NOT reuse a signing key for different
purposes. For example, if an agent implementor has two agents they
want to differentiate, these should use distinct signing keys and
signing key directories.
6.7. Reverse proxy consideration
An origin may be placed behind a reverse proxy, which means the proxy
will see the Signature and Signature-Agent headers before the origin
does. A proxy SHOULD NOT strip the Signature or Signature-Agent
headers from requests.
A proxy SHOULD NOT replay signatures against other reverse proxies
used by the origin, as this allows impersonation of the principal
signature agent.
Origins MAY require a specific nonce policy to prevent such malicious
behaviour and decide to validate the signature themselves. This has
to be done in accordance with Section 6.3. For example, an origin
could require a nonce derived from public information (such as the
current date), mandate nonce chaining (where each nonce is the hash
of the previous one), or provide its own nonce in an Accept-Signature
response to challenge the agent.
Meunier & Major Expires 7 February 2027 [Page 19]
Internet-Draft HTTP Message Signatures for Bots August 2026
Such policies MAY incur additional round-trip between the client and
the origin to convey accept-signature header, or deployment specific
exchanges.
6.7.1. Signature-Agent labeling
Section 7.2.5 of [HTTP-MESSAGE-SIGNATURES] allows an intermediary to
relabel a signature, because the label of a Signature dictionary
member is not part of the signature base. The key of a Signature-
Agent member is different: when a signature covers "signature-
agent";key="agent2", that key appears in the signature base, so
changing it invalidates the signature. Only the holder of the
signing key can produce a signature over the new member key.
An intermediary MUST NOT alter the key of a Signature-Agent member
that is covered by a signature it is not able to recompute.
Relabeling the Signature dictionary member remains permitted.
A signer acting as an intermediary on its own signature is not
restricted by this, since it can sign the result.
6.8. Server-Side Request Forgery (SSRF)
As described in Section 5.5, verifiers may fetch key directories
based on the value conveyed in Signature-Agent when included in a
request. Since clients control the Signature-Agent header value,
this introduces a risk of server-side request forgery (SSRF) attacks
by malicious clients.
Verifiers SHOULD take appropriate precautions as follows:
Response size a directory can be arbitrarily large. Verifiers
SHOULD reject responses exceeding a defined byte limit after
content decoding.
Key count a JWKS with many keys forces O(n) key search. Verifiers
SHOULD enforce a maximum key count.
Fetch latency no timeout allows slowloris-style exhaustion.
Verifiers SHOULD apply a wall-clock timeout to directory fetches.
Redirect chains unbounded HTTP redirects can be used to amplify
requests. Verifiers SHOULD limit redirect depth.
Network address ranges no address filtering can target internal
services. Verifiers SHOULD prevent directory fetches to private,
loopback, and link-local address ranges.
Meunier & Major Expires 7 February 2027 [Page 20]
Internet-Draft HTTP Message Signatures for Bots August 2026
Further recommendations can be found in the Open Worldwide
Application Security Project (OWASP) SSRF Prevention Cheat Sheet
[OWASP-SSRF].
6.9. Test and Demonstration Keys
Test keys, including the example keys in [HTTP-MESSAGE-SIGNATURES],
MUST NOT be used in production. Verifiers SHOULD reject known test
keys when they are detected in key directories or out-of-band
configuration.
6.10. Static Signatures
Deployments MUST NOT treat a precomputed Web Bot Auth signature as a
long-lived access credential. A reusable static signature has
bearer-token semantics and can be replayed until the covered
signature parameters, key, or verifier policy make it unusable.
Agents SHOULD generate signatures for the request being sent, with
bounded created and expires values. Long expiration windows increase
replay risk.
6.11. Discovery Failure
Resolving a Signature-Agent URL can fail in several ways: the name
does not resolve, the connection or TLS handshake fails, the response
is not a directory or contains no key matching keyid, or the fetch is
refused by the verifier's own limits (Section 6.8). All have the
same outcome for the request in hand. The verifier holds no
association between that URL and the signing key, so under
Section 4.4 it MUST NOT attribute the request to that URL. It may
still verify the signature if it holds the key by other means, in
which case the identifier is the thumbprint (Section 4.3); otherwise
the request is unverified.
They differ in what they say about cached state, and verifiers MUST
keep them apart. A directory that resolves and does not contain the
key is evidence: it is newer than whatever the verifier holds, and
under Section 4.4 replaces it. That is how a removed key stops
verifying. A directory that fails to resolve is not evidence and
MUST NOT evict a cached entry, or an operator's outage revokes its
keys at every verifier at once.
A failed fetch says nothing about the signer. It does not prove the
signer is malicious, and it does not make the request trusted. What
an origin does with an unverified request is local policy, and
treating it as a distinct outcome rather than as success or failure
is discussed in Appendix C.1. Verifiers should also expect failures
Meunier & Major Expires 7 February 2027 [Page 21]
Internet-Draft HTTP Message Signatures for Bots August 2026
to be correlated: a single operator's directory going down takes out
every request naming it at once, across every verifier whose cache
expires in the same window.
6.12. Unsigned requests
Most HTTP requests carry no signature. A verifier that sees none has
learned nothing about the sender: not that it is automated, not that
it is human, not that it is evading anything. Absence of a signal is
not evidence about the party that did not send it, in the same way
that a failed fetch (Section 6.11) is not evidence about the signer.
What an origin does with a request it cannot attribute is its own
decision, as it was before this protocol existed. This document
neither requires an origin to treat unsigned requests differently nor
gives it grounds to.
7. Privacy Considerations
7.1. Public Identity
This protocol assumes that automated clients identify themselves
explicitly using digital signatures. The identity associated with a
signing key is expected to be publicly discoverable for verification
purposes. This reduces anonymity and allows receivers to associate
requests with specific agents. If an agent wishes not to identify
itself, this is not the right choice of protocol for it.
7.2. No Human Correlation
The key used for signing MUST NOT be tied to a specific human
individual. Keys SHOULD represent a role, company, or automation
identity (e.g., "news-aggregator- bot", "example-crawler-v1"). This
avoids accidental exposure of personally identifiable information and
prevents the misuse of keys for user tracking or profiling.
7.3. Minimizing Tracking Risks
To limit tracking risks, implementations SHOULD avoid long-lived,
globally unique key identifiers unless strictly necessary. Key
rotation SHOULD be supported, and clients SHOULD take care to avoid
signing information that could be used to correlate activity across
contexts, especially where sensitive user data is involved.
Meunier & Major Expires 7 February 2027 [Page 22]
Internet-Draft HTTP Message Signatures for Bots August 2026
7.4. Directory content and access patterns
A key directory should only contain keys actively used for signing.
Additional keys or metadata expose more about the signing service
than verification requires. Verifiers fetching a directory also
reveal something about their verification patterns, so directory
servers should avoid logging personally identifiable information from
directory requests.
8. IANA Considerations
This section contains considerations for IANA.
8.1. Well-Known 'http-message-signatures-directory' URI
This document updates the "Well-Known URIs" Registry [WellKnownURIs]
with the following values.
+===============+============+===========+===========+=============+
| URI Suffix | Change | Reference | Status | Related |
| | Controller | | | information |
+===============+============+===========+===========+=============+
| http-message- | IETF | this | permanent | None |
| signatures- | | document | | |
| directory | | | | |
+---------------+------------+-----------+-----------+-------------+
Table 1: 'http-message-signatures-directory' Well-Known URI
8.2. Media Types
The following entries should be added to the IANA "media types"
registry:
* "application/http-message-signatures-directory+json"
The templates for these entries are listed below and the reference
should be this RFC.
8.2.1. "application/http-message-signatures-directory+json" media type
Type name: application
Subtype name: http-message-signatures-directory
Required parameters: N/A
Optional parameters: N/A
Encoding considerations: "binary"
Security considerations: see Section 6
Interoperability considerations: N/A
Meunier & Major Expires 7 February 2027 [Page 23]
Internet-Draft HTTP Message Signatures for Bots August 2026
Published specification: this specification
Applications that use this media type: Services that implement the
signer role for HTTP Message Signatures and verifiers that
interact with the signer for the purpose of validating signatures.
Fragment identifier considerations: N/A
Additional information: Magic number(s): N/A
Deprecated alias names for this type: N/A
File extension(s): N/A
Macintosh file type code(s): N/A
Person and email address to contact for further information: see
Authors' Addresses section
Intended usage: COMMON
Restrictions on usage: N/A
Author: see Authors' Addresses section
Change controller: IETF
9. References
9.1. Normative References
[CIMD] Parecki, A. and E. Smith, "OAuth Client ID Metadata
Document", Work in Progress, Internet-Draft, draft-ietf-
oauth-client-id-metadata-document-02, 6 July 2026,
<https://datatracker.ietf.org/doc/html/draft-ietf-oauth-
client-id-metadata-document-02>.
[DIGEST-FIELDS]
Polli, R. and L. Pardue, "Digest Fields", RFC 9530,
DOI 10.17487/RFC9530, February 2024,
<https://www.rfc-editor.org/rfc/rfc9530>.
[HTTP] Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke,
Ed., "HTTP Semantics", STD 97, RFC 9110,
DOI 10.17487/RFC9110, June 2022,
<https://www.rfc-editor.org/rfc/rfc9110>.
[HTTP-CACHE]
Fielding, R., Ed., Nottingham, M., Ed., and J. Reschke,
Ed., "HTTP Caching", STD 98, RFC 9111,
DOI 10.17487/RFC9111, June 2022,
<https://www.rfc-editor.org/rfc/rfc9111>.
[HTTP-MESSAGE-SIGNATURES]
Backman, A., Ed., Richer, J., Ed., and M. Sporny, "HTTP
Message Signatures", RFC 9421, DOI 10.17487/RFC9421,
February 2024, <https://www.rfc-editor.org/rfc/rfc9421>.
Meunier & Major Expires 7 February 2027 [Page 24]
Internet-Draft HTTP Message Signatures for Bots August 2026
[HTTP-MESSAGE-SIGNATURES-IANA]
"HTTP Message Signatures", n.d.,
<https://www.iana.org/assignments/http-message-signature/
http-message-signature.xhtml>.
[HTTP-MORE-STATUS-CODE]
Nottingham, M. and R. Fielding, "Additional HTTP Status
Codes", RFC 6585, DOI 10.17487/RFC6585, April 2012,
<https://www.rfc-editor.org/rfc/rfc6585>.
[JWK] Jones, M., "JSON Web Key (JWK)", RFC 7517,
DOI 10.17487/RFC7517, May 2015,
<https://www.rfc-editor.org/rfc/rfc7517>.
[JWK-OKP] Liusvaara, I., "CFRG Elliptic Curve Diffie-Hellman (ECDH)
and Signatures in JSON Object Signing and Encryption
(JOSE)", RFC 8037, DOI 10.17487/RFC8037, January 2017,
<https://www.rfc-editor.org/rfc/rfc8037>.
[JWK-THUMBPRINT]
Jones, M. and N. Sakimura, "JSON Web Key (JWK)
Thumbprint", RFC 7638, DOI 10.17487/RFC7638, September
2015, <https://www.rfc-editor.org/rfc/rfc7638>.
[ORIGIN] Barth, A., "The Web Origin Concept", RFC 6454,
DOI 10.17487/RFC6454, December 2011,
<https://www.rfc-editor.org/rfc/rfc6454>.
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119,
DOI 10.17487/RFC2119, March 1997,
<https://www.rfc-editor.org/rfc/rfc2119>.
[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
May 2017, <https://www.rfc-editor.org/rfc/rfc8174>.
[STRUCTURED-HEADERS]
Nottingham, M. and P. Kamp, "Structured Field Values for
HTTP", RFC 9651, DOI 10.17487/RFC9651, September 2024,
<https://www.rfc-editor.org/rfc/rfc9651>.
[URI] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform
Resource Identifier (URI): Generic Syntax", STD 66,
RFC 3986, DOI 10.17487/RFC3986, January 2005,
<https://www.rfc-editor.org/rfc/rfc3986>.
Meunier & Major Expires 7 February 2027 [Page 25]
Internet-Draft HTTP Message Signatures for Bots August 2026
[WellKnownURIs]
"Well-Known URIs", n.d.,
<https://www.iana.org/assignments/well-known-uris/well-
known-uris.xhtml>.
9.2. Informative References
[HPACK] Peon, R. and H. Ruellan, "HPACK: Header Compression for
HTTP/2", RFC 7541, DOI 10.17487/RFC7541, May 2015,
<https://www.rfc-editor.org/rfc/rfc7541>.
[HTTP-BEST-PRACTICES]
Nottingham, M., "Building Protocols with HTTP", BCP 56,
RFC 9205, DOI 10.17487/RFC9205, June 2022,
<https://www.rfc-editor.org/rfc/rfc9205>.
[OAUTH-BEARER]
Jones, M. and D. Hardt, "The OAuth 2.0 Authorization
Framework: Bearer Token Usage", RFC 6750,
DOI 10.17487/RFC6750, October 2012,
<https://www.rfc-editor.org/rfc/rfc6750>.
[OWASP-SSRF]
"OWASP Server-Side Request Forgery Prevention Cheat
Sheet", n.d.,
<https://cheatsheetseries.owasp.org/cheatsheets/
Server_Side_Request_Forgery_Prevention_Cheat_Sheet.html>.
[QPACK] Krasic, C., Bishop, M., and A. Frindell, Ed., "QPACK:
Field Compression for HTTP/3", RFC 9204,
DOI 10.17487/RFC9204, June 2022,
<https://www.rfc-editor.org/rfc/rfc9204>.
[REGISTRY] Guerreiro, M., Kirazci, U., and T. Meunier, "Registry and
Signature Agent card for Web bot auth", Work in Progress,
Internet-Draft, draft-meunier-webbotauth-registry-03, 26
June 2026, <https://datatracker.ietf.org/doc/html/draft-
meunier-webbotauth-registry-03>.
[RFC8446] Rescorla, E., "The Transport Layer Security (TLS) Protocol
Version 1.3", RFC 8446, DOI 10.17487/RFC8446, August 2018,
<https://www.rfc-editor.org/rfc/rfc8446>.
Meunier & Major Expires 7 February 2027 [Page 26]
Internet-Draft HTTP Message Signatures for Bots August 2026
[SIGNATURE-KEY]
Hardt, D. and T. Meunier, "HTTP Signature Keys", Work in
Progress, Internet-Draft, draft-hardt-httpbis-signature-
key-08, 5 August 2026,
<https://datatracker.ietf.org/doc/html/draft-hardt-
httpbis-signature-key-08>.
[USE-CASES]
Nottingham, M., "Use Cases for Authentication of Web
Bots", Work in Progress, Internet-Draft, draft-nottingham-
webbotauth-use-cases-02, 1 April 2026,
<https://datatracker.ietf.org/doc/html/draft-nottingham-
webbotauth-use-cases-02>.
[WELLKNOWN-URI]
Nottingham, M., "Well-Known Uniform Resource Identifiers
(URIs)", RFC 8615, DOI 10.17487/RFC8615, May 2019,
<https://www.rfc-editor.org/rfc/rfc8615>.
Appendix A. Use cases and what they need
[USE-CASES] collects the use cases this group has discussed. Most
are served by the URL alone. The table below records which ones need
the domain binding in Appendix B, and why.
Meunier & Major Expires 7 February 2027 [Page 27]
Internet-Draft HTTP Message Signatures for Bots August 2026
+=============================+===========================+========+
| Use case | What the origin does | Needs |
+=============================+===========================+========+
| Mitigating volumetric abuse | Rate limit per URL | URL |
+-----------------------------+---------------------------+--------+
| Controlling access by bots | Set policy per URL | URL |
+-----------------------------+---------------------------+--------+
| Providing different content | Recognise a given URL | URL |
| to bots | | |
+-----------------------------+---------------------------+--------+
| Auditing bot behaviour | Group logs by URL | URL |
+-----------------------------+---------------------------+--------+
| Classifying traffic | Correlate observed | URL |
| | behaviour with a URL | |
+-----------------------------+---------------------------+--------+
| IP address mobility and | Nothing: the signature | URL |
| sharing | does not depend on the IP | |
+-----------------------------+---------------------------+--------+
| Robots.txt alignment | Match the crawler against | Domain |
| | a name in the file | |
+-----------------------------+---------------------------+--------+
| Conveying contextual | Read signed headers | Domain |
| information | alongside the identifier | |
+-----------------------------+---------------------------+--------+
Table 2: Use cases and the identifier they need
The last two are the pattern from Section 4.5. Both consume
something held against a name rather than against the key: a
robots.txt file names crawlers, and contextual assertions are only
worth as much as the party making them. End-user authentication and
anonymous authentication are out of scope.
Appendix B. Validating the domain binding
This appendix describes what a verifier checks when it wants the
domain a key is published under, rather than the URL on its own. It
applies to the directory type in Section 5.5. Verification,
rotation, and continuity do not depend on any of it, and a verifier
that only needs the URL as an identifier can skip the whole appendix.
Authority over the domain comes from the TLS connection to the
directory. Nothing below adds to that.
Meunier & Major Expires 7 February 2027 [Page 28]
Internet-Draft HTTP Message Signatures for Bots August 2026
B.1. Possession proof on the directory response
It is RECOMMENDED that a directory server construct and include one
HTTP Message Signature per key with the response, as defined in
[HTTP-MESSAGE-SIGNATURES]. Each key SHOULD be used to provide one
signature. These signatures prove possession of the advertised keys
and, by covering @authority, prevent the key set from being re-served
under a different authority. This matters for a domain-bound
identifier, where the verifier is about to consume information it
holds against the name: it distinguishes a key set the key holders
assembled from one that was copied.
Directory server MUST include the following covered components:
@authority as defined in Section 2.2.3 of [HTTP-MESSAGE-SIGNATURES].
req flag defined in Section 2.4 of [HTTP-MESSAGE-SIGNATURES] MUST
be set.
content-digest as defined in [DIGEST-FIELDS].
Directory server MUST include the following @signature-params as
defined in Section 2.3 of [HTTP-MESSAGE-SIGNATURES]
created as defined in Section 2.3 of [HTTP-MESSAGE-SIGNATURES]
expires as defined in Section 2.3 of [HTTP-MESSAGE-SIGNATURES]
Without them the signature is a permanent assertion that these keys
were bound to this authority at some unstated time, of no use to a
verifier consuming it through Section 5.5.3.
keyid MUST be a base64url JWK SHA-256 Thumbprint as defined in
Section 3.2 of [JWK-THUMBPRINT] for RSA and EC, and in
Appendix A.3 of [JWK-OKP] for ed25519.
tag MUST be http-message-signatures-directory
A verifier relying on the domain MUST validate these signatures using
the keys provided by the directory, MUST validate the Content-Digest
field against the response body, and MUST ignore keys that do not
have a corresponding valid signature. A verifier MUST reject a
directory response signature whose created is in the future, as it
would a certificate that is not yet valid. Section 4.4 orders
competing evidence by created, so a future-dated signature would
outrank every later fetch.
Meunier & Major Expires 7 February 2027 [Page 29]
Internet-Draft HTTP Message Signatures for Bots August 2026
B.2. What the binding attaches to
The binding is not exclusive. Several domains may publish the same
key, and the binding attaches to the pair the verifier validated, not
to the key on its own. A verifier that recognises a key under one
domain has learned nothing about the same key served under another.
Appendix C. Deployment Guidance
This appendix is operational guidance. It does not define new
protocol requirements.
C.1. Verifier Outcomes
Verifiers should keep three outcomes distinct:
verified the signature and key material validate.
invalid the signature, covered components, key, or freshness checks
fail.
unverified the verifier cannot obtain enough information to decide,
for example because directory discovery failed or the key is
unknown.
Origins can apply local policy to each outcome. During deployment,
treating unverified as one bot-management signal is safer than
treating it as either verified or invalid.
C.2. Directory Availability
Directory resources are bootstrap material. Operators serving a
directory should make it reachable without requiring Web Bot Auth on
the directory request. They should also avoid bot protection rules
that block ordinary verifier fetches of the well-known resource.
The directory endpoint should support GET. Supporting HEAD, ETag,
Last-Modified, Cache-Control, and conditional requests can reduce
fetch load. Cache is specifically discussed in Appendix C.4.
C.3. Bounded Directory Fetches
Verifiers fetch directories named by untrusted requests, and should
bound those fetches as described in Section 6.8.
Meunier & Major Expires 7 February 2027 [Page 30]
Internet-Draft HTTP Message Signatures for Bots August 2026
Verifiers should also coalesce concurrent fetches for the same
directory and apply per-directory or per-origin concurrency limits.
This avoids a fetch storm when many requests reference the same
uncached directory.
C.4. Cache Behaviour
Verifiers should use normal HTTP caching semantics [HTTP-CACHE] for
key directories. In particular, verifiers should respect Cache-
Control, Expires, Date, ETag, and Last-Modified when present.
A verifier should not fetch the directory for every request. It
should refresh cached directories when they become stale, and can use
background refresh with jitter to avoid synchronized refetches.
C.5. Negative Caching and Retry
Verifiers can cache unsuccessful discovery outcomes for a short
period to reduce repeated fetches. Negative cache entries should
expire after no more than five minutes. They are operational
throttling state, not proof that a signature is invalid.
Network failures, TLS failures, and 5xx responses should be treated
as transient unless local policy says otherwise. Verifiers should
retry with bounded exponential backoff and jitter. When a directory
response includes Retry-After, verifiers should respect it as
described by [HTTP] and [HTTP-BEST-PRACTICES].
C.6. Freshness and Replay
Shorter signature lifetimes reduce replay risk but increase
sensitivity to clock skew and signing failures. Nonces provide
stronger replay defense, but require state at the verifier. Some
deployments can tolerate bounded replay for short windows; others
need strict Section 6.3.
These choices are deployment policy. Verifiers should avoid
accepting signatures with freshness windows longer than their risk
model permits.
C.7. Field compression
Covering per-request components costs bytes when a connection is
reused. HPACK [HPACK] and QPACK [QPACK] can index a repeated
Signature, Signature-Input, or Signature-Agent value, so a signature
reused across requests on one connection is sent once and referenced
afterwards. A per-request value cannot be referenced; it is sent as
a literal every time. Huffman coding and an indexed field name
Meunier & Major Expires 7 February 2027 [Page 31]
Internet-Draft HTTP Message Signatures for Bots August 2026
reduce that literal, they do not replace the reference.
This is not a reason to widen the covered components. The bytes
saved are the bytes of a credential anyone who observes it can replay
until expires (Section 5.2), and one static signature for many
requests is an anti-pattern (Appendix C.12). An encoder that treats
a signature as a credential may also decline to index it
(Section 7.1.3 of [HPACK]).
C.8. Directory Response Signature Lifetimes
Where the key set is redistributed, revocation latency is already
floored by how often the redistributor republishes, so a short
expires on a directory response signature (Appendix B) buys nothing
and costs availability: at expiry every consumer drops that
operator's keys to unverified at once, with no serving stale.
Operators should set expires well beyond the republication interval
of any list they expect to appear in. The lever for faster
revocation is publishing more often, not signing shorter.
C.9. Rollout and Fallback
Web Bot Auth deployments will coexist with existing bot
identification signals during rollout. Verifiers can continue to use
existing methods such as IP-based checks, forward-confirmed reverse
DNS, local allowlists, and reputation systems.
Fallback should not turn an unsupported or unverifiable Web Bot Auth
signature into a trusted identity. It should leave the request in
the origin's existing bot-management path.
C.10. Proxies and Intermediaries
Proxies and intermediaries need to preserve the fields covered by a
signature if the origin will verify that signature. If a proxy
rewrites the authority, path, or signed header fields, the origin may
no longer see the message that was signed.
A deployment can instead verify at the proxy and pass the result to
the origin through a deployment-local trusted channel. That
assertion is local policy; it is not a replacement for the original
HTTP Message Signature.
Meunier & Major Expires 7 February 2027 [Page 32]
Internet-Draft HTTP Message Signatures for Bots August 2026
C.11. CORS
Key directories contain public key material. If browser-based
verifiers need to fetch them cross-origin, a directory server can use
a permissive CORS policy such as Access-Control-Allow-Origin: *
without credentials. CORS is not key authentication and does not
replace signature validation.
C.12. Deployment Anti-Patterns
Deployments should avoid:
* using test or demonstration keys in production
* issuing one static signature for many requests
* asking users to copy long-lived signatures into third-party tools
* sharing one signing key across unrelated agents or purposes
* relying on manual key rotation as the only revocation mechanism
Appendix D. Examples
D.1. Delegation and chaining
Delegation and chaining are out of scope for this document and are
expected to be specified separately. Input is welcome on the
associated GitHub issue (https://github.com/thibmeu/http-message-
signatures-directory/issues/27).
D.2. Multiple signatures with a remote browser
This example shows Alice's agent using a remote browser to fetch a
resource. The agent signs selected request fields. The remote
browser signs the request it sends to the origin and also covers the
agent's signature fields. The signature values are illustrative;
this is not a test vector.
Meunier & Major Expires 7 February 2027 [Page 33]
Internet-Draft HTTP Message Signatures for Bots August 2026
NOTE: '\' line wrapping per RFC 8792
GET /resource HTTP/1.1
Host: origin.example
Signature-Agent: agent="https://agent.alice.example",\
browser="https://browser.example"
Signature-Input: agent=("@method" "@authority" "@path"\
"signature-agent";key="agent");created=1735689600\
;keyid="poqkLGiymh_W0uP6PZFw-dvez3QJT5SolqXBCW38r0U"\
;tag="web-bot-auth",\
browser=("@method" "@authority" "@path"\
"signature-agent";key="browser"\
"signature-agent";key="agent"\
"signature-input";key="agent"\
"signature";key="agent");created=1735689601\
;keyid="oD0HwocPBSfpNy5W3bpJeyFGY_IQ_YpqxSjQ3Yd-CLA"\
;tag="web-bot-auth"
Signature: agent=:YWdlbnQtc2lnbmF0dXJl:,\
browser=:YnJvd3Nlci1zaWduYXR1cmU=:
The origin verifies each signature on its own. The agent signature
covers the fields selected by Alice's agent. The browser signature
covers the request sent by the remote browser, its own Signature-
Agent member, and all three of the agent label's fields, as
Section 5.2.2 requires. This records that the remote browser
forwarded a request carrying the agent's signature. It does not say
that Alice's agent authorized the remote browser to act for it.
Appendix E. Test Vectors
These vectors exercise the minimum this document requires, so most of
them cover @authority and nothing else, with an expires far enough
out that they do not age. That combination is a parsing and
verification exercise, not a configuration to copy: as Section 5.2
explains, a signature covering @authority alone is reusable against
that authority for any method, path, and body until it expires.
Deployments should cover more and expire sooner.
E.1. RSASSA-PSS Using SHA-512
The test vectors in this section use the RSA-PSS key defined in
Appendix B.1.2 of [HTTP-MESSAGE-SIGNATURES]. This section includes
non-normative test vectors that may be used as test cases to validate
implementation correctness.
Meunier & Major Expires 7 February 2027 [Page 34]
Internet-Draft HTTP Message Signatures for Bots August 2026
E.1.1. Signature-Agent absent from the request
This example presents a minimal signature using the rsa-pss-sha512
algorithm over test-request. The request does not contain a
Signature-Agent header.
The corresponding signature base is:
NOTE: '\' line wrapping per RFC 8792
"@authority": example.com
"@signature-params": ("@authority")\
;created=1735689600\
;keyid="oD0HwocPBSfpNy5W3bpJeyFGY_IQ_YpqxSjQ3Yd-CLA"\
;alg="rsa-pss-sha512"\
;expires=4889289600\
;nonce="JojDFWJ90jf+gZhdKeTyJYsu1XvNPZSFAGhvYq5SuV3gneOEUAhq+xl792WGuD1W+Dr6NRmx+m+t06NsYnL4iA=="\
;tag="web-bot-auth"
This results in the following Signature-Input and Signature header
fields being added to the message under the label sig1:
NOTE: '\' line wrapping per RFC 8792
Signature-Input: sig1=("@authority")\
;created=1735689600\
;keyid="oD0HwocPBSfpNy5W3bpJeyFGY_IQ_YpqxSjQ3Yd-CLA"\
;alg="rsa-pss-sha512"\
;expires=4889289600\
;nonce="JojDFWJ90jf+gZhdKeTyJYsu1XvNPZSFAGhvYq5SuV3gneOEUAhq+xl792WGuD1W+Dr6NRmx+m+t06NsYnL4iA=="\
;tag="web-bot-auth"
Signature: sig1=:hWPaj85MWQiRkzU4jnIKvdPQiDfMCPIoxOP8nZveNc3aFQ7r/UmXWCwGNImw588iRvTFey5TR3fVEgnXpcttlyK+u5pN831z9Wlr+IMNfub4uEM3SuO+SKFygJZyLG0pf7OAiRcU4C0gyx1BS/+z9ydQTRzDLr88wCkBBRqwGRrSi8HTwxkqg1jugobh93hcnU6gV8MK1n+VnhRprIgl2RQSO6q5cfbB4OS8C4t/8ndW0lYmP2SWzKZJXnpX5Wrj17PuLqnVW6MO8pJnLAMXNvxUdx32KHeq/cHFrzZazZsua3UOoP+k+niHwoQ8bBWj1Vi4mM1mYJK+fk366cCLsQ==:
E.1.2. Signature-Agent included present on the request
This example presents a minimal signature using the rsa-pss-sha512
algorithm over test-request. The request contains a Signature-Agent
header.
The corresponding signature base is:
Meunier & Major Expires 7 February 2027 [Page 35]
Internet-Draft HTTP Message Signatures for Bots August 2026
NOTE: '\' line wrapping per RFC 8792
"@authority": example.com
"signature-agent";key="agent2": "https://signature-agent.test"
"@signature-params": ("@authority" "signature-agent";key="agent2")\
;created=1735689600\
;keyid="oD0HwocPBSfpNy5W3bpJeyFGY_IQ_YpqxSjQ3Yd-CLA"\
;alg="rsa-pss-sha512"\
;expires=4889289600\
;nonce="wcfPQPh7SzkvrIVvhD00vNk9PkxJNY2NVbYl2PVBB4zmUoluSwE7W6bPtF60QA3k8g06FU7PPCD+J58YofY1zg=="\
;tag="web-bot-auth"
This results in the following Signature-Input and Signature header
fields being added to the message under the label sig2:
NOTE: '\' line wrapping per RFC 8792
Signature-Agent: agent2="https://signature-agent.test"
Signature-Input: sig2=("@authority" "signature-agent";key="agent2")\
;created=1735689600\
;keyid="oD0HwocPBSfpNy5W3bpJeyFGY_IQ_YpqxSjQ3Yd-CLA"\
;alg="rsa-pss-sha512"\
;expires=4889289600\
;nonce="wcfPQPh7SzkvrIVvhD00vNk9PkxJNY2NVbYl2PVBB4zmUoluSwE7W6bPtF60QA3k8g06FU7PPCD+J58YofY1zg=="\
;tag="web-bot-auth"
Signature: sig2=:gHzpLNeHaHIO19NaJH9YMW5dcVSi2s0wOMBr6p18vcofS106sfC4KBIS0/szPlBBd1vIcyQ88B6CTEWIhRAiVrb9zfX0mx1aG12CSGWcYkSirHeyTxhbuJvXd27ed6skWoy4PjXItq38936ivUQjfdIwXh1aX6HxkAC3vRnEdSNfntkLWeEuIQ5BLIOBGE39fSwg27Qjq6OVWYas/9/aFUr3HA34MXWYdp+//cvlEKDp3kRoLOw9ro0AOr6srHrTeEtxon2afcws1aZVSlPdd2fZSEIGmw9HAHLDCEkFTERu1gH2k/zIEqgy7CAYXI9E5slog0cLg/Vc6+f8gih33g==:
E.1.3. Legacy Signature-Agent, sf-string
Retained for implementers migrating to the dictionary form
(Section 5.2.1). Do not copy it into new deployments.
This example presents a minimal signature using the rsa-pss-sha512
algorithm over test-request. The request contains a Signature-Agent
header.
The corresponding signature base is:
Meunier & Major Expires 7 February 2027 [Page 36]
Internet-Draft HTTP Message Signatures for Bots August 2026
NOTE: '\' line wrapping per RFC 8792
"@authority": example.com
"signature-agent": "https://signature-agent.test"
"@signature-params": ("@authority" "signature-agent")\
;created=1735689600\
;keyid="oD0HwocPBSfpNy5W3bpJeyFGY_IQ_YpqxSjQ3Yd-CLA"\
;alg="rsa-pss-sha512"\
;expires=1735693200\
;nonce="XSHtZVCThSIAksXsH9WBs6AtxtXC0eQGiIcUGSoJstFs8lAWakjhrfwzLhyjtme5iXMZvmFWqDEs6cT3Jf+BbQ=="\
;tag="web-bot-auth"
This results in the following Signature-Input and Signature header
fields being added to the message under the label sig2:
NOTE: '\' line wrapping per RFC 8792
Signature-Agent: "https://signature-agent.test"
Signature-Input: sig2=("@authority" "signature-agent")\
;created=1735689600\
;keyid="oD0HwocPBSfpNy5W3bpJeyFGY_IQ_YpqxSjQ3Yd-CLA"\
;alg="rsa-pss-sha512"\
;expires=1735693200\
;nonce="XSHtZVCThSIAksXsH9WBs6AtxtXC0eQGiIcUGSoJstFs8lAWakjhrfwzLhyjtme5iXMZvmFWqDEs6cT3Jf+BbQ=="\
;tag="web-bot-auth"
Signature: sig2=:I1QWNzGXdP1a4dSvOHLCVOOanEYHDk+ZsVxM9MLX/p4ko69ghKwR5EOtAD96g7g4GWP7lmpM/jFAf9q8EFRDTPLjUXySwMv4YPgabv2LQihTJG2y8a2m6IGltyruwQNiqSJVUuRaG9+b17CGmAMFZh30X6GXLdQJrCARpeTqPwp2DC+a8haDE/VE5EruqzjA5/2mKwvrkzkSqeW5tOVtFwWRRHIOidquf/8Je6kM9mhgkg4arudLA5SL4wyyYE1jURIgcOl8agrfdJ5Def23DIRtiOLRa8jT9cpTLFAuFHN+mrZA/LH9h0gSIg1cPb+0cMASee5uku1KjWcFer7jWA==:
E.2. EdDSA Using Curve edwards25519
The test vectors in this section use the Ed25519 key defined in
Appendix B.1.4 of [HTTP-MESSAGE-SIGNATURES]. This section include
non-normative test vectors that may be used as test cases to validate
implementation correctness.
E.2.1. Signature-Agent absent from the request
This example presents a minimal signature using the ed25519 algorithm
over test-request. The request does not contain a Signature-Agent
header.
The corresponding signature base is:
Meunier & Major Expires 7 February 2027 [Page 37]
Internet-Draft HTTP Message Signatures for Bots August 2026
NOTE: '\' line wrapping per RFC 8792
"@authority": example.com
"@signature-params": ("@authority")\
;created=1735689600\
;keyid="poqkLGiymh_W0uP6PZFw-dvez3QJT5SolqXBCW38r0U"\
;alg="ed25519"\
;expires=4889289600\
;nonce="zIW8+cdmA3vdYagbxojpONwa/l0EKJ/O3/wD486VvsQjO/RxPaSt6ZxvQaMcQzNnqKN/mQ6hpGiFro2L2qkz5A=="\
;tag="web-bot-auth"
This results in the following Signature-Input and Signature header
fields being added to the message under the label sig1:
NOTE: '\' line wrapping per RFC 8792
Signature-Input: sig1=("@authority")\
;created=1735689600\
;keyid="poqkLGiymh_W0uP6PZFw-dvez3QJT5SolqXBCW38r0U"\
;alg="ed25519"\
;expires=4889289600\
;nonce="zIW8+cdmA3vdYagbxojpONwa/l0EKJ/O3/wD486VvsQjO/RxPaSt6ZxvQaMcQzNnqKN/mQ6hpGiFro2L2qkz5A=="\
;tag="web-bot-auth"
Signature: sig1=:QKN4fTdIYfh82fvoZCQiQA1weuozfCS/Led2zTMbewMMqH8PI2Wsy/5c4ao6B6D09nraNQdBNOADg8aM1MqfCg==:
E.2.2. Signature-Agent included present on the request
This example presents a minimal signature using the ed25519 algorithm
over test-request. The request contains a Signature-Agent header.
The corresponding signature base is:
NOTE: '\' line wrapping per RFC 8792
"@authority": example.com
"signature-agent";key="agent2": "https://signature-agent.test"
"@signature-params": ("@authority" "signature-agent";key="agent2")\
;created=1735689600\
;keyid="poqkLGiymh_W0uP6PZFw-dvez3QJT5SolqXBCW38r0U"\
;alg="ed25519"\
;expires=4889289600\
;nonce="n9p433xm+NJ3ph3upfBIGmsuwHw387YV7Q/F+6BSpGCVjYCqQw6rznNA8PVVLySrAWsv0hQtFioQb6E1YsauiA=="\
;tag="web-bot-auth"
This results in the following Signature-Input and Signature header
fields being added to the message under the label sig2:
Meunier & Major Expires 7 February 2027 [Page 38]
Internet-Draft HTTP Message Signatures for Bots August 2026
NOTE: '\' line wrapping per RFC 8792
Signature-Agent: agent2="https://signature-agent.test"
Signature-Input: sig2=("@authority" "signature-agent";key="agent2")\
;created=1735689600\
;keyid="poqkLGiymh_W0uP6PZFw-dvez3QJT5SolqXBCW38r0U"\
;alg="ed25519"\
;expires=4889289600\
;nonce="n9p433xm+NJ3ph3upfBIGmsuwHw387YV7Q/F+6BSpGCVjYCqQw6rznNA8PVVLySrAWsv0hQtFioQb6E1YsauiA=="\
;tag="web-bot-auth"
Signature: sig2=:RdNFx5Bj6au3YgAMQL/RzmUlZE8QZLIaXGRpw985hWnwPfMxT228NMk6ehRS1PSl4e8PhbNZACSanGdhEwYCCg==:
E.2.3. Legacy Signature-Agent, sf-string
Retained for implementers migrating to the dictionary form
(Section 5.2.1). Do not copy it into new deployments.
This example presents a minimal signature using the ed25519 algorithm
over test-request. The request contains a Signature-Agent header.
The corresponding signature base is:
NOTE: '\' line wrapping per RFC 8792
"@authority": example.com
"signature-agent": "https://signature-agent.test"
"@signature-params": ("@authority" "signature-agent")\
;created=1735689600\
;keyid="poqkLGiymh_W0uP6PZFw-dvez3QJT5SolqXBCW38r0U"\
;alg="ed25519"\
;expires=1735693200\
;nonce="e8N7S2MFd/qrd6T2R3tdfAuuANngKI7LFtKYI/vowzk4lAZYadIX6wW25MwG7DCT9RUKAJ0qVkU0mEeLElW1qg=="\
;tag="web-bot-auth"
This results in the following Signature-Input and Signature header
fields being added to the message under the label sig2:
NOTE: '\' line wrapping per RFC 8792
Signature-Agent: "https://signature-agent.test"
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=:jdq0SqOwHdyHr9+r5jw3iYZH6aNGKijYp/EstF4RQTQdi5N5YYKrD+mCT1HA1nZDsi6nJKuHxUi/5Syp3rLWBA==:
Meunier & Major Expires 7 February 2027 [Page 39]
Internet-Draft HTTP Message Signatures for Bots August 2026
Appendix F. Implementations
This draft has a couple of public implementations. A demonstration
server has been deployed to https://http-message-signatures-
example.research.cloudflare.com/ (https://http-message-signatures-
example.research.cloudflare.com/).
It uses ed25519 example signing and verifying keys defined in
Appendix B.1.4 of [HTTP-MESSAGE-SIGNATURES].
F.1. Clients
draft-meunier-webbotauth-httpsig-protocol-00
* Chrome MV3 (https://github.com/cloudflare/web-bot-auth)
(TypeScript)
* Cloudflare Workers (https://github.com/cloudflare/web-bot-auth)
(TypeScript)
* Rust binaries (https://github.com/cloudflare/web-bot-auth) (Rust)
draft-meunier-web-bot-auth-architecture-03
* Puppeteer script (https://github.com/stytchauth/web-bot-auth-
example) (JavaScript)
* Guzzle middleware (https://github.com/olipayne/guzzle-web-bot-
auth-middleware) (PHP)
* Python script (https://zenn.dev/oymk/articles/944069e5eddc27)
(Python)
* Bot-Authentication (https://github.com/cyberstormdotmu/bot-
authentication) (Python)
* HTTPie plugin (https://github.com/cloudflare/web-bot-auth)
(Python)
* Web scrapers (scrapy/crawl4ai)
(https://github.com/cyberstormdotmu/bot-authentication) (Python)
* HUMAN Verified AI Agents (https://github.com/HumanSecurity/human-
verified-ai-agent) (Python)
* Linzer
(https://github.com/nomadium/linzer/blob/master/spec/integration/
cloudflare_example_research_spec.rb) (Ruby)
Meunier & Major Expires 7 February 2027 [Page 40]
Internet-Draft HTTP Message Signatures for Bots August 2026
F.2. Servers
draft-meunier-webbotauth-httpsig-protocol-00
* Cloudflare Workers (https://github.com/cloudflare/web-bot-auth)
(TypeScript)
draft-meunier-web-bot-auth-architecture-03
* Caddy plugin (https://github.com/cloudflare/web-bot-auth) (Go)
* Apache module (https://github.com/garyillyes/web-bot-auth-apache)
(C)
F.3. Test vectors
* In JSON format (https://github.com/cloudflare/web-bot-
auth/blob/main/packages/web-bot-auth/test/test_data/
web_bot_auth_architecture_v2.json)
Acknowledgments
The editor would also like to thank the following individuals (listed
in alphabetical order) for feedback, insight, and implementation of
this document - Marwan Fayed, Maxime Guerreiro, Scott Hendrickson,
Jonathan Hoyland, Nikhil Kandoi, Akshat Mahajan, Mark Nottingham,
Eugenio Panero, Lucas Pardue, Malte Ubl, Loganaden Velvindron, Tanya
Verma.
Changelog
draft-meunier-webbotauth-httpsig-protocol-01
* Add an Identifiers and Trust Model section: opaque and domain
binding modes.
* Describe the document as a protocol throughout (was:
architecture).
* Fold draft-meunier-webbotauth-httpsig-directory into this document
with its IANA registrations, and move to Standards Track.
* Anchor identity on the resolved Signature-Agent URL rather than
the key. Rotation is the same URL serving a new key; the
thumbprint identifies only when no URL is sent. A directory value
is an origin, identifiers are normalized before comparison, and
kid equals the key thumbprint.
Meunier & Major Expires 7 February 2027 [Page 41]
Internet-Draft HTTP Message Signatures for Bots August 2026
* Define attribution: lookup on the (URL, key) pair, what
redistributed key material must carry, which source wins when two
disagree, what a failed resolution means, a bound on the
resolution behind it, and rejection of directory response
signatures dated in the future.
* When chaining, an outer signature covering an inner signature MUST
also cover its signature-input, signature-agent, and every
component the inner signature covered. Verifiers validate each
signature independently.
* Say what a signature does not reach: not the body without Content-
Digest, and not the method or path when only @authority is
covered. Correct the relabeling guidance, and note how to migrate
from the sf-string form.
* Move the domain binding to an appendix. Add objectives, the
relationship with anonymous bot authentication, a use case to
identifier mapping, what an unsigned request tells a verifier, and
the worst case for a compromised key.
* Note how field compression treats reused and per-request
signatures, and why that is not a reason to widen coverage.
draft-meunier-webbotauth-httpsig-protocol-00
* Rename draft from draft-meunier-web-bot-auth-architecture.
* Add SSRF guidance for Signature-Agent directory fetches.
* Add deployment guidance for verifier outcomes, directory fetches,
caching, retry, rollout, proxies, CORS, and observability.
* Add guidance for test keys, static signatures, and discovery
failures.
* Add multiple Web Bot Auth signatures and an example.
* Add typed Signature-Agent discovery examples for directory,
jwks_uri, and cimd.
* Group implementations by the draft version that added them.
* Clarify that Signature-Input keyid selects the key and Signature-
Agent points to candidate key material.
* Note Signature-Key as an optional discovery header.
Meunier & Major Expires 7 February 2027 [Page 42]
Internet-Draft HTTP Message Signatures for Bots August 2026
* Align examples with published test-vector fixtures.
* Fix typos.
draft-meunier-web-bot-auth-architecture-05
* Add Sandor Major as an author.
* Add session protocol considerations.
* Update HTTP Message Signatures test vectors.
* Keep legacy Signature-Agent string examples for implementers
migrating to dictionary members.
draft-meunier-web-bot-auth-architecture-04
* Change Signature-Agent to a Structured Fields dictionary.
* Add a security consideration for intermediaries that relabel
Signature-Agent members.
* Allow @target-uri as a replacement for @authority.
* Add contributors.
* Add implementations.
* Remove the purpose field from the Web Bot Auth example.
draft-meunier-web-bot-auth-architecture-03
* Update the Linzer example URL.
* Fix the section reference and name for status code 429.
* Fix typos.
draft-meunier-web-bot-auth-architecture-02
* Add response status codes.
* Add references for readability.
* Add text about signing extra headers.
* Add TLS guidance to Security Considerations.
Meunier & Major Expires 7 February 2027 [Page 43]
Internet-Draft HTTP Message Signatures for Bots August 2026
* Add RSASSA-PSS examples.
* Update acknowledgments.
* Add PHP, Python, Ruby, and Rust implementations.
* Fix Signature-Agent in the architecture diagram to use Structured
Fields.
* Fix test vectors to use Structured Fields for Signature-Agent.
* Fix typos.
draft-meunier-web-bot-auth-architecture-01
* Require clients to sign Signature-Agent when it is present.
* Add test vectors for requests with and without Signature-Agent.
* Fix the example diagram.
* Add reverse proxy security considerations.
* Update text about why an origin may request a new signature.
* Update nonce validation wording and uniqueness requirements.
* Add acknowledgments.
draft-meunier-web-bot-auth-architecture-00
* Initial draft.
* Describe how to use HTTP Message Signatures to sign requests.
* Describe signature verification.
* Define the web-bot-auth tag.
* Derive keyid from the JWK Thumbprint.
* Add initial Security and Privacy Considerations.
Authors' Addresses
Thibault Meunier
Cloudflare
Email: ot-ietf@thibault.uk
Meunier & Major Expires 7 February 2027 [Page 44]
Internet-Draft HTTP Message Signatures for Bots August 2026
Sandor Major
Google
Email: ietf@sandormajor.com
Meunier & Major Expires 7 February 2027 [Page 45]