litellm/tests/test_litellm/proxy/auth
devin-ai-integration[bot] 52403d7a8d
fix(jwt): retry JWKS fetches, serve stale keys, and return 503 when the IdP is unreachable (#37690)
A JWKS fetch had no retry, so a single connect timeout to the identity provider
failed authentication outright, and once the cached copy expired there was
nothing to fall back on. How that surfaced depended on the outage shape:
httpx.ConnectTimeout was missing from DB_CONNECTION_ERROR_TYPES so it fell
through to the generic auth handler as a 401 with an empty detail, while a read
timeout took the database path and reported a healthy database as unreachable.

Transport failures are now retried three times with a short backoff, and the
last-known-good JWKS stays usable for a bounded window past public_key_ttl.
That window is public_key_stale_ttl, a new config field defaulting to 3600s and
settable to 0 to fail closed. It is checked on every read against the current
setting rather than baked into the cache entry when it is written, so lowering
it binds immediately instead of waiting for entries written under the old value
to age out, which matters because a shared cache survives the restart an
operator performs to make the change take effect. A copy whose write time
cannot be established is not servable. Only httpx.TransportError unlocks the
stale copy, so an identity provider that answers at all, including with a
narrowed key set, revokes on the next refresh. Every stale serve logs the kid
it authenticated, how long ago that copy was refreshed, and how long until it
stops being trusted.

A sustained outage is remembered for 30s per key url, so it costs one fetch per
window instead of three timeouts per request serialised behind the refresh lock.
Non-200 JWKS responses now raise instead of being cached as the key set, which
previously let an error body overwrite the last-known-good copy. An unreachable
identity provider with no cached copy left returns 503 auth_provider_unavailable.

Resolves LIT-5524

Co-authored-by: Yassin Kortam <yassin@berri.ai>
2026-08-20 16:41:06 -07:00
..
test_admin_viewer_handler_access.py feat(proxy): add GET /management/v1/budgets (#35310) 2026-07-31 11:47:05 -07:00
test_auth_checks.py fix(auth): cache team member default budget as a typed model (#37695) 2026-08-20 16:00:57 -07:00
test_auth_exception_handler.py fix(proxy): capture requester IP in 401 and auth-time 429 failure logs (#37707) 2026-08-20 16:05:59 -07:00
test_auth_hot_path_network_requests.py perf(auth): negative-cache missing user/key lookups on the request hot path (#32368) 2026-07-08 09:59:57 +03:00
test_auth_utils.py feat(rust): route /chat/completions through the Rust core for anthropic and bedrock (#37241) 2026-08-20 16:15:24 -07:00
test_banned_params_extra_body.py fix(proxy): ban caller-supplied aws identity selectors in request bodies 2026-08-10 22:05:49 -07:00
test_cli_auth.py fix(cli): surface actionable CLI SSO errors when CLI and proxy versions skew (#33309) 2026-07-15 10:17:40 -07:00
test_custom_auth_end_user_budget.py fix(proxy): registry caches stop per-request tag and end-user Postgres reads in auth (#36801) 2026-08-17 18:52:13 +00:00
test_handle_jwt.py fix(jwt): retry JWKS fetches, serve stale keys, and return 503 when the IdP is unreachable (#37690) 2026-08-20 16:41:06 -07:00
test_info_routes.py style: run black formatter on files from main merge 2026-04-17 13:02:59 -07:00
test_litellm_license.py style: run black formatter on files from main merge 2026-04-17 13:02:59 -07:00
test_login_utils.py feat(mcp): gateway DCR session admission at the aggregate /mcp endpoint (LIT-3637) 2026-07-23 00:24:28 -07:00
test_mcp_ip_filtering.py feat(mcp): add mcp_xff_num_trusted_hops to harden X-Forwarded-For client IP resolution (#31257) 2026-06-25 07:31:29 -07:00
test_model_checks.py fix(proxy): expand config-defined model access groups when resolving team models for /v2/model/info (#34211) 2026-08-12 12:54:36 -07:00
test_model_checks_fallbacks.py perf: build log messages lazily so filtered-out log records cost nothing (#35703) 2026-08-04 04:34:52 +00:00
test_multi_budget_windows.py fix(proxy): enforce budgets against authoritative DB spend when the cross-pod counter is unreliable (#30684) 2026-06-18 10:35:41 -07:00
test_network.py feat(auth): resolve caller identity once into a Principal at the auth seam (#30887) 2026-06-20 18:49:41 -07:00
test_oauth2_proxy_hook.py chore(auth): require trusted proxy for header identity auth 2026-04-29 21:20:21 -07:00
test_object_permission_loading.py style: run black formatter on files from main merge 2026-04-17 13:02:59 -07:00
test_onboarding.py feat(auth): resolve caller identity once into a Principal at the auth seam (#30887) 2026-06-20 18:49:41 -07:00
test_organization_budget_enforcement.py style: run black formatter on files from main merge 2026-04-17 13:02:59 -07:00
test_password_hashing.py chore: fixes 2026-03-30 18:36:58 -07:00
test_resolvers_exceptions.py feat(auth): resolve caller identity once into a Principal at the auth seam (#30887) 2026-06-20 18:49:41 -07:00
test_resolvers_models.py feat(auth): resolve caller identity once into a Principal at the auth seam (#30887) 2026-06-20 18:49:41 -07:00
test_resolvers_seam.py feat(auth): resolve caller identity once into a Principal at the auth seam (#30887) 2026-06-20 18:49:41 -07:00
test_resolvers_store.py feat(auth): resolve caller identity once into a Principal at the auth seam (#30887) 2026-06-20 18:49:41 -07:00
test_route_checks.py fix(proxy): split agent inference and management routes so admin nodes can create agents (#37730) 2026-08-20 16:03:15 -07:00
test_router_override_fallback_auth.py chore(proxy): clean up request parameter validation and provider destination handling (#34189) 2026-07-22 00:57:58 +00:00
test_team_member_budget.py Fix team member budget enforcement without user row (#27273) 2026-05-06 11:42:29 -07:00
test_unmapped_model_budget_enforcement.py fix(router): never price a strategy-router alias (#36691) 2026-08-12 14:26:30 -07:00
test_user_api_key_auth.py fix(proxy): registry caches stop per-request tag and end-user Postgres reads in auth (#36801) 2026-08-17 18:52:13 +00:00