From be5a1234a8db3fef61df32a919fff66e40bd2dee Mon Sep 17 00:00:00 2001 From: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Wed, 8 Jul 2026 08:10:23 +0000 Subject: [PATCH] fix(proxy): allow llm_api_routes virtual keys to reach model-discovery endpoints --- litellm/proxy/auth/route_checks.py | 12 ++++++++ .../proxy/auth/test_route_checks.py | 30 +++++++++++++++++++ 2 files changed, 42 insertions(+) diff --git a/litellm/proxy/auth/route_checks.py b/litellm/proxy/auth/route_checks.py index dd0a34a7898..1c4b49eea07 100644 --- a/litellm/proxy/auth/route_checks.py +++ b/litellm/proxy/auth/route_checks.py @@ -61,6 +61,15 @@ _PROXY_ADMIN_VIEW_ONLY_BLOCKED_KEY_SUFFIXES = ("/regenerate", "/reset_spend") _AUTH_ENFORCED_PASS_THROUGH_ROUTE_GROUPS = frozenset(("openai_routes", "llm_api_routes")) +_LLM_API_MODEL_DISCOVERY_ROUTES = frozenset( + ( + "/model/info", + "/v1/model/info", + "/v2/model/info", + "/model_group/info", + ) +) + class RouteChecks: @staticmethod @@ -165,6 +174,9 @@ class RouteChecks: if RouteChecks._is_get_mcp_server_discovery_route(route=route, request=request): return True + if route in _LLM_API_MODEL_DISCOVERY_ROUTES: + return True + # check if wildcard pattern is allowed for allowed_route in valid_token.allowed_routes: if RouteChecks._route_matches_wildcard_pattern(route=route, pattern=allowed_route): diff --git a/tests/test_litellm/proxy/auth/test_route_checks.py b/tests/test_litellm/proxy/auth/test_route_checks.py index d623149ff6a..5624b1f6c74 100644 --- a/tests/test_litellm/proxy/auth/test_route_checks.py +++ b/tests/test_litellm/proxy/auth/test_route_checks.py @@ -486,6 +486,36 @@ def test_virtual_key_llm_api_routes_denies_spend_logs_v2(): assert "Virtual key is not allowed to call this route" in str(exc_info.value.detail) +@pytest.mark.parametrize( + "route", + [ + "/model/info", + "/v1/model/info", + "/v2/model/info", + "/model_group/info", + ], +) +def test_virtual_key_llm_api_routes_allows_model_discovery(route): + """Regression test for #32443: virtual keys with allowed_routes=["llm_api_routes"] + (the default the Create Key UI applies to LLM API keys) must be able to reach the + read-only model-discovery endpoints. These back OpenAI-compatible model listing and + the LiteLLM VS Code extension; the GET handlers already scope results to the models + the caller can access.""" + + valid_token = UserAPIKeyAuth( + user_id="test_user", + allowed_routes=["llm_api_routes"], + ) + + result = RouteChecks.is_virtual_key_allowed_to_call_route( + route=route, + valid_token=valid_token, + request=_mock_request("GET"), + ) + + assert result is True + + @pytest.mark.parametrize( "route", [