Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions litellm/proxy/management_endpoints/key_management_endpoints.py
Original file line number Diff line number Diff line change
Expand Up @@ -942,9 +942,9 @@ async def _check_team_key_limits(
where={"team_id": team_table.team_id},
)
# Exclude the key being updated to avoid double-counting its limits.
# key.token is the SHA-256 hash stored in DB; data.key is the raw key string.
# data.key may be a raw key (sk-...) or a pre-hashed token_id.
if isinstance(data, UpdateKeyRequest):
hashed_key = hash_token(data.key)
hashed_key = _hash_token_if_needed(data.key)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Missing test coverage for pre-hashed token_id path

The PR description explains the motivation clearly, but no tests are included that pass a pre-hashed token_id to /key/update. Without a test, it's easy for a future refactor to re-introduce this regression silently.

A minimal test could call update_key_fn (or hit the endpoint via the test client) with a pre-hashed token value and assert that:

  1. The limit-check exclusion filter (key.token != hashed_key) correctly excludes the key.
  2. The cache invalidation call receives the already-hashed value unchanged.

This same coverage gap applies to both the _check_team_key_limits path (line 947) and the _check_org_key_limits path (line 1106).

Rule Used: What: Ensure that any PR claiming to fix an issue ... (source)

keys = [key for key in keys if key.token != hashed_key]
check_team_key_model_specific_limits(
keys=keys,
Expand Down Expand Up @@ -1101,9 +1101,9 @@ async def _check_org_key_limits(
where={"organization_id": org_table.organization_id},
)
# Exclude the key being updated to avoid double-counting its limits.
# key.token is the SHA-256 hash stored in DB; data.key is the raw key string.
# data.key may be a raw key (sk-...) or a pre-hashed token_id.
if isinstance(data, UpdateKeyRequest):
hashed_key = hash_token(data.key)
hashed_key = _hash_token_if_needed(data.key)
keys = [key for key in keys if key.token != hashed_key]
check_org_key_model_specific_limits(
keys=keys,
Expand Down Expand Up @@ -2157,7 +2157,7 @@ async def update_key_fn(
# Delete - key from cache, since it's been updated!
# key updated - a new model could have been added to this key. it should not block requests after this is done
await _delete_cache_key_object(
hashed_token=hash_token(key),
hashed_token=_hash_token_if_needed(key),
user_api_key_cache=user_api_key_cache,
proxy_logging_obj=proxy_logging_obj,
)
Expand Down
Loading