From 121d46051ffa3237245d6d2e5b5c34c351f55234 Mon Sep 17 00:00:00 2001 From: ryan-crabbe-berri Date: Fri, 5 Jun 2026 15:23:49 -0700 Subject: [PATCH] feat(proxy): resolve auth_v2 OAuth client secret via the secret manager The RFC 7662 introspection client secret was read straight from config. Resolve it through litellm's get_secret_str at introspection time so it can live in a secret manager (or env ref) instead of plaintext config; a literal value passes through unchanged. Resolved in _introspect rather than at settings load so the secret-manager lookup never runs in can_handle for non-OAuth tokens. mypy clean on 23 files, 141 tests green. --- litellm/proxy/auth/v2/authn/authenticators.py | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/litellm/proxy/auth/v2/authn/authenticators.py b/litellm/proxy/auth/v2/authn/authenticators.py index aa6de0b0beb..3698fd4b9bc 100644 --- a/litellm/proxy/auth/v2/authn/authenticators.py +++ b/litellm/proxy/auth/v2/authn/authenticators.py @@ -258,13 +258,25 @@ class OAuth2IntrospectionAuthenticator: import base64 from litellm.llms.custom_httpx.http_handler import get_async_httpx_client + from litellm.secret_managers.main import get_secret_str from litellm.types.llms.custom_http import httpxSpecialProvider # RFC 7662 client auth is HTTP Basic; the shared handler's post() takes - # headers, not an auth tuple, so build the header explicitly. + # headers, not an auth tuple, so build the header explicitly. Resolve the + # client secret through the secret manager here (not at settings load, which + # runs in can_handle) so it is never required to sit in plaintext config; + # a literal value passes through unchanged. headers = {} if settings.client_id: - credentials = f"{settings.client_id}:{settings.client_secret or ''}" + secret = "" + if settings.client_secret: + secret = ( + get_secret_str( + settings.client_secret, default_value=settings.client_secret + ) + or "" + ) + credentials = f"{settings.client_id}:{secret}" headers["Authorization"] = ( "Basic " + base64.b64encode(credentials.encode()).decode() )