Skip to content

Comments

feat: add ability to auth to azure with token#21764

Open
Harshit28j wants to merge 1 commit intoBerriAI:mainfrom
Harshit28j:litellm_feat_azure_auth_handle
Open

feat: add ability to auth to azure with token#21764
Harshit28j wants to merge 1 commit intoBerriAI:mainfrom
Harshit28j:litellm_feat_azure_auth_handle

Conversation

@Harshit28j
Copy link
Collaborator

@Harshit28j Harshit28j commented Feb 21, 2026

Relevant issues

Pre-Submission checklist

Please complete all items before asking a LiteLLM maintainer to review your PR

  • I have Added testing in the tests/litellm/ directory, Adding at least 1 test is a hard requirement - see details
  • My PR passes all unit tests on make test-unit
  • My PR's scope is as isolated as possible, it only solves 1 specific problem
  • I have requested a Greptile review by commenting @greptileai and received a Confidence Score of at least 4/5 before requesting a maintainer review

CI (LiteLLM team)

CI status guideline:

  • 50-55 passing tests: main is stable with minor issues.
  • 45-49 passing tests: acceptable but needs attention
  • <= 40 passing tests: unstable; be careful with your merges and assess the risk.
  • Branch creation CI run
    Link:

  • CI run for the last commit
    Link:

  • Merge / cherry-pick CI run
    Links:

Type

🆕 New Feature
📖 Documentation
✅ Test

Changes

image
  • Core Proxy Cache Update: Brought parity to Azure Managed Redis caches with existing GCP IAM auth. Allows LiteLLM to auto-authenticate with Azure AD (Entra ID) via temporary, rotating token injection without relying on static connection passwords.
  • Auto-Refresh Handlers: Created create_azure_ad_redis_connect_func hook which utilizes the azure-identity library to extract fresh OAuth access tokens mapped specifically for https://redis.azure.com/.default scopes.
  • Coverage: Implemented robust mocking validation inside tests/test_litellm/test_utils.py to ensure credentials parsing and fallback pathways correctly build their injection handlers against real Client IDs, Secrets, and system-assigned behaviors.
  • End-to-end Validated: Verified E2E with mock Azure Identity token generation communicating directly to a mock standalone redis Docker image.
  • Documentation: New dedicated doc section added covering proper .yaml configuration usage (azure_redis_ad_token: true) mapped over azure_client_id specifications.

E2E Verification Details

  • Redis Isolation: Started a password-protected Docker Redis to force a strict authentication requirement.
  • SDK Mocking: Intercepted the azure-identity library to return our local Redis password as a fake AD token.
  • Handshake Validation: Verified LiteLLM correctly requested the token and successfully executed the AUTH <token> command.
  • Connectivity Proof: Confirmed successful cache reads/writes by achieving a ~1.8ms response time and observing the x-litellm-cache-key header.

@vercel
Copy link

vercel bot commented Feb 21, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
litellm Ready Ready Preview, Comment Feb 21, 2026 3:16pm

Request Review

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 21, 2026

Greptile Summary

This PR adds Azure AD (Entra ID) passwordless authentication support for Azure Managed Redis caches, following the same pattern as the existing GCP IAM authentication. It introduces token generation via azure-identity, a custom redis_connect_func for automatic token refresh on reconnect, and support for both standalone and async cluster Redis clients.

  • Core implementation in litellm/_redis.py: _generate_azure_ad_redis_token supports Service Principal, Managed Identity, and DefaultAzureCredential flows; create_azure_ad_redis_connect_func handles per-connection token refresh; _get_redis_client_logic and get_redis_async_client are updated to wire Azure AD auth through
  • Tests: Four new tests covering default credential, service principal, import error, and end-to-end _get_redis_client_logic integration. However, the mocking approach (patch("azure.identity.X")) differs from the GCP IAM tests (patch.dict("sys.modules")) and will fail in CI environments where azure-identity is not installed
  • Documentation: New page at docs/my-website/docs/caching/azure_redis_passwordless.md with clear configuration examples for System-Assigned Managed Identity, User-Assigned Managed Identity, and Service Principal
  • Formatting: ~90% of the test file diff is auto-formatter changes (Black) unrelated to the feature — consider separating formatting changes from feature work in future PRs

Confidence Score: 3/5

  • Core implementation is sound and follows existing patterns, but test mocking issues may cause CI failures.
  • The Redis auth implementation in _redis.py is well-structured and mirrors the existing GCP IAM pattern. However, the tests use a mocking strategy (patching azure.identity attributes directly) that differs from the GCP tests (patching sys.modules) and will fail if azure-identity is not installed in the CI environment. The massive formatting changes in the test file also make the actual feature changes harder to review.
  • Pay close attention to tests/test_litellm/test_utils.py — the Azure AD test mocking approach will likely fail in CI environments without azure-identity installed.

