| Internet-Draft | x402-rfc9421-binding | June 2026 |
| Hopley | Expires 15 December 2026 | [Page] |
This document specifies the normative binding of RFC 9421 (HTTP Message Signatures) and RFC 9530 (Digest Fields for HTTP) to the x402-foundation/x402 challenge/response payment flow. It defines the minimum covered-components set for an x402 challenge response and a payment proof submission, the RFC 9530 Content-Digest discipline, keyid resolution patterns, and the multi-hop proxy-chain survival property that the x402 transport requires.¶
This binding is complementary to the existing
http-message-signatures extension in the x402 specification,
which specifies agent identity and registration (registrationUrl,
signatureSchemes, tags). This document specifies the normative
binding: which components MUST be covered, how Content-Digest is
handled, and how signatures survive multi-hop proxy chains. The two
compose cleanly in a deployment that uses both.¶
A reference implementation is provided as
algovoi-rfc9421-verifier on PyPI and npm (Apache 2.0), with
Python and TypeScript byte-for-byte parity, cross-validated against
external fixture sets.¶
This document is an Independent Submission filed per RFC 4846 and is intended for publication as Informational. It is not an IETF Standards Track document, does not represent IETF community consensus, and has not been subject to review by an IETF Working Group. Change control resides with the document author. The binding specified is one approach among possible alternatives; implementers may choose this approach, alternative approaches, or hybrid approaches as appropriate to their requirements.¶
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/.¶
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 15 December 2026.¶
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.¶
The x402-foundation/x402 specification defines an HTTP 402-based challenge/response payment flow. It specifies the payment-payload signature semantics (which sign the payment proof content) but does not normatively specify:¶
This document closes those gaps by providing a normative binding of RFC 9421 and RFC 9530 to the x402 challenge/response flow. The binding is transport-layer and additive: it adds message-integrity signing on the HTTP request/response envelope without modifying the existing payment-payload signature semantics.¶
This document specifies:¶
This document does NOT specify:¶
http-message-signatures extension
(registrationUrl, signatureSchemes, tags).¶
This document normatively references:¶
This document is complementary to:¶
http-message-signatures extension -- agent identity
and registration. This document specifies the normative binding
that the identity extension assumes.¶
This document is distinct from message-signing extensions for agent-to-agent protocols. The Envoys signature/v1 extension (proposed on the a2aproject/A2A repository) targets A2A task envelopes, not x402 HTTP requests. A2A messages have a different envelope shape than x402 HTTP challenge/response and require their own composition. This extension covers only the x402 HTTP request and response shape; the two layers are orthogonal.¶
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.¶
x402 challenge response: the HTTP 402 response emitted by a resource server per the x402 base specification, carrying the payment challenge.¶
payment proof submission: the HTTP request carrying the buyer-agent's payment proof, submitted to the resource server per the x402 base specification.¶
covered components: the set of RFC 9421 component identifiers
included in the Signature-Input header and covered by the
detached signature.¶
signing base: the canonical byte string constructed per RFC 9421 Section 2.5 over which the signature is computed.¶
proxy-chain survival: the property that an RFC 9421 signature remains verifiable at the final destination after traversing one or more intermediate proxy hops, provided no covered component is modified in transit.¶
An x402 challenge or response that adopts this binding MUST carry the following HTTP headers:¶
Signature-Input: per RFC 9421, with covered components from
the closed set defined in Section 4.¶
Signature: per RFC 9421, carrying the detached signature over
the signing base.¶
Content-Digest: per RFC 9530, carrying a digest of the message
body under the discipline defined in Section 5.¶
The following header is OPTIONAL:¶
Signature-Algorithm: an extension parameter indicating the
algorithm class, when the verifier needs this information at
admission time without resolving the keyid.¶
The signing base is constructed per RFC 9421 Section 2.5. When the
x402 payload body is canonicalised under the JCS discipline pinned
by draft-hopley-x402-canonicalisation-jcs-v1, the
content-digest covered component commits the signature to the
JCS-canonical bytes of the body. Component identifiers are quoted
per RFC 9421 Section 2.5. The @signature-params component is
included in the signing base by RFC 9421 mandate.¶
Implementations MUST cover the following RFC 9421 components on an x402 challenge response:¶
| Component | Source | Rationale |
|---|---|---|
@method
|
HTTP method of the request that triggered the 402 | Binds the signature to the request method |
@authority
|
HTTP authority of the resource being challenged | Binds the signature to the resource origin |
@path
|
HTTP path of the resource being challenged | Binds the signature to the resource path |
content-digest
|
RFC 9530 Content-Digest of the response body | Binds the signature to the body integrity |
Implementations MAY additionally cover RFC 9421 derived components per facilitator-specific need. The minimum covered set above is normative.¶
The covered set on a payment proof submission MUST include:¶
| Component | Source |
|---|---|
@method
|
HTTP method of the proof submission |
@path
|
HTTP path of the proof submission |
content-digest
|
RFC 9530 Content-Digest of the proof body |
created
|
RFC 9421 created parameter |
The created parameter is REQUIRED on payment proof submissions to
bind the signature to a specific point in time and prevent replay
of a valid payment proof against a fresh challenge.¶
The covered-components minimum sets defined in Sections 4.1 and 4.2
are normative. Implementations MUST include the minimum set.
Implementations MAY add additional components; they MUST NOT remove
components from the minimum set. New mandatory components MAY be
introduced only by a normative successor document
(rfc9421-x402-binding-v2 or higher).¶
Implementations MUST emit Content-Digest using the sha-256
algorithm (mandatory per RFC 9530) for all x402 message bodies.¶
Implementations SHOULD additionally emit sha-512 for bodies at or
above 4096 bytes, per RFC 9530 implementation guidance.¶
Verifiers MUST accept both sha-256 and sha-512 digest
algorithms.¶
Verifiers MUST NOT silently skip Content-Digest verification when
only an unsupported algorithm is present in the header. When the
Content-Digest header is present but contains only algorithms the
verifier does not support, the verifier MUST treat the header as if
no usable digest were present and MUST reject the message. Silent
skip would defeat the body-integrity binding the signature
provides.¶
The RFC 9421 signature over an x402 message MUST survive byte-identically across multi-hop proxy chains (for example, CDN edge to reverse proxy to application server) provided that each intermediate hop:¶
Content-Digest header.¶
Verifiers SHOULD re-derive the signing base from the as-received headers without normalising them. The signature verifies byte-for-byte against the bytes the original signer covered, regardless of the number of intervening proxy hops.¶
The conformance fixture set rfc9421_proxy_chain_v1 in the
AlgoVoi JCS conformance vectors repository provides byte-level
proof of this property across a three-hop proxy chain topology,
using the RFC 9421 Section 2.5-conformant signing base specified by
this document. (The earlier rfc9421_proxy_chain_v0 set uses a
legacy, pre-conformance signing base and is retained only as a
historical companion.) See Appendix A for the repository reference.¶
The keyid parameter on the Signature-Input header MUST be a
stable identifier for the signing key. Implementations MAY use
either of the following resolution patterns:¶
keyid is a DID URI (e.g. did:web:...). The
verifier resolves the DID document to obtain the public key
material, using the standard DID resolution procedure for the
DID method.¶
keyid is an HTTPS URL that returns a JSON
object containing the public key, following the Envoys
signature/v1 convention. The verifier fetches the URL to obtain
the public key material.¶
Both patterns MUST be supported by conformant verifiers. A verifier
that supports only one pattern MUST reject Signature-Input headers
whose keyid is in the unsupported format rather than treating
verification as passed.¶
This binding composes with the x402 challenge/response flow as follows:¶
Signature-Input,
Signature, and Content-Digest headers per Section 3.¶
The transport-layer message-integrity signing defined by this binding is additive to the existing x402 payment-payload validation. Existing x402 payload signatures, which sign the payment proof content per the x402 base specification, are unchanged. This binding adds an additional layer of transport-layer signing on the HTTP request/response envelope.¶
This binding composes with the AlgoVoi-authored receipt format suite:¶
This binding is additive. Resource servers that do not adopt RFC 9421 signing on x402 messages are unaffected. Buyer-agents that do not verify transport-layer signatures continue to function as before, subject to their own signature discipline. Adoption is opt-in per-deployment.¶
A resource server that adopts this binding MUST NOT reject x402
requests from buyer-agents that do not include Signature-Input
headers, unless the resource server's policy explicitly requires
transport-layer signing. The binding is additive at the sender
level; enforcement is a resource-server policy decision.¶
This document defines no new IANA registrations. The HTTP header
fields referenced (Signature-Input, Signature, Content-Digest,
Signature-Algorithm) are registered by RFC 9421 and RFC 9530
respectively.¶
The extension identifier rfc9421-x402-binding-v1 is an x402
extension identifier. Registration with any IANA registry is not
requested at this time.¶
The minimum covered set (method, authority, path, content-digest) binds the signature to the specific resource and its body. An attacker cannot replay a valid challenge response against a different resource or path without invalidating the signature. Implementations that add additional covered components increase the binding strength; they MUST NOT remove components from the minimum set.¶
The created parameter is REQUIRED on payment proof submissions
(Section 4.2). This binds the proof signature to a specific
instant and prevents replay of a valid payment proof against a
fresh challenge from the same resource server. Resource servers
SHOULD enforce a created freshness window appropriate to their
risk model.¶
The rejection rule in Section 5 (verifiers MUST NOT silently skip Content-Digest when only an unsupported algorithm is present) is a security requirement. Silent skip would allow an attacker to present a message with a body that differs from what the signer covered, by substituting an unsupported algorithm name in the Content-Digest header. The mandatory rejection rule closes this gap.¶
The proxy-chain survival property defined in Section 6 requires
that covered components and the Content-Digest header are not
modified by intermediate hops. A proxy that modifies any covered
component (e.g. rewrites the Host header that maps to
@authority) will invalidate the signature at the destination.
Operators deploying this binding in environments with header-
rewriting proxies MUST ensure that covered components are not
modified in transit, or MUST exclude the affected components from
the covered set (subject to the minimum-set constraint).¶
Both DID-based and HTTPS-URL-based keyid resolution fetch public key material at verification time. If the key at the resolution endpoint changes between signature creation and verification (key rotation), verification will fail. Implementations SHOULD cache resolved keys with an appropriate TTL and SHOULD implement key rollover signalling per their chosen DID method or HTTPS-URL convention.¶
The following open-source implementation conforms to this binding:¶
algovoi-rfc9421-verifier (Python) on PyPI:
https://pypi.org/project/algovoi-rfc9421-verifier/
Apache 2.0 licensed. Implements RFC 9421 verification with
default signing base mode rfc9421. 23 internal unit tests
passing.¶
@algovoi/rfc9421-verifier (TypeScript) on npm:
https://www.npmjs.com/package/@algovoi/rfc9421-verifier
Byte-for-byte parity with the Python sibling. Apache 2.0
licensed. 18 internal unit tests passing.¶
Cross-validated against external fixture sets: 7 of 7 verifiable
vectors PASS across envoys-rfc9421 (jschoemaker/Envoys-public,
5 positive verifiable plus 2 manifest-declared non-verifiable) and
hippo-rfc9421 (opena2a-org/a2a-idf-conformance, 2 composition
vectors).¶
Conformance fixture set for proxy-chain survival:¶
https://github.com/chopmob-cloud/algovoi-jcs-conformance-vectors/tree/main/vectors/rfc9421_proxy_chain_v1¶
The rfc9421_proxy_chain_v1 fixture set provides byte-level
reference vectors for the three-hop proxy-chain topology described
in Section 6, including the as-received header bytes at each hop
and the expected signing-base bytes at the final destination. It uses
the RFC 9421 Section 2.5-conformant signing base specified by this
document; the legacy rfc9421_proxy_chain_v0 set (pre-conformance
signing base) is retained only as a historical companion.¶
This document, the binding it specifies, and the conformance vectors derived from it are AlgoVoi work under sole AlgoVoi authorship. Substrate authorship history is catalogued at https://docs.algovoi.co.uk/substrate-authorship-provenance.¶
The canonicalisation discipline referenced in Section 3 is normatively specified in draft-hopley-x402-canonicalisation-jcs-v1 under the same authorship.¶
The author acknowledges Anders Rundgren as the editor of RFC 8785, the JSON Canonicalization Scheme referenced by the canonicalisation discipline, and the authors of RFC 9421 (Backman, Richer, Sporny) and RFC 9530 (Polli, Pardue) whose specifications this binding composes with.¶
Updated the proxy-chain conformance fixture reference (Section 6 and
Appendix A) from rfc9421_proxy_chain_v0 to
rfc9421_proxy_chain_v1. The v1 fixture set uses the RFC 9421
Section 2.5-conformant signing base normatively specified by this
document (case-preserved @method, the created value as a
signature parameter, and the trailing @signature-params line);
the earlier v0 set used a pre-conformance signing base and is retained
in the repository only as a labelled legacy companion. No normative
requirements changed.¶