Skip to content

Commit b188f76

Browse files
Merge pull request #15201 from BerriAI/litellm_staging_10_04_2025_p2
(security) prevent user key from updating other user keys + don't return all keys with blank key alias on /v2/key/info
2 parents bf641fe + bb50115 commit b188f76

File tree

3 files changed

+190
-127
lines changed

3 files changed

+190
-127
lines changed

litellm/proxy/_new_secret_config.yaml

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,32 @@
11
model_list:
22
- model_name: openai/gpt-4o
33
litellm_params:
4-
model: openai/gpt-4o
5-
api_key: os.environ/OPENAI_API_KEY
4+
model: openai/gpt-4o-mini
5+
api_base: "https://webhook.site/2f385e05-00aa-402b-86d1-efc9261471a5"
6+
api_key: dummy
7+
- model_name: "byok-wildcard/*"
8+
litellm_params:
9+
model: openai/*
10+
- model_name: xai-grok-3
11+
litellm_params:
12+
model: xai/grok-3
13+
- model_name: hosted_vllm/whisper-v3
14+
litellm_params:
15+
model: hosted_vllm/whisper-v3
16+
api_base: "https://webhook.site/2f385e05-00aa-402b-86d1-efc9261471a5"
17+
api_key: dummy
18+
19+
# mcp_servers:
20+
# github_mcp:
21+
# url: "https://api.githubcopilot.com/mcp"
22+
# auth_type: oauth2
23+
# authorization_url: https://github.com/login/oauth/authorize
24+
# token_url: https://github.com/login/oauth/access_token
25+
# client_id: os.environ/GITHUB_OAUTH_CLIENT_ID
26+
# client_secret: os.environ/GITHUB_OAUTH_CLIENT_SECRET
27+
# scopes: ["public_repo", "user:email"]
28+
# allowed_tools: ["list_tools"]
29+
# # disallowed_tools: ["repo_delete"]
630

731
litellm_settings:
832
callbacks: ["prometheus"]

litellm/proxy/management_endpoints/key_management_endpoints.py

Lines changed: 32 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,10 @@ def _get_user_in_team(
9090
def _calculate_key_rotation_time(rotation_interval: str) -> datetime:
9191
"""
9292
Helper function to calculate the next rotation time for a key based on the rotation interval.
93-
93+
9494
Args:
9595
rotation_interval: String representing the rotation interval (e.g., '30d', '90d', '1h')
96-
96+
9797
Returns:
9898
datetime: The calculated next rotation time in UTC
9999
"""
@@ -102,28 +102,34 @@ def _calculate_key_rotation_time(rotation_interval: str) -> datetime:
102102
return now + timedelta(seconds=interval_seconds)
103103

104104

105-
def _set_key_rotation_fields(data: dict, auto_rotate: bool, rotation_interval: Optional[str]) -> None:
105+
def _set_key_rotation_fields(
106+
data: dict, auto_rotate: bool, rotation_interval: Optional[str]
107+
) -> None:
106108
"""
107109
Helper function to set rotation fields in key data if auto_rotate is enabled.
108-
110+
109111
Args:
110112
data: Dictionary to update with rotation fields
111113
auto_rotate: Whether auto rotation is enabled
112114
rotation_interval: The rotation interval string (required if auto_rotate is True)
113115
"""
114116
if auto_rotate and rotation_interval:
115-
data.update({
116-
"auto_rotate": auto_rotate,
117-
"rotation_interval": rotation_interval,
118-
"key_rotation_at": _calculate_key_rotation_time(rotation_interval)
119-
})
117+
data.update(
118+
{
119+
"auto_rotate": auto_rotate,
120+
"rotation_interval": rotation_interval,
121+
"key_rotation_at": _calculate_key_rotation_time(rotation_interval),
122+
}
123+
)
120124

121125

122126
def _is_allowed_to_make_key_request(
123-
user_api_key_dict: UserAPIKeyAuth, user_id: Optional[str], team_id: Optional[str]
127+
user_api_key_dict: UserAPIKeyAuth,
128+
user_id: Optional[str],
129+
team_id: Optional[str],
124130
) -> bool:
125131
"""
126-
Assert user only creates keys for themselves
132+
Assert user only creates/updates keys for themselves
127133
128134
Relevant issue: https://github.com/BerriAI/litellm/issues/7336
129135
"""
@@ -332,14 +338,15 @@ def common_key_access_checks(
332338
data: Union[GenerateKeyRequest, UpdateKeyRequest],
333339
llm_router: Optional[Router],
334340
premium_user: bool,
341+
user_id: Optional[str] = None,
335342
) -> Literal[True]:
336343
"""
337344
Check if user is allowed to make a key request, for this key
338345
"""
339346
try:
340347
_is_allowed_to_make_key_request(
341348
user_api_key_dict=user_api_key_dict,
342-
user_id=data.user_id,
349+
user_id=user_id or data.user_id,
343350
team_id=data.team_id,
344351
)
345352
except AssertionError as e:
@@ -1136,13 +1143,6 @@ async def update_key_fn(
11361143
if prisma_client is None:
11371144
raise Exception("Not connected to DB!")
11381145

1139-
common_key_access_checks(
1140-
user_api_key_dict=user_api_key_dict,
1141-
data=data,
1142-
llm_router=llm_router,
1143-
premium_user=premium_user,
1144-
)
1145-
11461146
existing_key_row = await prisma_client.get_data(
11471147
token=data.key, table_name="key", query_type="find_unique"
11481148
)
@@ -1153,6 +1153,14 @@ async def update_key_fn(
11531153
detail={"error": f"Team not found, passed team_id={data.team_id}"},
11541154
)
11551155

1156+
common_key_access_checks(
1157+
user_api_key_dict=user_api_key_dict,
1158+
data=data,
1159+
user_id=existing_key_row.user_id,
1160+
llm_router=llm_router,
1161+
premium_user=premium_user,
1162+
)
1163+
11561164
# check if user has permission to update key
11571165
await TeamMemberPermissionChecks.can_team_member_execute_key_management_endpoint(
11581166
user_api_key_dict=user_api_key_dict,
@@ -1198,9 +1206,9 @@ async def update_key_fn(
11981206

11991207
# Handle rotation fields if auto_rotate is being enabled
12001208
_set_key_rotation_fields(
1201-
non_default_values,
1202-
non_default_values.get("auto_rotate", False),
1203-
non_default_values.get("rotation_interval")
1209+
non_default_values,
1210+
non_default_values.get("auto_rotate", False),
1211+
non_default_values.get("rotation_interval"),
12041212
)
12051213

12061214
_data = {**non_default_values, "token": key}
@@ -1602,8 +1610,6 @@ def _check_model_access_group(
16021610
return True
16031611

16041612

1605-
1606-
16071613
async def generate_key_helper_fn( # noqa: PLR0915
16081614
request_type: Literal[
16091615
"user", "key"
@@ -1766,12 +1772,12 @@ async def generate_key_helper_fn( # noqa: PLR0915
17661772
"allowed_routes": allowed_routes or [],
17671773
"object_permission_id": object_permission_id,
17681774
}
1769-
1775+
17701776
# Add rotation fields if auto_rotate is enabled
17711777
_set_key_rotation_fields(
17721778
data=key_data,
17731779
auto_rotate=auto_rotate or False,
1774-
rotation_interval=rotation_interval
1780+
rotation_interval=rotation_interval,
17751781
)
17761782

17771783
if (

0 commit comments

Comments
 (0)