[Fix] Separate key expiration from budget reset logic #15136
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Title
Fix: Separate key expiration from budget reset logic
Relevant issues
Fixes key expiration bug where API keys expire at standardized intervals instead of actual duration from creation time.
Fixes: #15142
Pre-Submission checklist
Please complete all items before asking a LiteLLM maintainer to review your PR
I have Added testing in the
tests/litellm/
directory, Adding at least 1 test is a hard requirement - see detailstests/test_litellm/proxy/management_endpoints/test_key_management_endpoints.py
I have added a screenshot of my new test passing locally
My PR passes all unit tests on
make test-unit
My PR's scope is as isolated as possible, it only solves 1 specific problem
Type
🐛 Bug Fix
Changes
Problem
Key expiration was incorrectly using budget reset logic (
get_budget_reset_time()
), causing keys to expire at standardized intervals (e.g., 1st of next month) instead of the actual duration from creation time.Example of the bug:
duration="1mo"
Why This Is Wrong
Key expiration and budget reset serve fundamentally different purposes and must use different calculation methods:
1. Budget Reset (Financial/Accounting)
get_budget_reset_time()
for standardized intervals2. Key Expiration (Security/Access Control)
duration_in_seconds()
with relative time calculationSolution
File:
litellm/proxy/management_endpoints/key_management_endpoints.py
(lines 1678-1682)Changed key expiration calculation from:
To:
Note: Budget reset logic remains unchanged and continues to use
get_budget_reset_time()
for standardized intervals.Testing
New Tests Added
test_key_expiration_calculated_from_current_time
expires
is calculated ascurrent_time + duration
(not standardized)budget_reset_at
is standardized to 1st of next monthtest_key_expiration_with_various_durations
test_key_budget_reset_uses_standardized_time
Updated Test
test_budget_reset_and_expires_at_first_of_month
expires
to be on 1st of monthTest Results
$ poetry run pytest tests/test_litellm/proxy/management_endpoints/test_key_management_endpoints.py::test_key_expiration_calculated_from_current_time tests/test_litellm/proxy/management_endpoints/test_key_management_endpoints.py::test_key_expiration_with_various_durations tests/test_litellm/proxy/management_endpoints/test_key_management_endpoints.py::test_key_budget_reset_uses_standardized_time tests/test_litellm/proxy/management_endpoints/test_key_management_endpoints.py::test_budget_reset_and_expires_at_first_of_month -v ✅ test_budget_reset_and_expires_at_first_of_month PASSED ✅ test_key_budget_reset_uses_standardized_time PASSED ✅ test_key_expiration_calculated_from_current_time PASSED ✅ test_key_expiration_with_various_durations PASSED 4 passed in 2.19s
Files Changed
litellm/proxy/management_endpoints/key_management_endpoints.py
tests/test_litellm/proxy/management_endpoints/test_key_management_endpoints.py
Backward Compatibility
This change only affects NEW keys created after the fix. Existing keys with already-set expiration times are not modified.
The fix changes how expiration is calculated for new keys:
While this may affect users relying on the buggy behavior for new key creation: