Skip to content

[PERFORMANCE]: Double token scoping for /mcp requests when email_auth_enabled=True #2160

@crivetimihai

Description

@crivetimihai

Summary

When email_auth_enabled=True, the token scoping middleware was running twice for /mcp requests after PR #2153 (CORS preflight fix) changed the routing to go through the full middleware stack.

This issue has been fixed in PR #2153 by adding an idempotency guard in TokenScopingMiddleware.

Root Cause

PR #2153 changed /servers/{id}/mcp routing from:

# BEFORE: Direct handler call - bypassed middleware stack
await streamable_http_session.handle_streamable_http(scope, receive, send)

to:

# AFTER: Goes through middleware stack for CORS support
await self.application(scope, receive, send)

This caused TokenScopingMiddleware to run twice:

  1. First via MCPPathRewriteMiddleware.dispatch (on original path /servers/{id}/mcp)
  2. Second via BaseHTTPMiddleware.dispatch (on rewritten path /mcp/)

Actual Impact (Corrected)

The second pass on /mcp/ path only performed:

  • JWT extraction and validation (cached, but still has overhead)
  • Team membership DB query (cached 60s)

NOT performed on second pass (no regex patterns match /mcp/):

  • Resource team ownership check
  • Server ID restriction check
  • Permission restriction check

Fix Applied

Added idempotency guard using request.state flag:

# Skip if already scoped (prevents double-scoping for /mcp requests)
if getattr(request.state, "_token_scoping_done", False):
    return await call_next(request)

# Mark as scoped before doing any work
request.state._token_scoping_done = True

Why request.state instead of scope["modified_path"]:

  • request.state persists across all middleware invocations
  • The flag is set immediately, before any scoping work
  • More robust than path-based detection which depends on execution order

Status

Fixed in PR #2153

Metadata

Metadata

Assignees

Labels

enhancementNew feature or requestpythonPython / backend development (FastAPI)

Type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions