Signature-Key Header Explainer
December 15, 2025 · View on GitHub
Signature-Key allows flexible, privacy-preserving, and interoperable key distribution for HTTP Message Signatures.
Author:
Dick Hardt
Hellō Identity
Email: dick.hardt@hello.coop
URI: https://github.com/DickHardt
Date: November 21, 2025 Status: Internet-Draft (Exploratory)
TL;DR
Signature-Key solves key distribution for HTTP Message Signatures (RFC 9421):
- sig=hwk - Pseudonymous (inline key, no identity)
- sig=jwks - Identified (explicit identity with id + optional metadata)
- sig=x509 - X.509 certificate (explicit identity via PKI trust chains)
- sig=jwt - Delegated (key inside signed JWT, enables horizontal scale)
Why: RFC 9421 defines how to sign HTTP messages but not how verifiers obtain the public key. Signature-Key provides four flexible schemes for different trust models.
Overview
The Signature-Key HTTP header provides the keying material required to verify an HTTP Message Signature (RFC 9421).
It supports four schemes representing a natural progression from pseudonymous to identified to delegated access:
sig=hwk— Header Web Key (pseudonymous, self-contained public key)sig=jwks— Identified signer (explicit identity with id, optional metadata discovery)sig=x509— X.509 certificate chain (explicit identity via PKI trust model)sig=jwt— JWT containing acnf.jwkconfirmation key (delegation and horizontal scale)
Label matching: The label (e.g., "sig") must be identical across Signature-Input, Signature, and Signature-Key headers for the same signature.
Offline verification: A verifier MAY pre-fetch, cache, or pin keys rather than performing key discovery as requests come in.
Example:
Signature-Input: sig=("@method" "@path"); created=1732210000
Signature: sig=:MEQCIA5...
Signature-Key: sig=hwk; kty="OKP"; crv="Ed25519"; x="JrQLj..."
1. sig=hwk — Header Web Key
wk provides a self-contained, pseudonymous, inline public key.
No key lookup required.
Example
Signature-Key: sig=hwk;
kty="OKP";
crv="Ed25519";
x="JrQLj5P_89iXES9-vFgrIy29clF9CC_oPPsw3c5D0bs"
Required parameters
kty— Key type (OKP,EC,RSA)crv— Curve (for OKP/EC)- Key material:
- OKP/EC:
x(andyfor EC) - RSA:
nande
- OKP/EC:
Forbidden / ignored
algMUST NOT appear (Algorithm is chosen fromSignature-Input.alg)kidSHOULD NOT be used inwkmode
When to use sig=hwk:
- Privacy-preserving agents that don't want to reveal identity
- Experimental bots testing APIs without registration
- Abuse prevention through per-key rate limiting
- Building reputation before identifying yourself
2. sig=jwks — Identified Signer
jwks mode explicitly identifies the signer using id and retrieves key material from a JWKS document.
Required parameters
id— Signer identifier (HTTPS URL)kid— Key ID used for the HTTP Signaturewell-known— OPTIONAL name of metadata document under/.well-known/
well-knowncould be shortened towk
Discovery
To discover the key, the verifier fetches:
-
If
well-knownis present: Fetch{id}/.well-known/{well-known}, parse as metadata, extractjwks_uri, then fetch the JWKS -
If
well-knownis absent: Fetch{id}directly as a JWKS
The resulting JWKS MUST contain a key whose kid matches the kid parameter in the Signature-Key header.
Examples
Direct JWKS fetch
Signature-Key: sig=jwks;
id="https://agent.example/crawler";
kid="key-1"
Verifier fetches https://agent.example/crawler directly as a JWKS.
JWKS via metadata
Signature-Key: sig=jwks;
id="https://agent.example";
well-known="agent-server";
kid="key-1"
Verifier:
- Fetches
https://agent.example/.well-known/agent-server - Parses as JSON metadata
- Extracts
jwks_uriproperty - Fetches JWKS from the
jwks_uriURL - Finds key with matching
kid
When to use sig=jwks:
- Established services with stable HTTPS identity
- Search engine crawlers, monitoring services, security scanners
- Services operating from single authority with long-lived keys
- When explicit signer entity identification is required
- To satisfy identity requirements in Agent-Auth challenges
3. sig=x509 — X.509 Certificate Chain
x509 mode provides an X.509 certificate chain via URL, enabling PKI-based trust models.
Required parameters
x5u— URL to X.509 certificate chain in PEM format (RFC 7517 Section 4.6)x5t— Certificate thumbprint: BASE64URL(SHA256(DER_bytes_of_leaf_certificate))- Enables cache lookup and key rotation detection
- Matches the
x5t#S256parameter from RFC 7515 Section 4.1.8
Example
Signature-Key: sig=x509;
x5u="https://agent.example/.well-known/cert.pem";
x5t="bWcoon4QTVn8Q6xiY0ekMD6L8bNLMkuDV2KtvsFc1nM"
The verifier:
- Check local cache for a certificate with matching
x5tthumbprint - If cached certificate found and still valid, skip to step 5
- Fetch the PEM file from the
x5uURL - Parse and validate the X.509 certificate chain:
- Verify chain of trust to a trusted root CA
- Check certificate validity (not expired, not revoked via CRL/OCSP)
- Validate certificate policies and constraints
- Verify
x5tmatches BASE64URL(SHA256(DER_bytes_of_leaf_certificate))
- Extract the public key from the end-entity certificate
- Verify the HTTP Signature using the extracted public key
- Cache the certificate indexed by
x5tfor future requests
When to use sig=x509:
- Enterprise environments with existing PKI infrastructure
- Integration with certificate management systems
- mTLS scenarios where certificates are already deployed
- When certificate-based trust chains and revocation are required
- Regulated industries requiring certificate-based authentication
Benefits of x5t parameter:
- CDN caching: CDNs can cache certificates by thumbprint without parsing the chain
- Key rotation detection: When keys at
x5uchange, thex5tchanges, signaling fresh fetch needed - Performance: Verifiers can check cache before fetching, reducing latency
- Bandwidth: Avoid re-fetching unchanged certificates on every request
Security considerations:
- Verifiers MUST validate the complete certificate chain
- Verifiers MUST check certificate revocation status (CRL or OCSP)
- Verifiers SHOULD enforce certificate policies appropriate to their security requirements
- The
x5uURL MUST use HTTPS to prevent certificate substitution attacks
4. sig=jwt — JWT With Confirmation Key
jwt embeds a JWK inside a signed JWT using the standard cnf (confirmation) claim (RFC 7800).
This scheme enables delegation and horizontal scale: a central authority issues short-lived JWTs to distributed instances, each with their own ephemeral signing key.
Example
Signature-Key: sig=jwt;
jwt="<compact-serialized-jwt>"
Requirements
The JWT MUST contain a cnf.jwk claim:
{
"iss": "https://issuer.example",
"sub": "instance-123",
"exp": 1732210000,
"cnf": {
"jwk": {
"kty": "OKP",
"crv": "Ed25519",
"x": "JrQLj5P_89iXES9-vFgrIy29clF9CC_oPPsw3c5D0bs"
}
}
}
Verifier Procedure
- Validate the JWT signature using the issuer's key
- Verify standard claims:
iss,exp,iat(per policy) - Extract the JWK from
cnf.jwk - Verify the HTTP Message Signature using that key
Use cases:
- Agent tokens binding ephemeral keys to agent server identity
- Auth tokens binding agent key to authorization grant
- Distributed services where each instance has unique ephemeral keys