chore(release): backport #29612 (session-token budget-ceiling exemption) into stable/1.86.x and cut 1.86.5 - #29635
Conversation
…ng for team keys (#29612) Non-admin users creating a team key through the UI were rejected with "max_budget cannot exceed the caller's own max_budget (0.25)". The request is authenticated by a UI/CLI session token whose max_budget is the per-session chat spend cap (max_ui_session_budget, default $0.25), and the delegated-authority budget ceiling (GHSA-q775-qw9r-2r4g) treated that cap as a delegation limit. Skip the ceiling only when a session token creates a team key (data.team_id set); that key's spend is bounded by the team budget at request time. Personal keys and every other non-admin caller keep the ceiling, so a session token cannot mint an arbitrary-budget personal key. (cherry picked from commit 97ba7e1)
Greptile SummaryThis backport cherry-picks #29612 onto
Confidence Score: 5/5Safe to merge — the change is a narrow, well-scoped exemption that preserves the budget ceiling for all personal-key creation paths and is guarded by three targeted regression tests. The implementation correctly captures No files require special attention.
|
| Filename | Overview |
|---|---|
| litellm/proxy/management_endpoints/key_management_endpoints.py | Captures _requested_team_id before the defaults loop and adds is_ui_session_team_key guard to exempt UI/CLI session tokens from the GHSA-q775 budget ceiling only when explicitly creating a team key. Logic is correct and well-commented. |
| tests/test_litellm/proxy/management_endpoints/test_key_management_endpoints.py | Adds three targeted regression tests. The two security-regression tests (personal key ceiling, default-team_id bypass) use strong pytest.raises assertions. The exemption test uses a weaker try/except pattern (already flagged in previous review thread). |
| pyproject.toml | Routine version bump 1.86.4 → 1.86.5 in both [project] and [tool.commitizen] sections. |
Reviews (2): Last reviewed commit: "fix(key_generate): harden GHSA-q775 sess..." | Re-trigger Greptile
|
|
||
| @pytest.mark.asyncio | ||
| async def test_ghsa_q775_ui_session_token_personal_key_still_capped(): | ||
| """ | ||
| Security regression for GHSA-q775: the session-token exemption must NOT extend | ||
| to personal keys. A UI/CLI session token (team_id=litellm-dashboard) creating a | ||
| key with no data.team_id is still bound by the ceiling; otherwise a session | ||
| token - or a leaked one, whose blast radius is the $0.25 chat cap - could mint | ||
| an arbitrary-budget personal key, the exact escalation GHSA-q775 closed. Unlike |
There was a problem hiding this comment.
Weak assertion may pass even if ceiling check is never reached
The try/except only asserts that the failure message (if any) does not contain "cannot exceed". If _common_key_generation_helper raises for a completely different reason before it reaches the budget-ceiling block (e.g., a mock attribute access error from team_table=MagicMock()), the assertion still passes, giving a false green on the exemption under test. Consider asserting an explicit success or using pytest.raises with a match on the opposite condition, similar to how the companion personal-key test uses pytest.raises(...) as exc_info followed by a strong assert "cannot exceed" in msg.lower().
Codecov Report❌ Patch coverage is
📢 Thoughts on this report? Let us know! |
…efault_key_generate_params Capture _requested_team_id before the default_key_generate_params loop runs and key the UI/CLI session-token budget-ceiling exemption off it, instead of the post-defaults data.team_id. On an install that sets default_key_generate_params.team_id, a session token requesting a personal key (no explicit team_id) would otherwise have data.team_id auto-filled, flipping is_ui_session_team_key on and bypassing the delegated-authority ceiling -- the exact escalation GHSA-q775 closed. Mirrors the existing pre-defaults capture of _requested_max_budget. Adds a regression test. https://claude.ai/code/session_01RT583b1khYC3wjLrQ5hT5h (cherry picked from commit efeb101)
Relevant issues
Backports #29612 (fixes #29073) onto the 1.86.x line, which already received the earlier batch (#29628–#29632). Cherry-picked from the squashed commit that landed on
litellm_internal_staging(97ba7e1a30). Cuts 1.86.5What is included
The last two commits are the version bump (1.86.4 → 1.86.5) and the matching uv.lock refresh
#29612 applies cleanly here: 1.86.x carries the GHSA-q775 delegated-authority budget ceiling (introduced by #27897) that this fix adds an exemption to. The cherry-pick is byte-identical to upstream (
2 files changed, 93 insertions(+), no conflicts)Pre-Submission checklist
make test-unitType
Bug Fix
Infrastructure
Changes
See the commit list. No new code beyond the cherry-pick, the version bump, and the lockfile refresh