JWKS rotation, identifier gates, and authserver 0.2.0 alignment - #28
Open
RobertoIskandarani wants to merge 1 commit into
Open
RobertoIskandarani wants to merge 1 commit into
RobertoIskandarani wants to merge 1 commit into
Conversation
Brings main up to the current development line. The CHANGELOG's [Unreleased] section is the authoritative list; the themes are: - A rotated jwks_uri is followed on ordinary verification traffic, and jwks_uri is resolved per key-set fetch rather than captured at construction. A failed document refresh now backs off instead of being retried by the next reader. - Resource and issuer identifiers are gated at construction: absolute URL with a scheme and a host, no fragment, no userinfo. - DPoP: the RFC 3986 ;params segment survives htu normalisation, and an IPv6 authority is re-bracketed. Neither is cosmetic — both made proofs compare unequal to themselves. - Internal error messages no longer reach the WWW-Authenticate challenge. - resource_metadata can point at an AS-hosted PRM document. - authserver 0.2.0: access_denied and invalid_target are typed and kept out of the circuit breaker, and an introspection active:false following a locally valid JWT is logged rather than silently read as revoked. - The conformance catalog pin moves to 583a6d9. Two files keep what main already had rather than taking the development line's copy: publish-pypi.yml keeps the gh-action-pypi-publish v1.14.2 pin (v1.14.0 does not upload metadata 2.5 wheels), and three CHANGELOG bullets are condensed to one line each to match the family's shape.
| assert claims.kid == "key-v1" | ||
| # Still inside the refresh interval, so no second read: the hop on the | ||
| # verify path is TTL-gated, not a fetch per verification. | ||
| assert metadata_calls == 1 |
| # translate it to the shape a reader expects from a failing import. | ||
| try: | ||
| _resolve_elicitation_id_kwarg(ElicitRequestURLParams) | ||
| _ELICITATION_ID_KWARG = _resolve_elicitation_id_kwarg(ElicitRequestURLParams) |
| # translate it to the shape a reader expects from a failing import. | ||
| try: | ||
| _resolve_elicitation_id_kwarg(ElicitRequestURLParams) | ||
| _ELICITATION_ID_KWARG = _resolve_elicitation_id_kwarg(ElicitRequestURLParams) |
| from pydantic import BaseModel | ||
|
|
||
| from authplane_mcp import url_elicitation | ||
| import authplane_mcp.url_elicitation as url_elicitation |
| from pydantic import BaseModel | ||
|
|
||
| from authplane_fastmcp import url_elicitation | ||
| import authplane_fastmcp.url_elicitation as url_elicitation |
| self, base_url: str, resource: str, *, scopes: list[str] | None = None | ||
| ) -> AuthplaneTokenVerifier: | ||
| """Build a verifier for ``resource`` against the server at ``base_url``.""" | ||
| ) -> AuthplaneTokenVerifier: ... |
| await cache.get() | ||
| refresh_task = cache._refresh_task # pyright: ignore[reportPrivateUsage] | ||
| assert refresh_task is not None | ||
| await refresh_task |
| @property | ||
| def jwks(self) -> dict[str, Any]: | ||
| """The single-key JWKS document publishing this key.""" | ||
| ... |
muralx
approved these changes
Sep 29, 2026
muralx
left a comment
Collaborator
There was a problem hiding this comment.
Fix bot review comments.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Brings
mainup to the current development line ahead of the 0.5.0 cut. The[Unreleased]section ofCHANGELOG.mdis the authoritative list of what changed for a caller; this body covers the mechanics a reviewer needs.What is in it
jwks_uriis followed on ordinary verification traffic rather than only when the rotation also introduces a newkid, andjwks_uriis resolved per key-set fetch instead of captured at construction. A failed document refresh backs off formax(1, min(30, refresh_seconds))instead of being retried by the next reader, which previously made every caller pay a full HTTP timeout serialized behind the fetch lock.;paramssegment surviveshtunormalisation (RFC 3986 §3.3 places it in the path; RFC 9449 §4.3 removes only query and fragment), and an IPv6 authority is re-bracketed. Both were cases where a proof this SDK minted compared unequal to itself.WWW-Authenticatechallenge.resource_metadatacan point at a document the authorization server hosts.access_deniedandinvalid_targetare typed and excluded from the circuit breaker shared with introspection — five policy refusals used to open it. An introspectionactive:falsefollowing a locally valid JWT is logged rather than silently read as a revocation.583a6d9.Two deliberate carry-forwards
Both are places where this branch keeps what
mainalready had rather than taking the development line’s copy:publish-pypi.ymlkeeps thegh-action-pypi-publishv1.14.2 pin. The development line is still on v1.14.0, which does not upload metadata 2.5 wheels — taking it would have reverted the fix and broken the release this port exists to enable.[Unreleased]bullets are condensed to one line each, matching the shape the rest of the family writes. No migration clause was dropped; the mechanism each one described is in the source comments and in this body.Verification
ruff+pytestgreen locally (930 passed) with the conformance suites driven against the pinned catalog583a6d9, which is what CI reads.