Important Files Changed

Filename Overview
litellm/_redis.py Adds Azure AD token generation, connect function, and integration into _get_redis_client_logic and get_redis_async_client for both standalone and cluster modes. Follows existing GCP IAM patterns well. Minor concern: no mutual exclusion between GCP IAM and Azure AD auth.
tests/test_litellm/test_utils.py Adds Azure AD Redis tests. Mocking approach uses patch() on azure.identity module directly, which will fail in CI if azure-identity is not installed — unlike the GCP IAM tests that use patch.dict("sys.modules") for robustness. Also contains extensive formatting-only changes (90%+ of the diff).
docs/my-website/docs/caching/azure_redis_passwordless.md New documentation page covering Azure Managed Redis passwordless authentication with Managed Identity, User-Assigned Identity, and Service Principal options. Clear and well-structured.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[_get_redis_client_logic] --> B{GCP IAM configured?}
    B -->|Yes| C[create_gcp_iam_redis_connect_func]
    B -->|No| D{Azure AD configured?}
    C --> D
    D -->|Yes| E[create_azure_ad_redis_connect_func]
    D -->|No| F[Continue with standard auth]
    E --> F
    F --> G{Connection type?}
    G -->|URL| H[Redis.from_url]
    G -->|Cluster| I{Sync or Async?}
    G -->|Sentinel| J[Redis Sentinel]
    G -->|Standard| K[Redis client]
    I -->|Sync| L[init_redis_cluster - passes redis_connect_func]
    I -->|Async| M[get_redis_async_client]
    M --> N{Has azure_redis_ad_token attr?}
    N -->|Yes| O[_generate_azure_ad_redis_token]
    O --> P[Set password + username on cluster]
    N -->|No| Q{Has GCP service account?}
    Q -->|Yes| R[_generate_gcp_iam_access_token]
    R --> S[Set password on cluster]
    Q -->|No| T[No IAM auth for cluster]
Loading

Last reviewed commit: 810ee68

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3 files reviewed, 3 comments

Edit Code Review Agent Settings | Greptile

mock_credential = Mock()
mock_credential.get_token.return_value = mock_token

with patch("azure.identity.DefaultAzureCredential", return_value=mock_credential):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test will fail if azure-identity is not installed

The mock patch("azure.identity.DefaultAzureCredential", ...) requires the azure.identity module to be importable. If azure-identity is not installed in the CI environment, this patch will raise a ModuleNotFoundError before the test even runs.

Compare with the GCP IAM test (test_generate_gcp_iam_access_token) which uses patch.dict("sys.modules", {...}) to mock the entire module — that approach works regardless of whether the actual package is installed. The Azure tests should follow the same pattern for CI reliability.

For example:

mock_azure_identity = Mock()
mock_credential = Mock()
mock_credential.get_token.return_value = mock_token
mock_azure_identity.DefaultAzureCredential = Mock(return_value=mock_credential)

with patch.dict("sys.modules", {"azure.identity": mock_azure_identity}):
    from litellm._redis import _generate_azure_ad_redis_token
    result = _generate_azure_ad_redis_token()

Context Used: Rule from dashboard - What: prevent any tests from being added here that make real network calls - only mock tests can be ... (source)

mock_credential = Mock()
mock_credential.get_token.return_value = mock_token

with patch("azure.identity.ClientSecretCredential", return_value=mock_credential) as mock_cls:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same mocking issue for ClientSecretCredential

Same as the DefaultAzureCredential test above — patch("azure.identity.ClientSecretCredential", ...) will fail if azure-identity is not installed. Use patch.dict("sys.modules", ...) instead, as was done in the GCP IAM tests.

Context Used: Rule from dashboard - What: prevent any tests from being added here that make real network calls - only mock tests can be ... (source)

Comment on lines +385 to +388
# Handle Azure AD authentication (after GCP IAM block)
_azure_redis_ad_token = redis_kwargs.get("azure_redis_ad_token") or get_secret("REDIS_AZURE_AD_TOKEN")

if _azure_redis_ad_token is not None and str(_azure_redis_ad_token).lower() == "true":
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Azure AD silently overwrites GCP IAM if both configured

If both gcp_service_account and azure_redis_ad_token: true are set, the Azure block (which runs second) will overwrite the redis_connect_func set by the GCP block without any warning. Consider adding mutual exclusion or at least a warning log to prevent silent misconfiguration.

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.

1 participant