Skip to content

Commit 03fa6bb

Browse files
yaronfcursoragent
andcommitted
docs: add v0.6.0 release notes draft and README upgrade guide
Document jwx v4 migration, ML-DSA foreign JWS usage, and SignAlg/SetAllowedAlgs for v0.6.0 callers. Co-authored-by: Cursor <cursoragent@cursor.com>
1 parent ccf8fd7 commit 03fa6bb

3 files changed

Lines changed: 95 additions & 1 deletion

File tree

README.md

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,39 @@ in the [API reference](https://pkg.go.dev/github.com/yaronf/httpsign).
2626
serverText, _ := io.ReadAll(res.Body)
2727
_ = res.Body.Close()
2828
```
29+
30+
### Upgrading from v0.5.x
31+
32+
**v0.6.0** is a breaking release for foreign-JWS users and raises the Go floor to **1.27+**.
33+
34+
| Caller | Change |
35+
|--------|--------|
36+
| Native algorithms only (RSA, ECDSA, Ed25519, HMAC) | Upgrade Go to 1.27+; no API changes. |
37+
| `NewJWSSignerV3` / `NewJWSVerifierV3` | Use `NewJWSSigner` / `NewJWSVerifier` with `github.com/lestrrat-go/jwx/v4/jwa`. |
38+
| `NewJWSSigner` / `NewJWSVerifier` (jwx v2) | Same: v4 import path; algorithms are functions (`jwa.ES256()`, not string constants). |
39+
40+
Foreign JWS signing must use `SignConfig.SignAlg(false)` — RFC 9421 does not define an HTTP `alg` value for arbitrary JWS algorithms. Verification policy `SetAllowedAlgs` applies to the optional HTTP `alg` signature parameter in the message, not to the JWS algorithm passed to `NewJWSVerifier`.
41+
42+
Full migration notes: [internal-docs/RELEASE-v0.6.0.md](internal-docs/RELEASE-v0.6.0.md) (maintainers: paste **Summary** into the GitHub release).
43+
44+
### Foreign JWS and ML-DSA
45+
46+
Optional algorithms beyond the native set use [`lestrrat-go/jwx/v4`](https://github.com/lestrrat-go/jwx) (≥ v4.4.0) via `NewJWSSigner` / `NewJWSVerifier`. Requires **Go 1.27+** (stdlib `encoding/json/v2`; no `GOEXPERIMENT`).
47+
48+
**ML-DSA (FIPS 204)** is supported through the same constructors with `crypto/mldsa` keys and `jwa.MLDSA44()` / `MLDSA65()` / `MLDSA87()`. RFC 9421 does not assign HTTP Message Signatures algorithm identifiers for ML-DSA; treat it like other foreign JWS algorithms (`SignAlg(false)`, JWS `alg` in the JWS layer only if your profile requires it).
49+
50+
```go
51+
priv, _ := mldsa.GenerateKey(mldsa.MLDSA65())
52+
pub := priv.Public().(*mldsa.PublicKey)
53+
signer, _ := httpsign.NewJWSSigner(jwa.MLDSA65(), priv,
54+
httpsign.NewSignConfig().SignAlg(false), fields)
55+
verifier, _ := httpsign.NewJWSVerifier(jwa.MLDSA65(), pub, httpsign.NewVerifyConfig(), fields)
56+
```
57+
58+
HMAC keys must be `[]byte` (minimum length per RFC 7518).
59+
2960
### Notes and Missing Features
3061
* Requires **Go 1.27+**.
31-
* Optional foreign JWS (including **ML-DSA** via `crypto/mldsa`) uses [`lestrrat-go/jwx/v4`](https://github.com/lestrrat-go/jwx) through `NewJWSSigner` / `NewJWSVerifier`.
3262
* The `Accept-Signature` header is unimplemented.
3363
* In responses, when using the "wrapped handler" feature, the `Content-Type` header is only signed if set explicitly by the server. This is different, but arguably more secure, than the normal `net.http` behavior.
3464
* **Behind a TLS-terminating reverse proxy:** The `@scheme` derived component defaults to `req.TLS != nil`. Behind nginx, Envoy, AWS ALB, etc., `req.TLS` is nil, so `@scheme` becomes `"http"` even for HTTPS traffic. Use `SetSchemeFromRequest` on `SignConfig` and `VerifyConfig` to derive the scheme from `X-Forwarded-Proto` or similar headers.

internal-docs/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ This directory contains internal documentation for maintainers of the httpsign l
55
## Contents
66

77
- **JWX.md** — Optional jwx / foreign-JWS: cut over to jwx v4.4.0+ on Go 1.27+ as **httpsign `v0.6.0`**, with **ML-DSA PQ signatures** as an explicit goal. Gate met 2026-08-26.
8+
- **RELEASE-v0.6.0.md** — Draft GitHub release text and upgrade guide for **v0.6.0** (copy Summary into the release when tagging).
89

910
## Purpose
1011

internal-docs/RELEASE-v0.6.0.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# Release notes draft: httpsign v0.6.0
2+
3+
Copy the **Summary** section below into the GitHub release when tagging `v0.6.0`.
4+
5+
---
6+
7+
## Summary
8+
9+
**Breaking release:** requires **Go 1.27+** and replaces dual `jwx/v2` + `jwx/v3` foreign-JWS support with a single **`github.com/lestrrat-go/jwx/v4`** dependency (≥ v4.4.0).
10+
11+
### Highlights
12+
13+
- **One foreign-JWS API:** `NewJWSSigner` / `NewJWSVerifier` only (`NewJWSSignerV3`, `NewJWSVerifierV3`, and the old v2-typed overloads are removed).
14+
- **Post-quantum (ML-DSA):** sign and verify HTTP messages with `crypto/mldsa` keys and `jwa.MLDSA44()` / `MLDSA65()` / `MLDSA87()` through the same constructors (Go 1.27 stdlib; no extra modules).
15+
- **Constructor hardening:** foreign JWS keys are validated at `NewJWS*` time (algorithm family, ECDSA curve bind per RFC 7518, HMAC minimum length, private key for signers / public key for verifiers). `jwa.NoSignature()` is rejected.
16+
- **Native algorithms unchanged** in API shape (HMAC-SHA256, RSA, RSA-PSS, P-256/P-384, Ed25519); only the Go toolchain floor moves to 1.27.
17+
18+
### Upgrade from v0.5.x
19+
20+
| You use | Action |
21+
|---------|--------|
22+
| **Native signers/verifiers only** | Bump Go to **1.27+** and upgrade httpsign. No API changes. |
23+
| **`NewJWSSignerV3` / `NewJWSVerifierV3`** | Rename to `NewJWSSigner` / `NewJWSVerifier`; change `github.com/lestrrat-go/jwx/v3/jwa``.../jwx/v4/jwa`. |
24+
| **`NewJWSSigner` / `NewJWSVerifier` (v2)** | Same as above: v4 import path and algorithm values (e.g. `jwa.ES256()`). |
25+
| **Foreign JWS signing** | Keep `SignConfig.SignAlg(false)` — RFC 9421 has no `alg` parameter for arbitrary JWS algorithms. |
26+
| **Foreign JWS verifying** | `VerifyConfig.SetAllowedAlgs` filters the HTTP **Signature** `alg` parameter if present; it does **not** select the JWS algorithm (that comes from `NewJWSVerifier`). |
27+
28+
**jwx v4 algorithm values** are functions, not string constants:
29+
30+
```go
31+
import "github.com/lestrrat-go/jwx/v4/jwa"
32+
33+
signer, err := httpsign.NewJWSSigner(jwa.ES256(), privKey, config.SignAlg(false), fields)
34+
verifier, err := httpsign.NewJWSVerifier(jwa.ES256(), &privKey.PublicKey, verifyConfig, fields)
35+
```
36+
37+
**ML-DSA example** (RFC 9421 does not register HTTP-sig algorithm names for ML-DSA; use foreign JWS with `SignAlg(false)`):
38+
39+
```go
40+
priv, _ := mldsa.GenerateKey(mldsa.MLDSA65())
41+
pub := priv.Public().(*mldsa.PublicKey)
42+
config := httpsign.NewSignConfig().SignAlg(false)
43+
44+
signer, _ := httpsign.NewJWSSigner(jwa.MLDSA65(), priv, config, fields)
45+
verifier, _ := httpsign.NewJWSVerifier(jwa.MLDSA65(), pub, httpsign.NewVerifyConfig(), fields)
46+
```
47+
48+
HMAC keys for foreign JWS must be `[]byte` (not `string`), at least 32/48/64 bytes for HS256/384/512 per RFC 7518.
49+
50+
### Toolchain
51+
52+
- **Go:** 1.27.0+ (`encoding/json/v2` in stdlib; no `GOEXPERIMENT=jsonv2`).
53+
- **jwx:** v4.4.0+ only; v2 and v3 are no longer pulled transitively.
54+
55+
### Upstream references
56+
57+
- [jwx v4 MIGRATION.md](https://github.com/lestrrat-go/jwx/blob/v4.4.0/MIGRATION.md)
58+
- [jwx v4 Changes-v4.md](https://github.com/lestrrat-go/jwx/blob/v4.4.0/Changes-v4.md)
59+
60+
### Also in v0.6.0 (non-breaking behavior fixes)
61+
62+
- `SetVerifyDateWithin` now correctly reads the HTTP `Date` header (lowercase key in parsed messages).
63+
- Defensive checks for malformed ECDSA keys, empty header value lists, and nil client/signer/verifier config.

0 commit comments

Comments
 (0)