feat: add On-Behalf-Of token exchange support - #122
Merged
Conversation
nandan-bhat
reviewed
Aug 14, 2026
- Re-export MissingRequiredArgumentError, VerifyAccessTokenError, and BaseAuthError from fastapi_plugin so the documented OBO surface is catchable without reaching into auth0_api_python.errors - Correct the Error Handling docs: GetTokenByExchangeProfileError also fires at request time for a malformed token, and document the request-time cases - Fix the authorization example to raise HTTPException(403) instead of PermissionError, which escaped as a 500 - Clarify the DPoP note: the binding is not preserved on the exchanged token - Move the OBO section after Protecting API Routes so require_auth() is introduced first - Add a TestClient test for the require_auth -> exchange flow and drop the duplicates of upstream auth0-api-python tests
nandan-bhat
approved these changes
Aug 14, 2026
Merged
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.
📋 Changes
This PR adds On-Behalf-Of (OBO) token exchange support to auth0-fastapi-api, enabling MCP servers and intermediary FastAPI APIs to exchange an incoming Auth0 access token for a new access token targeting a downstream API while preserving the original user identity (RFC 8693). The exchange itself is performed by the underlying
auth0-api-pythonclient (auth0.api_client.get_token_on_behalf_of()), consistent with how the SDK already surfacesget_access_token_for_connection(). This PR exposes the OBO surface through the plugin and documents it.✨ Features
auth0.api_client.get_token_on_behalf_of(access_token, audience, scope?), returning access-token-oriented fields only (noid_tokenorrefresh_token). Requires a confidential client (client_idandclient_secret).get_current_actor()andget_delegation_chain()re-exported fromfastapi_pluginfor inspecting theactclaim on verified tokens - the current actor (outermostact.sub) for authorization and the full delegation chain for audit or attribution.🔧 API Changes
fastapi_plugin:get_current_actor,get_delegation_chain,OnBehalfOfTokenResult,GetTokenByExchangeProfileError, andApiError📖 Documentation
README.mdwith an On-Behalf-Of Token Exchange sectionEXAMPLES.mdwith the end-to-end flow (verify -> exchange -> call downstream), return value, error handling, and delegation inspection, plus production and DPoP notes🧪 Testing
Manual Testing
Requires an Auth0 tenant with an On-Behalf-Of / token-exchange profile configured: an API for the intermediary's own
audience, a second API for the downstreamaudience, and a confidential client authorized for the downstream API.Expected: the exchange returns a downstream-scoped access token whose
act.subidentifies the exchanging client, and the delegation helpers resolve the current actor and full chain.Contributor Checklist