From ad8c9c2aa28a55a86e83f57b4eb979b6de3fbc23 Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Thu, 21 May 2026 19:08:29 +0000 Subject: [PATCH] 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 --- .../_experimental/mcp_server/auth/user_api_key_auth_mcp.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/litellm/proxy/_experimental/mcp_server/auth/user_api_key_auth_mcp.py b/litellm/proxy/_experimental/mcp_server/auth/user_api_key_auth_mcp.py index d55261982aa..16f8fe3fb74 100644 --- a/litellm/proxy/_experimental/mcp_server/auth/user_api_key_auth_mcp.py +++ b/litellm/proxy/_experimental/mcp_server/auth/user_api_key_auth_mcp.py @@ -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 )