Merge branch 'litellm_internal_staging' into litellm_/eager-rosalind-f7833a

This commit is contained in:
yuneng-jiang 2026-08-01 12:33:37 -07:00 committed by GitHub
commit 7e8c63a0cc
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 65 additions and 6 deletions

View file

@ -517,6 +517,11 @@ class LiteLLMRoutes(enum.Enum):
"/guardrails/apply_guardrail",
]
model_info_routes = [
"/model/info",
"/v1/model/info",
]
llm_api_routes = (
openai_routes
+ anthropic_routes
@ -527,6 +532,7 @@ class LiteLLMRoutes(enum.Enum):
+ mcp_inference_routes
+ litellm_native_routes
+ agent_routes
+ model_info_routes
)
info_routes = [
"/key/info",
@ -653,8 +659,8 @@ class LiteLLMRoutes(enum.Enum):
"/global/spend/all_tag_names",
]
public_routes = set(
[
public_routes = frozenset(
(
"/routes",
"/",
"/health/liveliness",
@ -669,7 +675,7 @@ class LiteLLMRoutes(enum.Enum):
"/public/mcp_hub",
"/public/skill_hub",
"/public/litellm_model_cost_map",
]
)
)
# Retained for backwards compatibility with JWT auth configs that reference

View file

@ -22,7 +22,6 @@ from typing import (
Mapping,
Optional,
Protocol,
Sequence,
Tuple,
TypeVar,
Union,

View file

@ -69,7 +69,7 @@
"limit": 4
},
"C405": {
"limit": 23
"limit": 22
},
"C408": {
"limit": 14

View file

@ -445,6 +445,60 @@ def test_virtual_key_llm_api_routes_allows_mcp_inference_endpoints(route, method
assert result is True
@pytest.mark.parametrize("route", ["/model/info", "/v1/model/info"])
def test_virtual_key_llm_api_routes_allows_model_info(route):
"""AI API virtual keys must be able to read model metadata (pricing, mode,
max_tokens) for the deployments they can already route to. Both the
unversioned and /v1 paths are the same handler, so both must be reachable.
"""
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", ["/model/info", "/v1/model/info"])
def test_model_info_not_classified_as_llm_api(route):
"""Membership in `llm_api_routes` must not promote /model/info to an
`is_llm_api_route()`. That predicate gates DISABLE_LLM_API_ENDPOINTS,
global/virtual-key budget enforcement, enforce_user_param and the JWT
x-litellm-team-id attachment; model metadata is a free read and must stay
outside all of them.
"""
assert RouteChecks.is_llm_api_route(route=route) is False
@pytest.mark.parametrize("route", ["/v2/model/info", "/model_group/info"])
def test_virtual_key_llm_api_routes_denies_other_model_info_routes(route):
"""The grant is scoped to the two /model/info paths. The paginated Admin UI
listing and the model-group endpoint stay outside it.
"""
valid_token = UserAPIKeyAuth(
user_id="test_user",
allowed_routes=["llm_api_routes"],
)
with pytest.raises(HTTPException) as exc_info:
RouteChecks.is_virtual_key_allowed_to_call_route(
route=route,
valid_token=valid_token,
request=_mock_request("GET"),
)
assert exc_info.value.status_code == 403
def test_spend_logs_v2_classified_as_management_not_llm_api():
"""Paginated spend logs are a management/spend read route, not an LLM API."""

View file

@ -3,7 +3,7 @@
"limit": 23191
},
"LIT002": {
"limit": 27276
"limit": 27275
},
"LIT003": {
"limit": 292