From acf069e93f7383d199bf20f2ed669e812af5977c Mon Sep 17 00:00:00 2001 From: ryan-crabbe-berri Date: Tue, 20 Oct 2026 12:15:12 -0700 Subject: [PATCH] fix(router): refuse a tagged auto-router entry to callers without its access group --- litellm/router.py | 3 ++ .../test_model_access_group_grants.py | 29 +++++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/litellm/router.py b/litellm/router.py index 400f65058ea..dd46e56179e 100644 --- a/litellm/router.py +++ b/litellm/router.py @@ -15551,6 +15551,9 @@ class Router: model=registered_model_name, strategy_tags=selected_strategy.tags, request_kwargs=request_kwargs ) definition: Final = selected_strategy.deployment + strategy_source: Final = marker if marker is not None else definition.model_dump() if definition else None + if strategy_source is not None: + _ = require_granted_deployment(strategy_source, model, request_kwargs) config_id: Final = definition.model_info.id if definition else None updated_at: Final = definition.model_info.updated_at if definition else None router_kind: Final = classify_strategy_router_model(definition.litellm_params.model) if definition else None diff --git a/tests/unit/router_utils/test_model_access_group_grants.py b/tests/unit/router_utils/test_model_access_group_grants.py index 5b73f21d37f..c4a7ac7609f 100644 --- a/tests/unit/router_utils/test_model_access_group_grants.py +++ b/tests/unit/router_utils/test_model_access_group_grants.py @@ -152,3 +152,32 @@ def test_resolution_finds_a_tagged_deployment_by_id_for_any_caller() -> None: ) assert isinstance(deployment, dict) assert (name, deployment["model_info"]["id"]) == ("openai/private-id-upstream", "private-id") + + +def _router_with_tagged_complexity_router() -> litellm.Router: + return litellm.Router( + model_list=[ + _deployment("public-model", "public", "public-id"), + { + "model_name": "private-router", + "litellm_params": { + "model": "auto_router/complexity_router", + "complexity_router_config": { + "tiers": {"SIMPLE": "public-model", "MEDIUM": "public-model", "COMPLEX": "public-model"} + }, + "complexity_router_default_model": "public-model", + }, + "model_info": {"id": "private-router-id", "access_groups": ["group-x"]}, + }, + ], + ) + + +async def test_a_tagged_auto_router_refuses_ungranted_callers_even_when_it_picks_a_public_target() -> None: + with pytest.raises(litellm.PermissionDeniedError) as denied: + await _reply(_router_with_tagged_complexity_router(), "private-router", frozenset({"public-model"})) + assert denied.value.status_code == 403 + + +async def test_a_tagged_auto_router_serves_callers_granted_its_group() -> None: + assert await _reply(_router_with_tagged_complexity_router(), "private-router", frozenset({"group-x"})) == "public"