fix(proxy): compare allowed routes semantically

This commit is contained in:
Devin AI 2026-07-14 22:45:22 +00:00
parent 6afdb5f21d
commit 3f0245d312
2 changed files with 25 additions and 5 deletions

View file

@ -18,7 +18,7 @@ import os
import re
import secrets
import traceback
from collections.abc import Mapping
from collections.abc import Mapping, Sequence
from datetime import datetime, timedelta, timezone
from typing import Any, Callable, Dict, List, Literal, Optional, Tuple, cast
@ -530,6 +530,15 @@ def _validate_caller_can_change_key_ownership(
)
def _allowed_routes_values_match(
submitted_routes: Sequence[str] | None,
existing_routes: Sequence[str] | None,
) -> bool:
if submitted_routes is None or existing_routes is None:
return submitted_routes == existing_routes
return set(submitted_routes) == set(existing_routes)
def _check_allowed_routes_caller_permission(
allowed_routes: Optional[list],
user_api_key_dict: UserAPIKeyAuth,
@ -2267,7 +2276,11 @@ async def _validate_update_key_data(
user_api_key_dict=user_api_key_dict,
allowed_routes_was_provided="allowed_routes" in data.model_fields_set,
allowed_routes_changed=(
"allowed_routes" in data.model_fields_set and data.allowed_routes != existing_key_row.allowed_routes
"allowed_routes" in data.model_fields_set
and not _allowed_routes_values_match(
data.allowed_routes,
existing_key_row.allowed_routes,
)
),
)
_check_passthrough_routes_caller_permission(

View file

@ -9589,6 +9589,8 @@ async def test_update_key_non_budget_fields_allowed_for_internal_user(monkeypatc
mock_existing_key.key_alias = None
mock_existing_key.models = []
mock_existing_key.metadata = {}
mock_existing_key.allowed_routes = []
mock_existing_key.permissions = {}
mock_existing_key.model_dump.return_value = {
"token": test_hashed_token,
"user_id": "internal_user",
@ -9650,7 +9652,12 @@ async def test_update_key_non_budget_fields_allowed_for_internal_user(monkeypatc
# Updating key_alias (non-budget field) should succeed
result = await update_key_fn(
request=mock_request,
data=UpdateKeyRequest(key=test_hashed_token, key_alias="my-alias"),
data=UpdateKeyRequest(
key=test_hashed_token,
key_alias="my-alias",
allowed_routes=[],
permissions={},
),
user_api_key_dict=user_api_key_dict,
litellm_changed_by=None,
)
@ -14348,9 +14355,9 @@ async def test_update_key_non_admin_permissions_non_empty_rejected(monkeypatch):
UpdateKeyRequest(
key="sk-alice-personal",
tpm_limit=42,
allowed_routes=["llm_api_routes"],
allowed_routes=["management_routes", "llm_api_routes"],
),
["llm_api_routes"],
["llm_api_routes", "management_routes"],
{},
),
(