The Azure Identity library provides credentialsâpublic classes that implement the Azure Core library's TokenCredential protocol. A credential represents a distinct authentication flow for acquiring an access token from Microsoft Entra ID. These credentials can be chained together to form an ordered sequence of authentication mechanisms to be attempted.
How a chained credential worksAt runtime, a credential chain attempts to authenticate using the sequence's first credential. If that credential fails to acquire an access token, the next credential in the sequence is attempted, and so on, until an access token is successfully obtained. The following sequence diagram illustrates this behavior:
Why use credential chains
A chained credential can offer the following benefits:
Environment awareness: Automatically selects the most appropriate credential based on the environment in which the app is running. Without it, you'd have to write code like this:
# Set up credential based on environment (Azure or local development)
if os.getenv("WEBSITE_HOSTNAME"):
credential = ManagedIdentityCredential(client_id=user_assigned_client_id)
else:
credential = AzureCliCredential()
Seamless transitions: Your app can move from local development to your staging or production environment without changing authentication code.
Improved resiliency: Includes a fallback mechanism that moves to the next credential when the prior fails to acquire an access token.
There are two disparate philosophies to credential chaining:
DefaultAzureCredential is an opinionated, preconfigured chain of credentials. It's designed to support many environments, along with the most common authentication flows and developer tools. In graphical form, the underlying chain looks like this:
The order in which DefaultAzureCredential
attempts credentials follows.
DefaultAzureCredential
uses these values to authenticate the app to Azure. This method is most often used in server environments but can also be used when developing locally. Yes 2 Workload Identity If the app is deployed to an Azure host with Workload Identity enabled, authenticate that account. Yes 3 Managed Identity If the app is deployed to an Azure host with Managed Identity enabled, authenticate the app to Azure using that Managed Identity. Yes 4 Shared Token Cache On Windows only, if the developer authenticated to Azure by logging into Visual Studio, authenticate the app to Azure using that same account. Yes 5 Azure CLI If the developer authenticated to Azure using Azure CLI's az login
command, authenticate the app to Azure using that same account. Yes 6 Azure PowerShell If the developer authenticated to Azure using Azure PowerShell's Connect-AzAccount
cmdlet, authenticate the app to Azure using that same account. Yes 7 Azure Developer CLI If the developer authenticated to Azure using Azure Developer CLI's azd auth login
command, authenticate with that account. Yes 8 Interactive browser If enabled, interactively authenticate the developer via the current system's default browser. No
In its simplest form, you can use the parameterless version of DefaultAzureCredential
as follows:
from azure.identity import DefaultAzureCredential
from azure.storage.blob import BlobServiceClient
# Acquire a credential object
credential = DefaultAzureCredential()
blob_service_client = BlobServiceClient(
account_url="https://<my_account_name>.blob.core.windows.net",
credential=credential
)
How to customize DefaultAzureCredential
The following sections describe strategies for omitting credentials from the chain.
Exclude an individual credentialTo exclude an individual credential from DefaultAzureCredential
, use the corresponding exclude
-prefixed keyword parameter. For example:
credential = DefaultAzureCredential(
exclude_environment_credential=True,
exclude_workload_identity_credential=True,
managed_identity_client_id=user_assigned_client_id
)
In the preceding code sample, EnvironmentCredential
and WorkloadIdentityCredential
are removed from the credential chain. As a result, the first credential to be attempted is ManagedIdentityCredential
. The modified chain looks like this:
Note
InteractiveBrowserCredential
is excluded by default and therefore isn't shown in the preceding diagram. To include InteractiveBrowserCredential
, set the exclude_interactive_browser_credential
keyword parameter to False
when you call the DefaultAzureCredential
constructor.
As more exclude
-prefixed keyword parameters are set to True
(credential exclusions are configured), the advantages of using DefaultAzureCredential
diminish. In such cases, ChainedTokenCredential
is a better choice and requires less code. To illustrate, these two code samples behave the same way:
credential = DefaultAzureCredential(
exclude_environment_credential=True,
exclude_workload_identity_credential=True,
exclude_shared_token_cache_credential=True,
exclude_azure_powershell_credential=True,
exclude_azure_developer_cli_credential=True,
managed_identity_client_id=user_assigned_client_id
)
credential = ChainedTokenCredential(
ManagedIdentityCredential(client_id=user_assigned_client_id),
AzureCliCredential()
)
Exclude a credential type category
To exclude all Developer tool
or Deployed service
credentials, set environment variable AZURE_TOKEN_CREDENTIALS
to prod
or dev
, respectively. When a value of prod
is used, the underlying credential chain looks as follows:
When a value of dev
is used, the chain looks as follows:
Important
The AZURE_TOKEN_CREDENTIALS
environment variable is supported in azure-identity
package versions 1.23.0 and later.
ChainedTokenCredential is an empty chain to which you add credentials to suit your app's needs. For example:
credential = ChainedTokenCredential(
AzureCliCredential(),
AzureDeveloperCliCredential()
)
The preceding code sample creates a tailored credential chain comprised of two development-time credentials. AzureCliCredential
is attempted first, followed by AzureDeveloperCliCredential
, if necessary. In graphical form, the chain looks like this:
Tip
For improved performance, optimize credential ordering in ChainedTokenCredential
from most to least used credential.
DefaultAzureCredential
is undoubtedly the easiest way to get started with the Azure Identity library, but with that convenience comes tradeoffs. Once you deploy your app to Azure, you should understand the app's authentication requirements. For that reason, replace DefaultAzureCredential
with a specific TokenCredential
implementation, such as ManagedIdentityCredential
.
Here's why:
ManagedIdentityCredential
always fails in the local development environment, unless explicitly disabled via its corresponding exclude
-prefixed property.DefaultAzureCredential
checks for the presence of certain environment variables. It's possible that someone could add or modify these environment variables at the system level on the host machine. Those changes apply globally and therefore alter the behavior of DefaultAzureCredential
at runtime in any app running on that machine.To diagnose an unexpected issue or to understand what a chained credential is doing, enable logging in your app. Optionally, filter the logs to only those events emitted from the Azure Identity client library. For example:
import logging
from azure.identity import DefaultAzureCredential
# Set the logging level for the Azure Identity library
logger = logging.getLogger("azure.identity")
logger.setLevel(logging.DEBUG)
# Direct logging output to stdout. Without adding a handler,
# no logging output is visible.
handler = logging.StreamHandler(stream=sys.stdout)
logger.addHandler(handler)
# Optional: Output logging levels to the console.
print(
f"Logger enabled for ERROR={logger.isEnabledFor(logging.ERROR)}, "
f"WARNING={logger.isEnabledFor(logging.WARNING)}, "
f"INFO={logger.isEnabledFor(logging.INFO)}, "
f"DEBUG={logger.isEnabledFor(logging.DEBUG)}"
)
For illustration purposes, assume the parameterless form of DefaultAzureCredential
is used to authenticate a request to a blob storage account. The app runs in the local development environment, and the developer authenticated to Azure using the Azure CLI. Assume also that the logging level is set to logging.DEBUG
. When the app is run, the following pertinent entries appear in the output:
Logger enabled for ERROR=True, WARNING=True, INFO=True, DEBUG=True
No environment configuration found.
ManagedIdentityCredential will use IMDS
EnvironmentCredential.get_token failed: EnvironmentCredential authentication unavailable. Environment variables are not fully configured.
Visit https://aka.ms/azsdk/python/identity/environmentcredential/troubleshoot to troubleshoot this issue.
ManagedIdentityCredential.get_token failed: ManagedIdentityCredential authentication unavailable, no response from the IMDS endpoint.
SharedTokenCacheCredential.get_token failed: SharedTokenCacheCredential authentication unavailable. No accounts were found in the cache.
AzureCliCredential.get_token succeeded
[Authenticated account] Client ID: 00001111-aaaa-2222-bbbb-3333cccc4444. Tenant ID: aaaabbbb-0000-cccc-1111-dddd2222eeee. User Principal Name: unavailableUpn. Object ID (user): aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb
DefaultAzureCredential acquired a token from AzureCliCredential
In the preceding output, notice that:
EnvironmentCredential
, ManagedIdentityCredential
, and SharedTokenCacheCredential
each failed to acquire a Microsoft Entra access token, in that order.AzureCliCredential.get_token
call succeeds and the output also indicates that DefaultAzureCredential
acquired a token from AzureCliCredential
. Since AzureCliCredential
succeeded, no credentials beyond it were tried.Note
In the preceding example, the logging level is set to logging.DEBUG
. Be careful when using this logging level, as it can output sensitive information. For example, in this case, the client ID, tenant ID, and the object ID of the developer's user principal in Azure. All traceback information has been removed from the output for clarity.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4