Repository navigation
Track signature-key -07: algorithm determination, hwk alg, and negotiation headers #1
Description
The draft-hardt-httpbis-signature-key draft is being revised. The JS implementation is tracking -07 on a v2 branch (hellocoop/packages-js#65) and this repo will need the same changes. -07 is not wire compatible with -05/-06 in either direction, and the protocol has no version negotiation.
Filing this so the Swift side is not caught by surprise — the draft is not adopted and -07 is not final, so nothing needs to move today.
Algorithm determination is inverted
This is the substantive one, and the part most likely to be wrong by construction rather than by omission.
The algorithm is now taken from the JWK alg member and must never be derived from kty + crv. Those underdetermine it:
- an RSA key has no
crvat all, andkty: "RSA"fixes neither the padding scheme nor the hash - an EC
crvfixes the curve but not the hash - the
AKPkey type (RFC 9964, post-quantum) covers several ML-DSA parameter sets
Only OKP is self-determining. Specifics:
algis REQUIRED on any conveyed or referenced JWK and must be fully specified (RFC 9864). The polymorphicEdDSAidentifier is rejected — useEd25519/Ed448.- A key whose
ktyorcrvdisagrees with itsalgmust be rejected, not resolved in favour of either reading. - Symmetric material (
oct,HS*) is rejected outright — every scheme distributes a public key. none, and any algorithm whose JOSE Implementation Requirement isProhibited, are rejected (RFC 9421 §3.3.7).- Identifiers come from the JOSE "JSON Web Signature and Encryption Algorithms" registry (RFC 7518), not the HTTP Signature Algorithms registry.
- The RFC 9421
algsignature parameter is not used: signers must not emit it, verifiers must ignore it. Note it must still be reproduced verbatim in the signature base when present, since@signature-paramsis covered by the signature — ignoring is not discarding.
Wire changes
-05/-06 |
-07 |
|
|---|---|---|
| hwk | sig=hwk;kty="OKP";crv="Ed25519";x="..." |
sig=hwk;alg="Ed25519";kty="OKP";crv="Ed25519";x="..." |
hwk alg |
forbidden | required |
hwk kid |
tolerated | rejected |
| scheme negotiation | ;sigkey= parameter on Accept-Signature |
Accept-Signature-Scheme / Accept-Signature-Alg header fields, Lists of Tokens |
| error algorithms | supported_algorithms member |
Accept-Signature-Alg |
| unknown scheme | implementation-defined | unsupported_scheme error code |
The hwk alg flip is the nasty one: forbidden in -06, required in -07, so the two are mutually unintelligible with nothing to negotiate over.
Enforcement
- Covering
signature-keyis mandatory and cannot be disabled — an uncoveredSignature-Keyheader can be substituted without invalidating the signature. - The
jwtscheme must validateexp; it bounds how long the confirmation key the assertion carries stays acceptable.
cross-test/ will break on its own schedule
cross-test/ pulls @hellocoop/httpsig from npm. When the JS side publishes 2.0 to latest, that cross-test starts running against an implementation this repo does not match, and will fail for reasons unrelated to any change here.
Worth pinning cross-test/package.json to ^1.7.1 now, then moving to the alpha dist-tag deliberately when this work starts. 2.0 prereleases publish under alpha specifically so latest keeps serving 1.x, but a floating range would still pick up 2.0 once it is released.
References
- Draft changes: BCP 14 audit of every SHOULD, and post-quantum rationale corrections dickhardt/signature-key#24
- JS implementation and full migration notes: httpsig 2.0: track draft-hardt-httpbis-signature-key-07 packages-js#65,
httpsig/MIGRATING-2.0.md
Revision correction: this work lands in -08, not -07. -07 was published to the datatracker on 2026-07-05 and was editorial (an Introduction paragraph citing AAuth and Email Verification). The hwk alg parameter was forbidden in -06 and -07 and becomes required in -08, so the break is -07 → -08. References to -07 below should be read as -08.
Activity