diff --git a/litellm/proxy/alerting_endpoints/usage_alerts.py b/litellm/proxy/alerting_endpoints/usage_alerts.py index 80d818f2dc7..dfd50e6e720 100644 --- a/litellm/proxy/alerting_endpoints/usage_alerts.py +++ b/litellm/proxy/alerting_endpoints/usage_alerts.py @@ -4,7 +4,7 @@ from datetime import date from typing import Annotated, Final, TypeAlias from fastapi import APIRouter, Depends, HTTPException, Query, Response -from pydantic import TypeAdapter +from pydantic import BaseModel, TypeAdapter from litellm.models.usage_alerts import UsageAlertStore from litellm.proxy._types import LiteLLMRoutes, UserAPIKeyAuth @@ -57,10 +57,14 @@ def _allows_write(grant: str, route: str) -> bool: return RouteChecks.check_route_access(route, paths) +class _WriteGrants(BaseModel, frozen=True): + allowed_routes: tuple[str, ...] | None = None + + def require_write_access(user: UserAPIKeyAuth, route: str) -> None: - if not user.allowed_routes: + grants: Final = _WriteGrants.model_validate(user, from_attributes=True).allowed_routes + if not grants: return - grants: Final = TypeAdapter(tuple[str, ...]).validate_python(user.allowed_routes) if not any(_allows_write(grant, route) for grant in grants): raise HTTPException(status_code=403, detail="This credential does not grant alert write access") diff --git a/tests/unit/proxy/alerting_endpoints/test_usage_alerts.py b/tests/unit/proxy/alerting_endpoints/test_usage_alerts.py index 9d8906eb4e0..1270b6809a9 100644 --- a/tests/unit/proxy/alerting_endpoints/test_usage_alerts.py +++ b/tests/unit/proxy/alerting_endpoints/test_usage_alerts.py @@ -25,12 +25,6 @@ def test_info_grants_do_not_authorize_mutations(role: LitellmUserRoles, key_type assert error.value.status_code == 403 -@pytest.mark.parametrize("grant", ["/usage/alert-rules/example", "/usage/*", "management_routes"]) -def test_explicit_management_grants_still_authorize_mutations(grant: str) -> None: - user: Final = UserAPIKeyAuth(user_role=LitellmUserRoles.PROXY_ADMIN, allowed_routes=["info_routes", grant]) - require_write_access(user, "/usage/alert-rules/example") - - @pytest.mark.asyncio @pytest.mark.parametrize( "role,key_type,write",