fix(mcp): restrict passthrough cold-start bypass to 401 only

The new elif passthrough cold-start branch reused is_auth_error which
matches both 401 and 403. A 403 from user_api_key_auth indicates the
LiteLLM key WAS recognized but is forbidden (e.g. over budget / rate
limited); falling through to anonymous UserAPIKeyAuth() in that case
bypasses spend and rate-limit controls on passthrough servers.

Only trigger the cold-start anonymous admission on 401, which is the
signal that the bearer is an upstream OAuth token rather than a
recognized LiteLLM key.

Co-authored-by: Yassin Kortam <yassin@berri.ai>
This commit is contained in:
Cursor Agent 2026-05-21 19:08:29 +00:00
parent f5a193f29b
commit ad8c9c2aa2
No known key found for this signature in database

View file

@ -237,6 +237,7 @@ class MCPRequestHandler:
# rewrite the auth error as a 500).
status = e.status_code if isinstance(e, HTTPException) else e.code
is_auth_error = status in (401, 403, "401", "403")
is_unauthenticated = status in (401, "401")
client_ip = IPAddressUtils.get_mcp_client_ip(request)
if is_auth_error and MCPRequestHandler._target_servers_use_oauth2(
path=request.url.path,
@ -248,7 +249,7 @@ class MCPRequestHandler:
"Authorization as upstream OAuth2 token passthrough"
)
validated_user_api_key_auth = UserAPIKeyAuth()
elif is_auth_error:
elif is_unauthenticated:
# Pass-through cold-start return: per RFC 9728 / MCP
# Authorization spec the client completes upstream OAuth
# discovery and returns with ``Authorization: Bearer
@ -258,6 +259,10 @@ class MCPRequestHandler:
# unchanged. Fall back to anonymous admission so the
# caller is not rejected for following the discovery
# flow without also setting ``x-litellm-api-key``.
# Only trigger on 401 (token unrecognized); a 403 means
# the key WAS recognized but is forbidden (e.g. over
# budget / rate limited) and must propagate so those
# controls are not bypassed via anonymous admission.
mcp_servers_from_path = _parse_mcp_server_names_from_path(
request.url.path
)