From 129534305f1411581f8272a3bb8139a7c4b3c8c6 Mon Sep 17 00:00:00 2001 From: Nicholas Gibson Date: Tue, 18 Aug 2026 13:00:23 -0700 Subject: [PATCH] fix(redis): avoid duplicate Azure AD credentials --- litellm/_redis.py | 2 ++ tests/test_litellm/test_redis.py | 28 +++++++++++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/litellm/_redis.py b/litellm/_redis.py index 0acc01fa14f..609f46592f3 100644 --- a/litellm/_redis.py +++ b/litellm/_redis.py @@ -456,6 +456,8 @@ def _get_redis_client_logic(**env_overrides): # are intentionally NOT exposed on the function to avoid leaking # credentials via inspection or logging. redis_kwargs["redis_connect_func"]._azure_redis_ad_token = True + redis_kwargs.pop("username", None) + redis_kwargs.pop("password", None) # Always remove Azure-specific kwargs that shouldn't be passed to Redis client redis_kwargs.pop("azure_redis_ad_token", None) diff --git a/tests/test_litellm/test_redis.py b/tests/test_litellm/test_redis.py index 896ca2de399..d80aa2e943c 100644 --- a/tests/test_litellm/test_redis.py +++ b/tests/test_litellm/test_redis.py @@ -12,11 +12,12 @@ from litellm._redis import ( get_redis_connection_pool, get_redis_url_from_environment, ) -from litellm.constants import REDIS_CLUSTER_HEALTH_CHECK_INTERVAL from litellm._redis_credential_provider import ( + AzureADCredentialProvider, GCPIAMCredentialProvider, _token_cache, ) +from litellm.constants import REDIS_CLUSTER_HEALTH_CHECK_INTERVAL @pytest.fixture(autouse=True) @@ -259,6 +260,31 @@ def test_get_redis_async_client_without_connection_pool(): ), "connection_pool should not be in kwargs when not provided" +def test_azure_ad_connection_pool_does_not_duplicate_credentials(monkeypatch): + credential = MagicMock() + credential.get_token.return_value.token = "azure-token" + monkeypatch.setenv("REDIS_USERNAME", "entra-user") + monkeypatch.setenv("REDIS_PASSWORD", "static-password") + + with patch("litellm._redis._build_azure_credential", return_value=credential): + pool = get_redis_connection_pool( + host="cache.redis.azure.net", + port=10000, + ssl=True, + azure_redis_ad_token="true", + ) + + assert pool is not None + connection = pool.make_connection() + assert isinstance(connection.credential_provider, AzureADCredentialProvider) + assert connection.username is None + assert connection.password is None + assert connection.credential_provider.get_credentials() == ( + "entra-user", + "azure-token", + ) + + def test_gcp_iam_credential_provider_get_credentials(): """GCPIAMCredentialProvider.get_credentials() returns a token tuple.""" service_account = "projects/-/serviceAccounts/test@project.iam.gserviceaccount.com"