Skip to content

fix(mcp): isolate OAuth request headers#33722

Open
rekram1-node wants to merge 2 commits into
devfrom
isolate-oauth-headers
Open

fix(mcp): isolate OAuth request headers#33722
rekram1-node wants to merge 2 commits into
devfrom
isolate-oauth-headers

Conversation

@rekram1-node

@rekram1-node rekram1-node commented Jun 24, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • patch MCP SDK 1.29 transports so resource requestInit.headers are used only for MCP resource requests, never OAuth PRM/authorization-server discovery, dynamic registration, token exchange, or refresh
  • make generated transport headers case-insensitively replace configured values, preventing duplicate Authorization fields while preserving custom MCP resource headers
  • treat configured static Authorization as mutually exclusive with OAuth in connection, explicit auth, and debug paths

Related issues

Security boundary

MCP resource headers may contain tenant credentials or other origin-scoped secrets. SDK 1.29 wrapped OAuth fetches with the complete resource requestInit, allowing those headers to cross from the MCP resource origin to separately hosted protected-resource metadata, authorization server, registration, and token endpoints. The local SDK patch retains non-header request options for compatibility but removes resource headers from every OAuth-owned fetch. OAuth-generated metadata headers and client authentication remain intact.

Compatibility

  • all configured headers continue to reach Streamable HTTP and SSE resource requests
  • static Authorization continues to authenticate the MCP resource, but no OAuth provider is installed for that configuration
  • OAuth bearer tokens replace any same-name resource header case-insensitively rather than combining values
  • existing auth and debug flows remain unchanged for configurations without static Authorization

Tests

  • bun test test/mcp/oauth-header-isolation.test.ts
  • bun test test/mcp/headers.test.ts
  • bun typecheck from packages/opencode

The integration coverage uses real loopback servers on ephemeral ports with distinct origins and no mocks, sleeps, or timers. It covers PRM and authorization-server discovery, DCR, authorization-code exchange, refresh, mixed-case Authorization, resource canaries, and exactly one OAuth Basic client-auth header.

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.

1 participant