mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-08 03:08:45 +00:00
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 <ishaan@berri.ai>
This commit is contained in:
parent
c215b3a79f
commit
51f5431e5a
2 changed files with 118 additions and 1 deletions
|
|
@ -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 = [
|
||||
|
|
|
|||
|
|
@ -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}"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue