Signature-Input
Verifying an HTTP message signature requires knowing which components were signed and with which parameters. The Signature-Input request and response header declares this metadata as the companion to the Signature header.
Usage
While the Signature header carries the cryptographic signature bytes, Signature-Input declares which message components are covered by the signature and includes metadata such as the signing algorithm, key identifier, and timestamps.
Each entry in Signature-Input is a labeled inner list of covered component identifiers followed by signature parameters. The label matches a corresponding entry in the Signature header. This pairing allows a verifier to reconstruct the signature base from the same components, then validate the signature using the declared algorithm and key.
The header applies to both requests and responses.
Request signatures cover components like the method,
authority, and path. Response signatures cover the
status code and response headers, and bind back to
the original request using the ;req flag on
request-derived components.
Directives
Covered components
The inner list specifies which parts of the HTTP
message are signed. Components fall into two
categories: derived components prefixed with @,
and standard HTTP header fields
referenced by name.
Derived components for requests:
@method- the HTTP method (GET, POST, etc.)@authority- the host and optional port@path- the absolute path@query- the query string including the leading?@query-param- an individual named query parameter@target-uri- the full target URI@scheme- the URI scheme (http or https)@request-target- the request-line target
Derived component for responses:
@status- the three-digit status code
Any HTTP header name is also valid as a covered
component. Common choices include content-type,
content-digest, content-length, and
authorization.
The ;req flag on a component means the value comes
from the request rather than the response, binding a
response signature to the original request.
alg
The alg parameter names the cryptographic
algorithm. Registered values include
rsa-pss-sha512, rsa-v1_5-sha256,
hmac-sha256, ecdsa-p256-sha256,
ecdsa-p384-sha384, and ed25519.
keyid
The keyid parameter identifies the key material
the verifier needs. The value is a string chosen
by the signer, such as "my-api-key" or
"server-key-ed25519".
created
The created parameter is a Unix timestamp
recording when the signature was generated.
Verifiers use this to enforce freshness.
expires
The expires parameter is a Unix timestamp after
which the signature is no longer valid. Combined
with created, the two parameters define a validity
window.
nonce
The nonce parameter is a random string unique to
each signature. Including a nonce prevents replay
attacks where an intercepted signed request is
resubmitted.
tag
The tag parameter is an application-specific
string describing the purpose of the signature, such
as "web-bot-auth" or "api-request".
Example
A client signs a POST request covering the
method, authority, path, content type, and content
digest. The created and expires parameters define
a five-minute validity window. The nonce prevents
replay.
Signature-Input: sig1=("@method" "@authority" "@path" "content-type" "content-digest");alg="ecdsa-p256-sha256";created=1739353800;expires=1739354100;keyid="client-ecdsa-p256";nonce="b3k2pp5k7z-50gnwp0ox2"
Signature: sig1=:MEYCIQCFsP8q2W8Uf24cOe0k8pISQv0w0bqo...:
A server signs a response, binding the signature
back to the original request. The @authority and
@method components carry the ;req flag,
indicating their values come from the request
message rather than the response.
Signature-Input: resp=("@status" "content-type" "content-digest" "@authority";req "@method";req);alg="ed25519";created=1739353801;keyid="server-key-ed25519"
Signature: resp=:dGhpcyBpcyBhIHNhbXBsZSByZXNwb25zZSBzaWduYXR1cmU=:
A minimal request signature covers only the method,
authority, and path with the date header. Fewer
covered components produce a shorter
Signature-Input value while still authenticating
the request target.
Signature-Input: sig1=("@method" "@authority" "@path" "date");alg="ed25519";created=1739353800;keyid="client-key-ed25519"
Signature: sig1=:dGhpcyBpcyBhIHNhbXBsZSBzaWduYXR1cmUgdmFsdWU=:
Two incompatible generations
Signature-Input belongs to the standardized
generation of HTTP message signing, and the wire
format separates the generations cleanly. The older
draft, known as Cavage after its author, packed
everything into a single Signature
header with a headers= list. The standard splits
the metadata into Signature-Input, naming the
covered components and parameters, with
Signature carrying only the bytes. A
validator built for one format rejects the other,
and neither relates to AWS request signing, which
rides in Authorization under a
different design.
Adoption in 2026 concentrates on bot and agent
authentication. Cloudflare's Web Bot Auth builds
directly on the standard, requiring the tag,
keyid, created, and expires parameters and
pairing the signature with a
Signature-Agent header pointing
at a key directory. OpenAI publishes a live Ed25519
key directory for exactly this exchange, letting
origins verify a crawler's signature against
published keys rather than IP ranges.
The federated web sits mid-migration. Mastodon validates standard signatures by default since 4.5, after introducing support behind a flag, while still emitting the older draft format outbound for compatibility with the wider fediverse, so a server operator sees both formats arriving today.
Signing the wrong components is the design decision
carrying consequences. Derived components such as
@authority and @path bind a signature to a
destination, and a signature omitting them survives
replay against other endpoints. The nonce and
expires parameters exist for the same reason, and
verification without checking them accepts replays
within the key's whole lifetime.