Skip to content

feat: add ability to auth to azure with token - #27556

Merged
oss-pr-review-agent-shin[bot] merged 6 commits into
shin_agent_oss_staging_05_09_2026from
litellm_azure_auth_handle
May 9, 2026
Merged

feat: add ability to auth to azure with token#27556
oss-pr-review-agent-shin[bot] merged 6 commits into
shin_agent_oss_staging_05_09_2026from
litellm_azure_auth_handle

Conversation

@shivamrawat1

@shivamrawat1 shivamrawat1 commented May 9, 2026

Copy link
Copy Markdown
Collaborator

Resolves LIT-1735
Description

Adds Azure AD (Entra ID) passwordless authentication for LiteLLM's Redis cache, mirroring the
existing GCP IAM support. Sync clients, async clients, async clusters, and async connection pools
all authenticate via the azure-identity SDK and refresh tokens silently before the ~1h TTL expires.
Supports DefaultAzureCredential, ManagedIdentityCredential, and ClientSecretCredential selection
based on which env vars are set.

Enable with REDIS_AZURE_AD_TOKEN=true plus AZURE_CLIENT_ID / AZURE_TENANT_ID / AZURE_CLIENT_SECRET
(or rely on workload identity / managed identity discovery).

Cause

LiteLLM's existing Redis auth supported only static passwords or GCP IAM. Operators running Azure
Cache for Redis with AAD auth (a hard requirement on many Azure environments — Microsoft has been
pushing customers off shared keys) had no first-class way to wire it up. Several attempts in the
wild were patching this in via redis_connect_func themselves, with two recurring footguns:

  1. Token-as-password baked into long-lived pools. A single Azure AD token captured at pool creation
    expires after ~1 hour, after which every new connection out of the pool fails authentication —
    silently bricking caching workloads. This is what the original PR feat: add ability to auth to azure with token #21764 shipped, and what the
    review caught.
  2. Raw client secret attached as a function attribute. The first cherry-pick stored
    _azure_client_id / _azure_tenant_id / _azure_client_secret directly on redis_connect_func so async
    paths could read them back — exposing the secret to anything that inspects, serialises, or logs the
    function object.

There was also no test coverage that worked without azure-identity installed, no REDIS_USERNAME
propagation in the pool path (breaking ACL-configured Azure Redis instances), and
_get_redis_client_logic tripped Ruff's PLR0915 once the new branches were added.

Fix

  • AzureADCredentialProvider (new in litellm/_redis_credential_provider.py) wraps a live
    azure-identity credential. It implements redis.credentials.CredentialProvider and is invoked
    per-connection by redis-py, so the SDK's internal token cache + silent refresh apply to async
    cluster, async standard, and BlockingConnectionPool paths. No more static-token-baked-in-pool
    expiry.
  • create_azure_ad_redis_connect_func (sync path) builds the credential once and reuses it across
    reconnects via the function's closure. Attaches the built credential object (_azure_credential) —
    not the raw inputs — for async paths to discover.
  • _get_redis_client_logic sets redis_connect_func from REDIS_AZURE_AD_TOKEN=true, marks it with
    azure_redis_ad_token = True for detection, and strips the four azure* kwargs before they hit the
    redis-py constructors. GCP IAM takes precedence if both are configured (with a warning).
  • REDIS_USERNAME is now honoured in all three async paths (cluster, standard, pool) via the
    credential provider, so ACL-configured Azure Redis instances connect cleanly.
  • Tests mock azure.identity via sys.modules so they pass without the package installed in CI; new
    tests cover the helpers, ImportError, service-principal selection, and that raw secrets are not
    exposed on the function.
  • Lint: # noqa: PLR0915 on _get_redis_client_logic (the function is a long sequence of optional
    config probes — splitting it would just scatter related logic).

Files: litellm/_redis.py (+219), litellm/_redis_credential_provider.py (+35),
tests/test_litellm/test_utils.py (+122).

shivamrawat1 and others added 4 commits May 7, 2026 18:39
Mirrors the system-message skip in PR #25481 for tool-role messages.
Adds a global litellm.skip_tool_message_in_guardrail flag and a
per-guardrail litellm_params.skip_tool_message_in_guardrail override,
applied in the OpenAI and Anthropic chat translation handlers.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a tri-state control (inherit / yes / no) when creating or editing
guardrails so admins can set litellm_params.skip_tool_message_in_guardrail
without YAML, mirroring the existing skip_system_message control.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…guardrails

  feat(guardrails): optional skip tool message in unified guardrail inputs
Cherry-pick of PR #21764 — adds Azure AD token authentication for Redis,
adapted to coexist with the existing GCP IAM credential provider refactor
on this branch.

Adds `_generate_azure_ad_redis_token`, `_build_azure_credential`, and
`create_azure_ad_redis_connect_func`, threads Azure AD config through
sync, async, async cluster, and connection pool paths, and includes
unit tests for the helpers and `_get_redis_client_logic` setup.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@codecov

codecov Bot commented May 9, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 62.50000% with 33 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
litellm/_redis.py 68.05% 23 Missing ⚠️
litellm/_redis_credential_provider.py 37.50% 10 Missing ⚠️

📢 Thoughts on this report? Let us know!

@greptile-apps

greptile-apps Bot commented May 9, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds Azure AD (Entra ID) token-based authentication for Redis, bringing parity with the existing GCP IAM auth flow. Users can set azure_redis_ad_token: true in their config along with azure_client_id/azure_tenant_id/azure_client_secret (or rely on DefaultAzureCredential), and LiteLLM will handle token acquisition and silent refresh via the Azure Identity SDK.

  • A long-lived credential object is built once in create_azure_ad_redis_connect_func and captured in a closure, so the Azure SDK's internal token cache handles silent refresh for the sync path without a static token.
  • All three async paths (cluster, standard async client, and BlockingConnectionPool) correctly convert the credential into an AzureADCredentialProvider, ensuring per-connection token refresh rather than a single token baked in at pool creation time.
  • AZURE_REDIS_SCOPE ("https://redis.azure.com/.default") is defined independently in both _redis.py and _redis_credential_provider.py; consolidating to a single definition would prevent future drift.

Confidence Score: 5/5

Safe to merge; the new auth paths are additive and only activate when the Azure AD flag is explicitly set, leaving all existing Redis configurations untouched.

The change is purely additive — Azure AD auth is gated behind an opt-in flag and does not alter any existing code paths. All three async paths correctly delegate to AzureADCredentialProvider so tokens refresh transparently. Tests mock the Azure Identity SDK and cover DefaultAzureCredential, ClientSecretCredential, and import-error paths without real network calls.

No files require special attention.

Important Files Changed

Filename Overview
litellm/_redis.py Adds Azure AD token-based Redis authentication: _build_azure_credential, create_azure_ad_redis_connect_func, and integration in _get_redis_client_logic, get_redis_async_client, and get_redis_connection_pool. All async paths correctly delegate to AzureADCredentialProvider so the Azure SDK handles silent refresh. Minor duplication of AZURE_REDIS_SCOPE with _redis_credential_provider.py.
litellm/_redis_credential_provider.py Adds AzureADCredentialProvider implementing CredentialProvider for Azure AD token-based Redis auth. Mirrors GCPIAMCredentialProvider pattern; correctly offloads the blocking get_token call to a thread in get_credentials_async.
tests/test_litellm/test_utils.py Adds four unit tests for Azure AD Redis auth. All tests mock azure.identity via patch.dict("sys.modules", ...), making them self-contained and CI-safe without requiring the real azure-identity package. No real network calls.

Reviews (2): Last reviewed commit: "chore(lint): silence PLR0915 on _get_red..." | Re-trigger Greptile

Comment thread litellm/_redis.py
Comment thread tests/test_litellm/test_utils.py Outdated
Comment thread litellm/_redis.py Outdated
Comment thread litellm/_redis.py Outdated
Comment thread litellm/_redis.py Outdated
@veria-ai

veria-ai Bot commented May 9, 2026

Copy link
Copy Markdown
Contributor

Azure AD Redis credential refresh added

This PR adds Azure AD credential support for Redis and routes the async cluster, standard async client, and async connection-pool paths through Redis credential providers so tokens are fetched per connection rather than baked into long-lived clients. I checked the surrounding Redis initialization paths and did not find a security issue in the changed code.


Status: 0 open · 1 resolved
Risk: 2/10

Address review issues on PR #21764 cherry-pick:

- Add AzureADCredentialProvider that wraps the live azure-identity
  credential, so async cluster, async standard, and connection-pool
  paths fetch tokens via the SDK's internal cache + silent refresh on
  every connection — instead of baking a single point-in-time token as
  the password (which would expire ~1h after pool creation and break
  all subsequent reconnects).
- Stop attaching raw client_id / tenant_id / client_secret to the
  redis_connect_func object. The credential closure already holds them;
  exposing them as function attributes risked leaks via inspection or
  logging. Async paths now read the already-built credential object via
  `_azure_credential` instead.
- Connection-pool path now picks up REDIS_USERNAME for ACL-configured
  Azure Redis instances, matching the cluster + async paths.
- Mock azure.identity via sys.modules in test_redis_client_logic_
  azure_ad_auth so the test no longer requires azure-identity to be
  installed in the CI environment.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The function is structured around a long sequence of optional
configuration probes (sentinel/cluster/GCP/Azure) and breaking it up
just to satisfy the statement count would split related logic.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@shivamrawat1

Copy link
Copy Markdown
Collaborator Author

@greptileai review again

@oss-pr-review-agent-shin
oss-pr-review-agent-shin Bot changed the base branch from litellm_internal_staging to shin_agent_oss_staging_05_09_2026 May 9, 2026 22:34
@oss-pr-review-agent-shin
oss-pr-review-agent-shin Bot merged commit c7739c9 into shin_agent_oss_staging_05_09_2026 May 9, 2026
115 checks passed
@oss-pr-review-agent-shin

Copy link
Copy Markdown
Contributor

🤖 litellm-agent: Squash-merged into staging branch shin_agent_oss_staging_05_09_2026. Staging PR: #27549


Triage Summary
Adds Azure AD (Entra ID) passwordless authentication for LiteLLM's Redis cache. Introduces AzureADCredentialProvider in litellm/_redis_credential_provider.py implementing redis.credentials.CredentialProvider so tokens are fetched per-connection via the Azure Identity SDK rather than baked into long-lived pools. Adds _build_azure_credential and create_azure_ad_redis_connect_func in litellm/redis.py, wires them into all three async paths (cluster, standard, BlockingConnectionPool), and strips azure* kwargs before they reach redis-py constructors. Supports DefaultAzureCredential, ManagedIden…

Merge Confidence: 5/5 ✅ READY
Ready to ship.

All checks green. Greptile 5/5, no blocking pattern findings, CircleCI passed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants