diff --git a/litellm/proxy/_types.py b/litellm/proxy/_types.py index cc44a86c691..a31b6f834b3 100644 --- a/litellm/proxy/_types.py +++ b/litellm/proxy/_types.py @@ -660,6 +660,11 @@ class LiteLLMRoutes(enum.Enum): KeyManagementRoutes.AUTO_ROUTER_MANAGE.value, ] + team_service_account_key_routes = [ + KeyManagementRoutes.KEY_GENERATE.value, + KeyManagementRoutes.KEY_UPDATE.value, + ] + management_routes = ( [ # user diff --git a/litellm/proxy/auth/route_checks.py b/litellm/proxy/auth/route_checks.py index 001ab9a30b0..1b9fd7c42bf 100644 --- a/litellm/proxy/auth/route_checks.py +++ b/litellm/proxy/auth/route_checks.py @@ -328,7 +328,9 @@ class RouteChecks: pass # authN/authZ handled by api itself elif RouteChecks.check_passthrough_route_access(route=route, user_api_key_dict=valid_token) or ( valid_token.is_team_service_account - and RouteChecks.check_route_access(route=route, allowed_routes=LiteLLMRoutes.key_management_routes.value) + and RouteChecks.check_route_access( + route=route, allowed_routes=LiteLLMRoutes.team_service_account_key_routes.value + ) ): pass elif valid_token.allowed_routes is not None: diff --git a/tests/test_litellm/proxy/auth/test_route_checks.py b/tests/test_litellm/proxy/auth/test_route_checks.py index b1405fc35cb..72c59223549 100644 --- a/tests/test_litellm/proxy/auth/test_route_checks.py +++ b/tests/test_litellm/proxy/auth/test_route_checks.py @@ -3993,8 +3993,10 @@ def test_team_service_account_key_allowed_key_management_routes(route): assert result is None -def test_team_service_account_key_rejected_for_non_key_management_route(): - """The service account carve-out does not extend past key-management routes.""" +@pytest.mark.parametrize("route", ["/team/new", "/spend/logs", "/key/delete", "/key/regenerate"]) +def test_team_service_account_key_rejected_outside_generate_and_update(route): + """The service account carve-out covers only /key/generate and /key/update; other + key-management routes lack team scoping for a userless caller and stay denied.""" valid_token = UserAPIKeyAuth( api_key="sk", team_id="t1", @@ -4008,7 +4010,7 @@ def test_team_service_account_key_rejected_for_non_key_management_route(): RouteChecks.non_proxy_admin_allowed_routes_check( user_obj=None, _user_role=None, - route="/team/new", + route=route, request=request, valid_token=valid_token, request_data={},