Commit Graph

36327 Commits

Author SHA1 Message Date
Ryan Crabbe
191bb9504d
chore(ui): migrate Tremor Text/Badge to antd Tag and native spans in logging_settings_view
Replace Tremor Text with native <span> elements (with block class where
stacking is needed) and Tremor Badge with antd Tag. All Tailwind classes
preserved. Gray badge default mapped to undefined (antd Tag default).
2026-03-28 16:59:19 -07:00
ryan-crabbe-berri
8fb27c697c
Merge pull request #24746 from BerriAI/litellm_feat-substring-key-filters
feat: support substring search for user_id and key_alias on /key/list
2026-03-28 16:57:11 -07:00
Ryan Crabbe
a59acc8f8a
[Fix] Derive use_substring_matching from role, not auto-set path
Substring matching for user_id and key_alias on /key/list is now gated
by caller role (admin only) rather than by whether user_id was auto-set.
This closes the gap where a non-admin explicitly passing their own
user_id still got contains-based filtering, which could surface keys
belonging to other users with overlapping IDs.

Adds three unit tests covering the substring, exact-match, and default
code paths in _build_key_filter_conditions. Restores the existing
member-team test to assert exact matching as a security regression guard.
2026-03-28 16:50:09 -07:00
ryan-crabbe-berri
77ad1ab530
Merge pull request #24745 from BerriAI/litellm_fix-logs-filtering
Fix logs page showing unfiltered results when filter matches zero rows
2026-03-28 16:24:09 -07:00
Ryan Crabbe
8a2186a654
[Fix] Reset page to 1 on filter reset and use pageSize param in fallbacks
Add setCurrentPage(1) to handleFilterReset in the hook so page resets
regardless of which component consumes it. Replace hardcoded page_size: 50
in empty-state fallbacks with the pageSize parameter for consistency.
2026-03-28 16:19:03 -07:00
ryan-crabbe-berri
9c59d5ee1b
Merge pull request #24747 from BerriAI/litellm_docs-high-availability
docs: Improve HA control plane diagram clarity
2026-03-28 16:11:12 -07:00
Ryan Crabbe
9284395c1d
[Fix] Hide connector label on mobile, remove stale master key mention
Hide .connectorBranchLabeled on ≤768px so the "UI management only"
label doesn't render without its branch lines. Also remove "master key"
from doc text since the diagram intentionally omits that box.
2026-03-28 15:51:44 -07:00
Ryan Crabbe
d332c5b541
[Docs] Improve high availability control plane diagram clarity
Show each worker's DB and Redis as prominent infra boxes instead of
small chips, and clarify that the control plane is admin UI only —
not a router.
2026-03-28 15:29:02 -07:00
Ryan Crabbe
65df501f15
Simplify substring search — remove admin-only gating
Substring matching for user_id and key_alias now applies unconditionally.
The admin-only flag was unnecessary since user_ids are typically UUIDs/emails
where substring collisions are not a practical concern. Updated existing test
to assert the new filter structure.
2026-03-28 14:50:31 -07:00
Ryan Crabbe
8881c36405
[Fix] Restrict substring key filters to admin users only
Non-admin users had their auto-set user_id go through substring matching,
which could leak keys belonging to other users with overlapping IDs.
Substring matching for user_id and key_alias now only applies when an
admin explicitly provides the filter parameter.
2026-03-28 14:20:07 -07:00
Ryan Crabbe
33bd570d5e
[Feat] Support substring search for user_id and key_alias filters on /key/list
The key list endpoint used exact-match filtering for user_id and key_alias,
requiring users to type the full value (e.g. full email address) to find keys.
Switch to Prisma `contains` with case-insensitive mode, matching the pattern
already used by /v2/team/list for team_alias.
2026-03-28 14:01:05 -07:00
Ryan Crabbe
fbddab6178
Handle search error state and cancel wasted API call on filter reset
- Set backendFilteredLogs to empty response on performSearch error so the
  UI shows "0 results" instead of appearing stuck in a loading state
- Cancel debounced search on filter reset instead of firing a request
  whose result would be ignored (hasBackendFilters is false after reset)
- Clear backendFilteredLogs immediately on filter change to prevent
  stale results from previous filter showing during debounce window
- Normalize response.data with nullish coalescing to handle missing data
- Use `not team_object.models` for None-safe emptiness check
2026-03-28 13:59:17 -07:00
ryan-crabbe-berri
479c5e21aa
Merge pull request #24743 from BerriAI/litellm_fix-access-group-models-in-ui
[Fix] Include access group models in UI model listing
2026-03-28 13:21:43 -07:00
Ryan Crabbe
640ea9228f
Remove unnecessary getattr defense for Prisma-backed field 2026-03-28 12:42:25 -07:00
Ryan Crabbe
8d9bbc6eb2
[Fix] Include access group models in UI model listing
Models associated with a team only through access groups (not directly in
team.models) were not appearing on the /ui/?page=models page. The API
authorization path already resolved access groups correctly, but the
/v2/model/info listing endpoint only checked team.models.

Add _add_access_group_models_to_team_models() which batch-fetches all
distinct access groups in a single find_many query, then resolves each
team's access group models into deployments and merges them into the
team_models dict.
2026-03-28 12:32:12 -07:00
Ryan Crabbe
12a55a8a6f
Fix logs page showing unfiltered results when filter matches zero rows
The backendFilteredLogs state initialized to { data: [], ... } which was
indistinguishable from "API returned empty results". When backend filters
were active, the filteredLogs memo fell back to showing unfiltered `logs`
because it couldn't tell whether a search had completed or not.

Fix: use null as initial state so we can distinguish "not yet searched"
(null → show empty placeholder) from "search returned empty" ({ data: [] }
→ show empty results). This prevents the fallback to unfiltered logs that
caused the model filter to display mismatched data.
2026-03-28 12:03:03 -07:00
yuneng-jiang
666a31d47a
Merge pull request #24741 from BerriAI/litellm_gha_p2
[Fix] Test Isolation and Path Resolution for GHA Unit Tests
2026-03-28 11:32:48 -07:00
Yuneng Jiang
7851567091
[Fix] Scope documentation workflow to match CircleCI and add missing router settings
Revert path fixes for documentation tests that CircleCI never ran
(test_exception_types, test_general_setting_keys, test_readme_providers,
test_standard_logging_payload). Update the GHA workflow to run only the
4 tests CircleCI actually executed: test_env_keys, test_router_settings,
test_api_docs, test_circular_imports.

Add 2 missing router_settings keys (enable_health_check_routing,
health_check_staleness_threshold) and 27 missing general_settings keys
to config_settings.md so test_router_settings passes.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 11:23:53 -07:00
Yuneng Jiang
7100ed5d0a
[Fix] Test isolation for agent health checks and documentation test path resolution
Fix agent health check tests failing with 500 errors in parallel CI by
mocking prisma_client to None. Fix documentation validation tests using
CWD-relative paths that break depending on the working directory.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 11:00:22 -07:00
yuneng-jiang
428d837704
Merge pull request #24740 from BerriAI/litellm_unit_test_workflow_isolation
[Infra] Isolate unit test workflows with hardened security posture
2026-03-28 10:30:13 -07:00
Yuneng Jiang
c717189ed2
[Infra] Remove workflows that require API keys or external services
These test suites are not pure unit tests and don't belong in Phase 1:
- litellm_utils_tests: health check tests need OPENAI_API_KEY
- pass_through_unit_tests: tests hit real Anthropic API
- router_unit_tests: tests call real OpenAI moderation endpoints
- proxy_security_tests: requires DATABASE_URL (Postgres)
- documentation_tests: requires docs directory at specific relative path

These will be re-added in later phases with proper secret scoping.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 10:16:19 -07:00
Yuneng Jiang
a34ed20901
[Infra] Fix job naming in reusable workflow callers
Rename job keys from generic 'test' to descriptive names (e.g.,
'core-utils', 'proxy-auth', 'router') so GitHub checks display as
'core-utils / run' instead of 'test / test'.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 10:07:32 -07:00
Yuneng Jiang
3d527b722d
[Infra] Add isolated unit test workflows with hardened security posture
Replace monolithic matrix workflow with individual, descriptively-named
workflow files. Each workflow uses a shared reusable base and follows
least-privilege security: zero secrets, read-only permissions, SHA-pinned
actions, persist-credentials: false, and env-var indirection to prevent
template injection.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 09:56:58 -07:00
ryan-crabbe-berri
2eb3c20e76
Merge pull request #24718 from BerriAI/litellm_ryan-march-26
litellm ryan march 26
2026-03-28 09:01:11 -07:00
ryan-crabbe-berri
726a34627c
Merge pull request #24717 from BerriAI/litellm_fix-user-cache-invalidation
fix(jwt): invalidate user cache after role/team sync updates
2026-03-27 19:50:41 -07:00
ryan-crabbe-berri
7907e5e126
Merge pull request #24711 from BerriAI/litellm_fix-edit-budget
fix(ui): refactor budget page to React Query hooks and fix crashes
2026-03-27 19:49:30 -07:00
Ryan Crabbe
dd11e77852
fix: add explicit TTL to cache writes and test coverage for user cache invalidation
Add DEFAULT_MANAGEMENT_OBJECT_IN_MEMORY_CACHE_TTL to both async_set_cache
calls in sync_user_role_and_teams for consistency with all other user cache
writes. Add 3 tests covering cache invalidation on role change, team change,
and no-op when nothing changes.
2026-03-27 19:45:13 -07:00
Ryan Crabbe
2ece79930b
fix(jwt): invalidate user cache after role/team sync updates
sync_user_role_and_teams updates the DB when a user's JWT role changes,
but the in-memory cache retained the stale role until TTL expiry. This
caused subsequent requests to see the old role for up to 60 seconds.

