diff --git a/litellm/proxy/_types.py b/litellm/proxy/_types.py index ed20fe86cd..1c38039234 100644 --- a/litellm/proxy/_types.py +++ b/litellm/proxy/_types.py @@ -707,6 +707,8 @@ class LiteLLMRoutes(enum.Enum): # Project read routes - endpoint scopes results to caller's teams (non-admin) "/project/list", "/project/info", + # Endpoint enforces proxy-admin vs team-admin model access itself. + "/health/test_connection", # Invitation routes - org/team admins checked in endpoint via _user_has_admin_privileges "/invitation/new", "/invitation/delete", diff --git a/tests/test_litellm/proxy/auth/test_route_checks.py b/tests/test_litellm/proxy/auth/test_route_checks.py index 268cdff1f7..9c1cd116e6 100644 --- a/tests/test_litellm/proxy/auth/test_route_checks.py +++ b/tests/test_litellm/proxy/auth/test_route_checks.py @@ -80,6 +80,28 @@ def test_compliance_routes_open_to_internal_user(route): ) +def test_health_test_connection_route_delegates_internal_user_auth_to_endpoint(): + """Team model test-connection requests are authorized by the endpoint.""" + role = LitellmUserRoles.INTERNAL_USER.value + user_obj = LiteLLM_UserTable( + user_id="test_user", + user_email="test@example.com", + user_role=role, + ) + valid_token = UserAPIKeyAuth(user_id="test_user", user_role=role) + request = MagicMock(spec=Request) + request.query_params = {} + + RouteChecks.non_proxy_admin_allowed_routes_check( + user_obj=user_obj, + _user_role=role, + route="/health/test_connection", + request=request, + valid_token=valid_token, + request_data={}, + ) + + @pytest.mark.parametrize( "route", ["/compliance/eu-ai-act", "/compliance/gdpr"],