All notable changes to this project are documented here. The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[0.6.0] - 2026-06-21
Security
AttestoClient.Discoveryhardens its discovery/JWKS fetches against SSRF: redirects are no longer followed (a 3xx surfaces as{:http_status, _}rather than being chased to itsLocation), and a URL whose host resolves to a loopback, private, link-local, or unique-local address is rejected with:blocked_host— so an attacker-influencedissuer/jwks_uricannot point a server-side fetch at an internal service or the cloud metadata endpoint. An unresolvable host is left to the transport.
Added
AttestoClient.IDToken- verify OpenID Connect ID Tokens against authorization server JWKS/discovery, including issuer, audience,azp, expiration, issued-at, nonce,max_age/auth_time, and detachedat_hash/c_hash/s_hashvalidation. Interop-tested againstAttesto.IDToken.mint/4.AttestoClient.IdentityAssertion- build Identity Assertion JWT Authorization Grant assertions (ID-JAG / EMA) with theoauth-id-jag+jwtheader and the requirediss/sub/aud/client_id/jti/iat/expclaims. Interop-tested againstAttesto.IdentityAssertion.verify/3.AttestoClient.PKCE- generate S256 PKCE verifier/challenge pairs, delegating challenge computation toAttesto.PKCE.challenge/1so generated pairs verify underAttesto.PKCE.verify/3.AttestoClient.SignedIntrospection- verify RFC 9701 signed token introspection responses against authorization-server JWKS/discovery. Interop-tested againstAttesto.SignedIntrospection.response_jwt/4.AttestoClient.UserInfo- verify signed OpenID Connect UserInfo JWT responses, including issuer/audience/subject checks and optional binding to a previously verified ID Token subject.- Internal AttestoClient.Verifier shared by the AS-signed JWT verifiers (not public API; hidden from docs).
AttestoClient.ClientAssertion- buildprivate_key_jwtclient authentication assertions (RFC 7523 / OpenID Connect Core §9), signed with the client's own key. Carries a cross-language parity test against an independent PyJWT reference verifier, plus in-family interop againstAttesto.ClientAssertion.verify/5.AttestoClient.RequestObject- build signed authorization request objects (JAR, RFC 9101 / FAPI 2.0 Message Signing §5.3.1): the caller's authorization parameters wrapped with the iss/aud/iat/nbf/exp/jti envelope and theoauth-authz-req+jwttyp, signed with the client's key. The lifetime is bounded to the FAPI 60-minute window. Parity-tested against an independent PyJWT reference and in-family againstAttesto.RequestObject.verify/3under the FAPI Message Signing policy.- Internal AttestoClient.Builder shared by the builders (not public API; hidden from docs).
AttestoClient.JARM- verify a signed authorization response (JARM, FAPI 2.0 Message Signing §5.4): JWS signature against the authorization server's JWKS (FAPI algorithm allow-list,nonerejected, kid selection), plusiss/aud/iat/exp, returning the response parameters. Parity-tested by verifying a JARM token signed by an independent PyJWT signer (the flipped external direction) and one signed byAttesto.JARM.response_jwt/4(in-family).AttestoClient.Discovery- fetch and read OAuth 2.0 / OpenID Connect authorization-server metadata and JWKS (RFC 8414 / OpenID Connect Discovery 1.0) overReq, withhttpsand RFC 8414 §3.3 issuer-match validation. Verified in-family againstAttesto.OpenIDDiscovery.metadata/2output.
Changed
- Require
attesto ~> 0.9so the client mirror can use the current ID Token, ID-JAG, PKCE, signed introspection, signing-algorithm, and hash primitives.