From 51f5431e5a7123a6013d3b612d642168977d8bde Mon Sep 17 00:00:00 2001 From: Cursor Agent Date: Wed, 14 Jan 2026 17:33:40 +0000 Subject: [PATCH] fix(proxy): add container routes to openai_routes for non-admin access Fixes #19088 Non-admin users were receiving 401 Unauthorized errors when calling OpenAI Container API endpoints (/containers/*) through LiteLLM proxy. Root cause: The /containers/* routes were not included in LiteLLMRoutes.openai_routes. When is_llm_api_route() checked if a route was in openai_routes and didn't find it, the request was treated as an admin-only route, blocking non-admin users. Changes: - Added all container routes to LiteLLMRoutes.openai_routes in _types.py: - /containers and /v1/containers - /containers/{container_id} and /v1/containers/{container_id} - /containers/{container_id}/files and /v1/containers/{container_id}/files - /containers/{container_id}/files/{file_id} and /v1/containers/{container_id}/files/{file_id} - /containers/{container_id}/files/{file_id}/content and /v1/containers/{container_id}/files/{file_id}/content - Added unit tests to verify container routes are recognized as LLM API routes and accessible to internal users and virtual keys with llm_api_routes permission Co-authored-by: ishaan --- litellm/proxy/_types.py | 11 ++ .../proxy/auth/test_route_checks.py | 108 +++++++++++++++++- 2 files changed, 118 insertions(+), 1 deletion(-) diff --git a/litellm/proxy/_types.py b/litellm/proxy/_types.py index a1186f8e372..adcdcefe2ec 100644 --- a/litellm/proxy/_types.py +++ b/litellm/proxy/_types.py @@ -360,6 +360,17 @@ class LiteLLMRoutes(enum.Enum): # OCR "/ocr", "/v1/ocr", + # containers + "/containers", + "/v1/containers", + "/containers/{container_id}", + "/v1/containers/{container_id}", + "/containers/{container_id}/files", + "/v1/containers/{container_id}/files", + "/containers/{container_id}/files/{file_id}", + "/v1/containers/{container_id}/files/{file_id}", + "/containers/{container_id}/files/{file_id}/content", + "/v1/containers/{container_id}/files/{file_id}/content", ] mapped_pass_through_routes = [ diff --git a/tests/test_litellm/proxy/auth/test_route_checks.py b/tests/test_litellm/proxy/auth/test_route_checks.py index ef7f2f3c30d..65209358327 100644 --- a/tests/test_litellm/proxy/auth/test_route_checks.py +++ b/tests/test_litellm/proxy/auth/test_route_checks.py @@ -905,4 +905,110 @@ def test_route_in_additional_public_routes_exact_match(): assert route_in_additonal_public_routes("/status") is True # Non-matching routes should fail assert route_in_additonal_public_routes("/other") is False - + + +@pytest.mark.parametrize( + "route", + [ + "/containers", + "/v1/containers", + "/containers/cntr_123", + "/v1/containers/cntr_123", + "/containers/cntr_123/files", + "/v1/containers/cntr_123/files", + "/containers/cntr_123/files/file_456", + "/v1/containers/cntr_123/files/file_456", + "/containers/cntr_123/files/file_456/content", + "/v1/containers/cntr_123/files/file_456/content", + ], +) +def test_container_routes_are_llm_api_routes(route): + """ + Test that container routes are recognized as LLM API routes. + + This test verifies the fix for issue #19088: + https://github.com/BerriAI/litellm/issues/19088 + + Container routes should be accessible to non-admin users since container + operations are legitimate user features, not management/admin-only features. + """ + + assert RouteChecks.is_llm_api_route(route) is True + + +def test_container_routes_accessible_to_internal_users(): + """ + Test that internal users can access the container routes. + + This test verifies the fix for issue #19088: + https://github.com/BerriAI/litellm/issues/19088 + + Container routes should be accessible to internal_user role since container + operations are legitimate user features, not management/admin-only features. + """ + + # Create an internal user object + user_obj = LiteLLM_UserTable( + user_id="test_user", + user_email="test@example.com", + user_role=LitellmUserRoles.INTERNAL_USER.value, + ) + + # Create an internal user API key auth + valid_token = UserAPIKeyAuth( + user_id="test_user", + user_role=LitellmUserRoles.INTERNAL_USER.value, + ) + + # Create a mock request + request = MagicMock(spec=Request) + request.query_params = {} + + # Test that calling /v1/containers route does NOT raise an exception + try: + RouteChecks.non_proxy_admin_allowed_routes_check( + user_obj=user_obj, + _user_role=LitellmUserRoles.INTERNAL_USER.value, + route="/v1/containers", + request=request, + valid_token=valid_token, + request_data={"name": "test-container"}, + ) + # If no exception is raised, the test passes + except Exception as e: + pytest.fail( + f"Internal user should be able to access /v1/containers route. Got error: {str(e)}" + ) + + +def test_container_routes_with_virtual_key_llm_api_routes(): + """ + Test that virtual keys with llm_api_routes permission can access container endpoints. + + This test verifies the fix for issue #19088: + https://github.com/BerriAI/litellm/issues/19088 + """ + + # Create a virtual key with llm_api_routes permission + valid_token = UserAPIKeyAuth( + user_id="test_user", + allowed_routes=["llm_api_routes"], + ) + + # Test that all container routes are accessible + test_routes = [ + "/v1/containers", + "/containers", + "/v1/containers/cntr_123", + "/containers/cntr_123/files", + "/v1/containers/cntr_123/files/file_456", + "/containers/cntr_123/files/file_456/content", + ] + + for route in test_routes: + result = RouteChecks.is_virtual_key_allowed_to_call_route( + route=route, valid_token=valid_token + ) + assert ( + result is True + ), f"Virtual key with llm_api_routes should be able to access {route}"