mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-20 00:11:50 +00:00
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> |
||
|---|---|---|
| .. | ||
| test_admin_viewer_handler_access.py | ||
| test_auth_checks.py | ||
| test_auth_exception_handler.py | ||
| test_auth_hot_path_network_requests.py | ||
| test_auth_utils.py | ||
| test_banned_params_extra_body.py | ||
| test_cli_auth.py | ||
| test_custom_auth_end_user_budget.py | ||
| test_handle_jwt.py | ||
| test_info_routes.py | ||
| test_litellm_license.py | ||
| test_login_utils.py | ||
| test_mcp_ip_filtering.py | ||
| test_model_checks.py | ||
| test_model_checks_fallbacks.py | ||
| test_multi_budget_windows.py | ||
| test_network.py | ||
| test_oauth2_proxy_hook.py | ||
| test_object_permission_loading.py | ||
| test_onboarding.py | ||
| test_organization_budget_enforcement.py | ||
| test_password_hashing.py | ||
| test_resolvers_exceptions.py | ||
| test_resolvers_models.py | ||
| test_resolvers_seam.py | ||
| test_resolvers_store.py | ||
| test_route_checks.py | ||
| test_router_override_fallback_auth.py | ||
| test_team_member_budget.py | ||
| test_unmapped_model_budget_enforcement.py | ||
| test_user_api_key_auth.py | ||