mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-25 01:02:15 +00:00
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:
parent
f5a193f29b
commit
ad8c9c2aa2
1 changed files with 6 additions and 1 deletions
|
|
@ -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
|
||||
)
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue