v1.20.4
Part of the Q3–Q4 2026 — eIDAS deadline & ecosystem refresh milestone.
Security
- Unknown JWS
critextensions are now rejected on every JOSE verify lane (RFC 7515 §4.1.11). openvc processes no JWS extension header parameters, so a token marking any as critical must fail closed — but the hand-rolled JWS lanes (the SD-JWT issuer JWT and KB-JWT, and the IETF status-list token) accepted them regardless of PyJWT version, and the VC-JWT lane inherited pre-2.13 PyJWT behaviour (CVE-2026-32597). All lanes — VC-JWT (the ML-DSA one included), SD-JWT, KB-JWT, status-list token — now reject through one shared check (reject_unknown_crit), matching the stance the COSE and JWE paths already took. Regression tests per lane, the publicverify_status_list_tokenentry point and the error-precedence ordering included. An adversarial review (parser tricks incl. duplicate / unicode-escapedcritkeys, lane completeness across every public entry point, precedence, hostile shapes,verify_manyisolation, global state) found no bypass; its coverage recommendations are these tests. (#125) - PyJWT floor raised to
>=2.13— 2.13.0 (2026-05-21) is a security release. The advisory-by-advisory reachability audit through openvc's usage is recorded indocs/audit/assurance.md§5: thePyJWK/PyJWKClient/ HMAC-confusion classes are structurally unreachable (allow-list before crypto, noPyJWK(Client), SSRF-guarded JWKS fetch); thecrit(CVE-2026-32597) andb64=false(CVE-2026-48525) classes were reachable pre-2.13 on the VC-JWT lane and are closed by the floor plus the openvc-sidecritrejection above.cryptography49.0.0 compatibility confirmed. (#125)
Verification for this release: flake8 + mypy clean; pytest 1217 passed / 20 skipped (coverage gate met); adversarial review clean (no bypass; findings were coverage recommendations, all addressed); sdist + wheel built and twine check passed; full CI matrix green (py3.10–3.14 + the pyld 2.0.4 floor leg); published to PyPI via Trusted Publishing with digital attestations.