Skip to content

Conversation

@bokhi
Copy link

@bokhi bokhi commented Nov 10, 2025

Fixes #108

Problem

When using RFC 8707 Resource Indicators with path components (e.g., resource=https://example.com/api), token validation fails with:

invalid_token: Token audience does not match resource server

This breaks OAuth flows for services like ChatGPT custom connectors.

Root Cause

In handleApiRequest, the resourceServer is computed using only the origin:

const resourceServer = `${requestUrl.protocol}//${requestUrl.host}`;

However, RFC 8707 recommends using full URLs with paths for resource indicators. Since audienceMatches performs strict equality (===):

  • Token audience: https://example.com/api (from authorization request's resource parameter)
  • Resource server: https://example.com (computed from request URL)
  • Result: mismatch → validation fails

Solution

This PR updates the resourceServer computation in both internal and external token validation flows to include the pathname component:

const resourceServer = `${requestUrl.protocol}//${requestUrl.host}${requestUrl.pathname}`;

Changes

  • src/oauth-provider.ts line 2194: Include pathname in resourceServer (internal token validation)
  • src/oauth-provider.ts line 2228: Include pathname in resourceServer (external token validation)

Testing

Tested with ChatGPT custom connector:

  • ✅ Authorization flow with resource=https://server/mcp
  • ✅ Token issued with aud: "https://server/mcp"
  • ✅ API request to https://server/mcp succeeds
  • ✅ Audience validation passes

References

…nce validation

Fixes cloudflare#108

When using RFC 8707 Resource Indicators with path components (e.g.,
resource=https://example.com/api), token validation was failing because
resourceServer was computed using only the origin (protocol + host),
while the token audience contained the full URL with path.

This commit updates the resourceServer computation in both internal and
external token validation flows to include the pathname component:

  const resourceServer = `${requestUrl.protocol}//${requestUrl.host}${requestUrl.pathname}`;

This ensures that audience validation succeeds when the resource
indicator includes the path component, as recommended by RFC 8707.
@changeset-bot
Copy link

changeset-bot bot commented Nov 10, 2025

⚠️ No Changeset found

Latest commit: 249513a

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@pkg-pr-new
Copy link

pkg-pr-new bot commented Nov 11, 2025

Open in StackBlitz

npm i https://pkg.pr.new/cloudflare/workers-oauth-provider/@cloudflare/workers-oauth-provider@109

commit: 5d65326

- Modify audienceMatches() to support both origin-only and path-aware audiences
- Origin-only audiences (e.g., https://example.com) match by origin for backward compatibility
- Path-aware audiences (e.g., https://example.com/api) require exact match per RFC 8707
- Add 3 test cases for path-aware audience validation
- Update TestApiHandler to handle all /api/* paths

This fixes the CI failures in PR cloudflare#109 while maintaining backward compatibility
with existing code that uses origin-only resource indicators.

Fixes cloudflare#108
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Audience validation fails for RFC 8707 resource indicators with path

1 participant