You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Adapters (authplane-mcp, authplane-fastmcp):
- Forward a DPoPRequestContext from verify_token to AuthplaneResource.verify
so inbound_dpop=InboundDPoPOptions(required=True) enforces the proof check
end-to-end. htu origin is the operator-configured resource URI, never the
inbound Host / X-Forwarded-Proto headers. Operators using required=True with
authplane-mcp should call install_request_context(mcp) after constructing
FastMCP so the verifier can read the per-request context; without it the
request fails closed (401) rather than skipping the check.
- Reconstruct htu from scope["raw_path"] to preserve percent-encoding (e.g.
%2F) on the wire under ASGI, falling back to request.url.path.
- authplane-mcp adds AuthplaneRequestContextMiddleware, get_current_request(),
and install_request_context(mcp) (idempotent) to publish the active request
on a ContextVar.
- Cache the in-flight verify task per request so a repeat verify_token within
one request reuses it instead of re-entering the inbound DPoP replay store.
Core (authplane):
- Bound TokenCache with a configurable max_entries cap (default 10_000) and
LRU eviction; plumbed through AuthplaneClient.create(cache_max_entries=).
- Add VerifiedClaims.require_scopes(scopes) plural AND-style scope helper.
Docs and demos run adapter setup, the async server entry point, and aclose()
in a single asyncio.run(main()), keeping the client's locks, HTTP pool, and
background refresh tasks on one event loop.
Copy file name to clipboardExpand all lines: CHANGELOG.md
+12Lines changed: 12 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,6 +7,18 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
7
7
8
8
## [Unreleased]
9
9
10
+
### Added
11
+
-`TokenCache` is now bounded by a configurable `max_entries` cap (default `10_000`, exposed as `TokenCache.DEFAULT_MAX_ENTRIES` and a read-only `cache.max_entries` property) and evicts the least-recently-used entry on overflow; both `get` and `set` bump the touched key to MRU. Plumbed through `AuthplaneClient.create(cache_max_entries=...)`. Token-exchange cache keys are high-cardinality (the subject token is part of the key), so the cap keeps long-lived clients bounded.
12
+
-`VerifiedClaims.require_scopes(scopes: Iterable[str])` — plural AND-style scope-union helper. Empty input is a no-op; on failure the raised `InsufficientScopeError` carries the full requested tuple on `required_scopes` and names every missing scope plus the token's available scopes in the message.
13
+
-`authplane-mcp`: new public surface — `AuthplaneRequestContextMiddleware`, `get_current_request()`, `install_request_context(mcp)` — an ASGI middleware that publishes the active request on a `ContextVar` so the verifier can build a `DPoPRequestContext`.
14
+
-`authplane-fastmcp`, `authplane-mcp`: `AuthplaneTokenVerifier` caches the in-flight verify task per request (keyed by access token on `request.state`), so a repeat `verify_token` within the same HTTP request awaits the same task rather than re-entering the inbound DPoP replay store. Cross-request replay protection is unaffected (distinct requests get distinct caches).
15
+
16
+
### Fixed
17
+
-`authplane-fastmcp`, `authplane-mcp`: inbound DPoP proof-of-possession is now enforced end-to-end. `AuthplaneTokenVerifier.verify_token` forwards a `DPoPRequestContext` (method + reconstructed `htu` + proof header) to `AuthplaneResource.verify`, so `inbound_dpop=InboundDPoPOptions(required=True)` checks the proof on every request. The `htu` origin is always the operator-configured resource URI, never the inbound `Host` / `X-Forwarded-Proto` headers. Operators using `required=True` with `authplane-mcp` should call `install_request_context(mcp)` after constructing `FastMCP` so the verifier can read the per-request context; if it is not installed the request fails closed (401) rather than skipping the check.
18
+
-`authplane-fastmcp`, `authplane-mcp`: DPoP `htu` reconstruction reads `scope["raw_path"]` to preserve percent-encoding (e.g. `%2F`) on the wire under ASGI, falling back to `request.url.path` when the server omits `raw_path`.
19
+
-`authplane-mcp`: `install_request_context(mcp)` is idempotent — repeated calls on the same `FastMCP` instance are no-ops.
20
+
- Docs and demos now run adapter setup, the async server entry point (`run_streamable_http_async` / `run_async`), and `aclose()` in a single `asyncio.run(main())`, keeping the client's locks, HTTP pool, and background JWKS/metadata refresh tasks on one event loop.
0 commit comments