feat(oauth): mirror RFC 8707 resource into Auth0's audience param#1277
Closed
brosand wants to merge 1 commit into
Closed
feat(oauth): mirror RFC 8707 resource into Auth0's audience param#1277brosand wants to merge 1 commit into
brosand wants to merge 1 commit into
Conversation
Auth0 does not implement RFC 8707 Resource Indicators: its endpoints
select the target API via a proprietary audience parameter and silently
ignore resource. Without it, client_credentials against an Auth0 tenant
fails with 403 access_denied ("No audience parameter was provided, and
no default audience has been configured"), so registered Auth0 OAuth
clients cannot mint tokens at all.
Mirror the resource value into audience on the authorization request,
code exchange, client_credentials exchange, and refresh, whenever the
endpoint host is an Auth0 tenant domain (*.auth0.com), keyed off the
host exactly like the existing providerAuthorizeExtras Google quirk.
Non-Auth0 endpoints are unaffected; an explicit extraParams audience on
the authorize URL still wins. Custom Auth0 domains are not auto-detected
and should configure a default audience tenant-side.
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.
feat(oauth): mirror RFC 8707
resourceinto Auth0'saudienceparamProblem
Executor's OAuth helpers send the standards-based RFC 8707 Resource Indicator (
resource) on the authorization request and on every token-endpoint grant, as the MCP Authorization spec requires. Auth0 does not implement RFC 8707: its endpoints silently ignoreresourceand instead select the target API (resource server) via a proprietaryaudienceparameter, which Auth0 documents as its equivalent of the resource indicator and which takes the same value (the API identifier URI).The practical consequence is that registered Auth0 OAuth clients cannot mint tokens through executor at all for the client_credentials grant. Observed empirically against a real Auth0 tenant:
Authorization-code grants "succeed" but fall back to an opaque token for the default (userinfo) audience, which resource servers cannot validate.
Approach
Add a small host-keyed quirk helper,
providerAudienceParam(endpointUrl, resource), inpackages/core/sdk/src/oauth-helpers.ts, following the exact pattern of the existingproviderAuthorizeExtrasGoogle quirk (offline access / consent prompt keyed offaccounts.google.com). It returns theresourcevalue as theaudienceto send when the endpoint hostname isauth0.comor ends with.auth0.com(case-insensitive, label-boundary suffix check soevilauth0.comdoes not match), andundefinedotherwise.The helper is applied at all four request-construction sites, so
audienceis sent alongside (not instead of)resource:buildAuthorizationUrl(authorization request). Set beforeextraParamsmerge, so an explicit caller-providedaudiencestill wins.exchangeAuthorizationCode(code exchange)exchangeClientCredentials(client_credentials, the grant that hard-fails today)refreshAccessToken(refresh)Why this shape
oauth-service.tsalready threads the client's storedresourceinto every one of these helpers, so the fix needs no changes to the OAuth client model, tool schemas, or DB schema, and existing Auth0 clients start working with no reconfiguration.oauth-helpers.ts) rather than introducing a new per-client setting for a value that is always identical toresource.resourceandaudienceis safe: Auth0 ignoresresource, and non-Auth0 providers never receiveaudience.Test coverage
New tests in
packages/core/sdk/src/oauth-helpers.test.ts, following the suite's existing patterns:providerAudienceParam: Auth0 tenant hosts (including regional<tenant>.<region>.auth0.com), case insensitivity, lookalike hosts (evilauth0.com,auth0.com.evil.com), unparseable URLs, and missing/empty resource.buildAuthorizationUrl: Auth0 authorize host emits bothresourceandaudience; non-Auth0 hosts and no-resource inputs emit noaudience; explicitextraParams.audienceoverrides the auto-mapping.*.auth0.comhost), so these use the helpers' injectedfetchto capture the POSTed form body and assertaudienceis present forhttps://tenant.us.auth0.com/oauth/tokenand absent for the local non-Auth0 endpoint.vitest run src/oauth-helpers.test.tsinpackages/core/sdk: 60 tests passed (14 new).oxfmt --check,oxlint --deny-warnings, and packagetypecheckclean on the touched files.Caveats
audiencecan be passed viaextraParamson the authorize request. If demand shows up, a per-client opt-in flag could be added later without disturbing this default.resourceis configured for the client; there is no behavior change for clients without one.resourceverbatim, which matches what Auth0 expects.