Published GitHub release for tag v0.6.1. Kept here for maintainers; do not treat as a draft for retagging.
Breaking for foreign-JWS verify callers (native signers/verifiers unchanged). Builds on v0.6.0 (Go 1.27+, jwx v4, ML-DSA).
- Preferred verify API:
NewJWSVerifier(allowed, key, …)infers the JWS algorithm fromjwk.Key,*ecdsa.PublicKey, or*mldsa.PublicKey. NewJWSSignerFromJWK: infer alg from a privatejwk.Keyand sign (symmetric with preferred verify for JWK-stored keys).- Escape hatch:
NewJWSVerifierWithAlg(allowed, alg, key, …)when alg cannot be inferred (raw RSA/HMAC) or the store already chose alg. Today’sNewJWSVerifier(alg, key, …)migrates here. JWSAlgAllowlist: both verify constructors take an allowlist (nilskips policy for tests/lazy use). Prefer a non-nil allowlist whenkeyidcan select among keys.NewJWSSigner: nil config defaults toSignAlg(false); configs withSignAlg(true)are rejected.Fields.AddRequestComponent: convenience for required associated-request components (;req), equivalent toAddHeaderExt(name, false, false, true, false).- Details by tag:
RequestDetailsByTag/ResponseDetailsByTag(strict) and*DetailsListByTag(lenient) locate signatures by thetagparameter;MessageDetails.Labelholds the dictionary member name forVerify*. Sentinels:ErrSignatureTagNotFound/ErrSignatureTagAmbiguous. - jwx bump to ≥ v4.5.0 (if not already on the release branch).
| You use | Action |
|---|---|
| Native only | No API changes. |
NewJWSVerifier(alg, key, …) |
Prefer NewJWSVerifier(allowed, key, …) when the key is inferrable; else NewJWSVerifierWithAlg(allowed, alg, key, …). |
NewJWSSigner |
Omit config or keep SignAlg(false); SignAlg(true) now errors. Prefer NewJWSSignerFromJWK when the private key is a JWK. |
HTTP SetAllowedAlgs |
Unchanged — Signature-Input alg only, not JWS jwa. |
Response ;req fields |
Prefer AddRequestComponent("@method") (etc.) over AddHeaderExt(..., false, false, true, false). |
Locate signature by tag |
Prefer RequestDetailsByTag / ResponseDetailsByTag, then Verify* on details.Label (see below). |
allowed, _ := httpsign.NewJWSAlgAllowlist(jwa.ES256(), jwa.MLDSA65())
verifier, err := httpsign.NewJWSVerifier(allowed, pubKey, verifyConfig, fields)
// or:
verifier, err := httpsign.NewJWSVerifierWithAlg(allowed, jwa.RS256(), rsaPub, verifyConfig, fields)Details by tag (when the dictionary label is not semantic):
details, err := httpsign.RequestDetailsByTag(req, "app")
if err != nil {
return err // includes ErrSignatureTagNotFound / ErrSignatureTagAmbiguous
}
// use details.KeyID to obtain verifier, then:
err = httpsign.VerifyRequest(details.Label, *verifier, req)ML-DSA:
priv, _ := mldsa.GenerateKey(mldsa.MLDSA65())
pub := priv.Public().(*mldsa.PublicKey)
allowed, _ := httpsign.NewJWSAlgAllowlist(jwa.MLDSA65())
signer, _ := httpsign.NewJWSSigner(jwa.MLDSA65(), priv, nil, fields)
// or, when the private key is a JWK:
// signer, _ := httpsign.NewJWSSignerFromJWK(privJWK, nil, fields)
verifier, _ := httpsign.NewJWSVerifier(allowed, pub, httpsign.NewVerifyConfig(), fields)Design notes: internal-docs/JWS-ALG-POLICY.md.