litellm/tests/enterprise/litellm_enterprise/proxy
ryan-crabbe-berri 83ab6e08da
fix(proxy): invalidate cached project object on project update and delete (#36028)
* fix(proxy): invalidate cached project object on /project/update and /project/delete

The auth path reads projects cache-first via get_project_object with a 60s
TTL and no freshness check, but no project write endpoint ever evicted the
project_id:{id} cache entry. A project cached before /project/update added a
model allowlist kept an empty models list in cache, so _run_project_checks
skipped can_project_access_model and project-bound keys could call team
models outside the project allowlist until the TTL expired. The same
staleness applied to blocked status and budget fields, and /project/delete
left the deleted project enforceable from cache.

Evict the cache entry after the DB write in update_project and
delete_project via a shared delete_cached_project_object helper, with the
cache key derivation shared with get_project_object.

* fix(proxy): broadcast project cache invalidation to all workers and make eviction best-effort

Single-worker eviction leaves every other worker serving its in-memory copy
of the mutated project until the 60s TTL expires, so a project allowlist
change was still bypassable on multi-worker deployments. Add a coordination
Redis pub/sub channel (litellm_proxy.auth_cache_invalidation): project
eviction publishes the cache key and a per-worker subscriber deletes the
local in-memory entry, with the next auth read refetching from the DB.
Subscriber starts on any deployment with a coordination Redis and falls back
to the TTL when none is configured.

Also wrap the eviction in a best-effort catch: the DB write has already
committed when eviction runs, so a cache backend error must not turn a
successful update into a 500 or abort the remaining ids in /project/delete.

* fix(lint): sort auth cache invalidation import and suppress best-effort shutdown catch

The strict-budget gate flagged the new import block as un-sorted (I001) and
the broad except in stop_auth_cache_invalidation_subscriber (BLE001); the
catch is intentional since a failing stop must not break proxy shutdown, so
it carries a named suppression instead of counting against the budget.
2026-08-07 15:19:00 +00:00
..
auth feat(auth): resolve caller identity once into a Principal at the auth seam (#30887) 2026-06-20 18:49:41 -07:00
guardrails fix(guardrails/bedrock): honor disable_exception_on_block by raising ModifyResponseException (#32289) 2026-07-09 13:18:51 -07:00
hooks fix(batches): keep an empty after meaning "start from the beginning" 2026-07-24 19:49:13 -07:00
management_endpoints fix(proxy): invalidate cached project object on project update and delete (#36028) 2026-08-07 15:19:00 +00:00
test_audit_logging_endpoints.py fixes test 2025-10-28 17:43:04 -07:00