Fix: accept user_api_key_cache parameter and re-cache the updated user
object after both role and team membership DB writes.
2026-03-27 19:36:38 -07:00
Ryan Crabbe
98ecf17550
fix(ui): refactor budget page to React Query hooks and fix crashes
- Migrate budget CRUD from manual state to React Query hooks (useBudgets, useCreateBudget, useUpdateBudget, useDeleteBudget)
- Fix crash when budget list contains null entries by filtering in query hook
- Fix max_budget type from string to number to match DB schema (double precision)
- Disable budget_id field in edit modal to prevent accidental changes
- Use budget_id as React key instead of array index
- Update tests to mock hooks instead of networking functions
2026-03-27 19:34:24 -07:00
ryan-crabbe-berri
5b651048f2
Merge pull request #24706 from BerriAI/litellm_fix-jwt-none-guard
fix(auth): guard JWTHandler.is_jwt() against None token
2026-03-27 18:06:24 -07:00
ryan-crabbe-berri
a533de0b08
Merge pull request #24701 from BerriAI/litellm_fix-jwt-role-mappings
fix(sso): pass decoded JWT access token to role mapping during SSO login
2026-03-27 18:06:15 -07:00
ryan-crabbe-berri
52e9ca7a73
Merge pull request #24708 from BerriAI/litellm_fix-bulk-update
fix: add /user/bulk_update to management routes
2026-03-27 18:05:16 -07:00
Ryan Crabbe
0c67f274e5
docs: add /user/bulk_update to internal_user_endpoints module docstring 2026-03-27 18:01:08 -07:00
Ryan Crabbe
a5ff668f5e
fix: add /user/bulk_update to management_routes so proxy admins can access it
/user/bulk_update was missing from the management_routes list in _types.py,
causing it to fall through to a 403 in non_proxy_admin_allowed_routes_check
even for proxy admin users. Also added it to the PROXY_ADMIN_VIEW_ONLY
blocked write operations list in route_checks.py to prevent view-only
admins from using it.
2026-03-27 17:50:42 -07:00
yuneng-jiang
fe080a86b2
Merge pull request #24705 from BerriAI/litellm_auto_schema_sync
[Infra] Automated schema.prisma sync and drift detection
2026-03-27 17:08:23 -07:00
yuneng-jiang
846e4b44b6
Merge pull request #24682 from michelligabriele/fix/budget-spend-counters
fix(proxy): enforce budget limits across multi-pod deployments via Redis-backed spend counters
2026-03-27 16:59:23 -07:00
Ryan Crabbe
8e3755931d
test(auth): add regression tests for JWTHandler.is_jwt(None)
Add None-token test cases to both proxy_unit_tests and test_litellm
to cover the guard added in the previous commit. Also add -> bool
return type annotation to is_jwt().
2026-03-27 16:51:08 -07:00
Ryan Crabbe
e36ab04a18
fix(auth): guard JWTHandler.is_jwt() against None token
When JWT auth is enabled and a request arrives without an Authorization
header (e.g. health checks, monitoring), api_key is None due to
APIKeyHeader(auto_error=False). The is_jwt() call crashes with
AttributeError: 'NoneType' object has no attribute 'split'.

Return False for None tokens since they are not JWTs.
2026-03-27 16:51:08 -07:00
Yuneng Jiang
a074d1d68b
[Infra] Mirror litellm_table_patch source changes (no binaries)
Cherry-pick source-only changes from litellm_table_patch, excluding
build artifacts from the incident response period.

- Remove destructive DROP COLUMN migration (20260311180521_schema_sync)
- Remove now-unnecessary restore migration (20260327232350)
- Bump litellm-proxy-extras 0.4.60 → 0.4.61
- Add regression test to block future DROP COLUMN migrations
- Fix double error handling in getTeamPermissionsCall

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:45:12 -07:00
Yuneng Jiang
46b92da0bd
[Infra] Add migration for restored BYOM lifecycle fields
The schema sync adopted the proxy version which includes source_url,
approval_status, and other BYOM fields. These were previously dropped
in migration 20260311180521 due to schema drift. This migration
restores them to match the now-unified schema.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:24:03 -07:00
Yuneng Jiang
e0e0c5e293
[Infra] Fix zizmor artipacked warnings on schema sync workflows
Add persist-credentials: false to check-schema-sync (read-only, no push needed).
Explicitly set persist-credentials: true on sync-schema (required for git push).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:14:06 -07:00
Yuneng Jiang
08e29e0a9a
[Infra] Automated schema.prisma sync and drift detection
Sync all 3 schema.prisma copies and add GHA workflows to keep them in sync automatically.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 16:01:20 -07:00
Ryan Crabbe
e24819afef
fix(sso): pass decoded JWT access token to role mapping during SSO login
During SSO login, bearer tokens are stripped from the OAuth response
before role mapping runs. Custom role claims encoded inside the JWT
access token are lost, so map_jwt_role_to_litellm_role() returns None
and the user falls back to internal_user_viewer.

process_sso_jwt_access_token() now returns the decoded JWT payload, and
a new _sync_user_role_from_jwt_role_map() receives it so
jwt_litellm_role_map works correctly during SSO login.
2026-03-27 13:50:30 -07:00
michelligabriele
d533b432fd
fix(proxy): enforce budget limits across multi-pod deployments via Redis-backed spend counters
Budget checks on API keys, teams, and team members were not enforced in
multi-pod deployments because user_api_key_cache is intentionally
in-memory-only. Each pod tracked spend independently, so with N pods
the effective budget was N × max_budget.

Introduces a separate spend_counter_cache (DualCache wired to
redis_usage_cache) with atomic increment/read helpers:
- increment_spend_counters(): awaited in cost callback (not create_task)
  to update both in-memory and Redis before the next auth check
- get_current_spend(): reads Redis first (cross-pod authoritative),
  falls back to in-memory, then to cached object .spend from DB

Budget check functions (_virtual_key_max_budget_check,
_team_max_budget_check, _check_team_member_budget) now read spend via
get_current_spend() instead of cached object .spend fields.

When Redis is not configured, falls back to in-memory-only counters
(same as current single-instance behavior).

Fixes #23714
2026-03-27 20:39:52 +01:00
yuneng-jiang
d949085310
Merge pull request #24697 from BerriAI/litellm_codeql_gha
[Infra] Improve CodeQL scanning coverage and schedule
2026-03-27 12:17:39 -07:00
yuneng-jiang
241c45663b
Merge pull request #24696 from BerriAI/litellm_pin_prisma_node_ci
[Fix] Pin Prisma Node.js dependency in CI workflows
2026-03-27 12:17:26 -07:00
Yuneng Jiang
ec4273ed8b
[Infra] Improve CodeQL scanning coverage and schedule
Switch query suite from security-extended to security-and-quality to
match the default GitHub Advanced Security setup. Run scheduled scans
daily instead of weekly. Remove paths-ignore for _experimental/out so
build artifacts are also scanned.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 12:04:09 -07:00
yuneng-jiang
1b111d23f3
Merge pull request #24688 from Sameerlite/litellm_litellm_team-model-group-name-routing-fix
fix(team-routing): preserve sibling deployment candidates for team public models
2026-03-27 12:00:34 -07:00
Sameer Kankute
c4159a2ade
Fix codeql 2026-03-28 00:01:33 +05:30
Yuneng Jiang
ca3457b091
Pin nodejs-wheel-binaries in CI workflows running prisma generate
prisma generate internally runs `npm install prisma@5.4.2` against the
npm registry at runtime. Without a bundled Node.js, this causes
ECONNRESET failures on flaky GitHub Actions network and leaves the
npm transitive dependency tree unpinned.

Pre-install nodejs-wheel-binaries==24.13.1 (matching the Dockerfiles)
so prisma uses the bundled Node/npm instead of fetching from the
registry.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-27 11:25:03 -07:00