mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-03 02:22:24 +00:00
fix(proxy): authorize model_group_alias target before routing
The request is authorized against the requested model group, so the alias target has to clear model access checks on its own before dispatch. Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
parent
3695ac5b13
commit
c4505baa85
2 changed files with 48 additions and 0 deletions
|
|
@ -485,6 +485,15 @@ async def route_request(
|
|||
|
||||
aliased_model = _resolve_per_request_model_group_alias(override_settings, data.get("model"))
|
||||
if aliased_model is not None:
|
||||
if user_api_key_dict is not None:
|
||||
from litellm.proxy.auth.auth_checks import can_key_call_resolved_model
|
||||
|
||||
await can_key_call_resolved_model(
|
||||
model=aliased_model,
|
||||
llm_model_list=llm_router.model_list if llm_router is not None else None,
|
||||
valid_token=user_api_key_dict,
|
||||
llm_router=llm_router,
|
||||
)
|
||||
data["model"] = aliased_model
|
||||
|
||||
# Use main router with overridden kwargs
|
||||
|
|
|
|||
|
|
@ -547,6 +547,45 @@ async def test_route_request_leaves_model_untouched_for_irrelevant_or_malformed_
|
|||
assert response.choices[0].message.content == "from-group-a"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_route_request_model_group_alias_target_needs_model_access():
|
||||
"""
|
||||
The request is authorized against the requested model, so an alias pointing at a
|
||||
model group the key cannot access must be rejected rather than silently served.
|
||||
"""
|
||||
from litellm.proxy._types import ProxyException, UserAPIKeyAuth
|
||||
|
||||
router = _router_with_two_model_groups()
|
||||
key = UserAPIKeyAuth(api_key="sk-restricted", models=["group-a"])
|
||||
data = {
|
||||
"model": "group-a",
|
||||
"messages": [{"role": "user", "content": "Hello"}],
|
||||
"router_settings_override": {"model_group_alias": {"group-a": "group-b"}},
|
||||
}
|
||||
|
||||
with pytest.raises(ProxyException) as exc_info:
|
||||
await route_request(data, router, None, "acompletion", user_api_key_dict=key)
|
||||
|
||||
assert "group-b" in exc_info.value.message
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_route_request_model_group_alias_applies_when_target_is_allowed():
|
||||
from litellm.proxy._types import UserAPIKeyAuth
|
||||
|
||||
router = _router_with_two_model_groups()
|
||||
key = UserAPIKeyAuth(api_key="sk-allowed", models=["group-a", "group-b"])
|
||||
data = {
|
||||
"model": "group-a",
|
||||
"messages": [{"role": "user", "content": "Hello"}],
|
||||
"router_settings_override": {"model_group_alias": {"group-a": "group-b"}},
|
||||
}
|
||||
|
||||
response = await (await route_request(data, router, None, "acompletion", user_api_key_dict=key))
|
||||
|
||||
assert response.choices[0].message.content == "from-group-b"
|
||||
|
||||
|
||||
def test_mock_testing_kwarg_names_matches_dataclass():
|
||||
"""``_MOCK_TESTING_KWARG_NAMES`` is hardcoded to avoid a cyclic import
|
||||
against ``litellm.types.router``. This test guards against drift —
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue