Blog Post

Educator Developer Blog
3 MIN READ

How to use DefaultAzureCredential across multiple tenants

Pamela_Fox's avatar
Pamela_Fox
Icon for Microsoft rankMicrosoft
May 01, 2025

If you are using the DefaultAzureCredential class from the Azure Identity SDK while your user account is associated with multiple tenants, you may find yourself frequently running into API authentication errors (such as HTTP 401/Unauthorized). This post is for you!

These are your two options for successful authentication from a non-default tenant:

  1. Setup your environment precisely to force DefaultAzureCredential to use the desired tenant
  2. Use a specific credential class and explicitly pass in the desired tenant ID

Option 1: Get DefaultAzureCredential working

The DefaultAzureCredential class is a credential chain, which means that it tries a sequence of credential classes until it finds one that can authenticate successfully. The current sequence is:

  • EnvironmentCredential
  • WorkloadIdentityCredential
  • ManagedIdentityCredential
  • SharedTokenCacheCredential
  • AzureCliCredential
  • AzurePowerShellCredential
  • AzureDeveloperCliCredential
  • InteractiveBrowserCredential

For example, on my personal machine, only two of those credentials can retrieve tokens:

  1. AzureCliCredential: from logging in with Azure CLI (az login)
  2. AzureDeveloperCliCredential: from logging in with Azure Developer CLI (azd auth login)

Many developers are logged in with those two credentials, so it's crucial to understand how this chained credential works. The AzureCliCredential is earlier in the chain, so if you are logged in with that, you must have the desired tenant set as the "active tenant". According to Azure CLI documentation, there are two ways to set the active tenant:

  1. az account set --subscription SUBSCRIPTION-ID where the subscription is from the desired tenant
  2. az login --tenant TENANT-ID, with no subsequent az login commands after

Whatever option you choose, you can confirm that your desired tenant is currently the default by running az account show and verifying the tenantId in the account details shown.

If you are only logged in with the azd CLI and not the Azure CLI, you have a problem: the azd cli does not currently have a way to set the active tenant. If that credential is called with no additional information, azd assumes your home tenant, which may not be desired. The azd credential does check for a system variable called AZURE_TENANT_ID, however, so you can try setting that in your environment before running code that uses DefaultAzureCredential. That should work as long as the DefaultAzureCredential code is truly running in the same environment where AZURE_TENANT_ID has been set.

Option 2: Use specific credentials

For this second option, we will abandon DefaultAzureCredential entirely, and replace it with specific credential classes. This approach requires a code change, but once you've gone through the effort to set it up, it's generally a more predictable experience.

Use CLI credential for local dev

Several of the credential classes allow you to explicitly pass in a tenant ID, including both the AzureCliCredential and AzureDeveloperCliCredential. If you know that you’re always going to be logging in with a specific CLI, you can change your code to that credential:

For example, in the Python SDK:

AzureDeveloperCliCredential(tenant_id=os.environ["AZURE_TENANT_ID"])

For more flexibility, you can use conditionals to only pass in a tenant ID if one is set in the environment:

if AZURE_TENANT_ID := os.environ("AZURE_TENANT_ID"): 
  cred = AzureDeveloperCliCredential(tenant_id=AZURE_TENANT_ID) 
else: 
  cred = AzureDeveloperCliCredential() 

💁🏼‍♀️ Tip: As a best practice, I always like to add logging statements that note exactly what credential I'm calling and whether I'm passing in a tenant ID, to help me spot misconfigurations from the logs.

Use managed identity credential in production

You must be careful when replacing DefaultAzureCredential if our code will also be deployed to a production host. In that case, your code was previously relying on DefaultAzureCredential using the ManagedIdentityCredential in the chain, and you now need to call that credential class directly. You will also need to pass in the managed identity client ID, if your host is using user-assigned identity instead of system-assigned identity.

For example, using managed identity in the Python SDK with user-assigned identity:

ManagedIdentityCredential(client_id=os.environ["AZURE_CLIENT_ID"])

Here’s a full credential setup for an app that works locally with azd and works in production with managed identity (either system or user-assigned):

if RUNNING_ON_AZURE: 
  if AZURE_CLIENT_ID := os.getenv("AZURE_CLIENT_ID"): 
    cred = ManagedIdentityCredential(client_id=AZURE_CLIENT_ID) 
  else: 
    cred = ManagedIdentityCredential() 
elif AZURE_TENANT_ID := os.getenv("AZURE_TENANT_ID"): 
  cred = AzureDeveloperCliCredential(tenant_id=AZURE_TENANT_ID) 
else: 
  cred = AzureDeveloperCliCredential() 

For a full walkthrough of an end-to-end template that uses keyless auth in multiple languages, check out my colleague's tutorials on using keyless auth in AI apps.

Updated Apr 29, 2025
Version 1.0
No CommentsBe the first to comment