Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-azure-identity for
openSUSE:Factory checked in at 2025-10-08 18:13:26
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-azure-identity (Old)
and /work/SRC/openSUSE:Factory/.python-azure-identity.new.11973 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-azure-identity"
Wed Oct 8 18:13:26 2025 rev:35 rq:1309585 version:1.25.1
Changes:
--------
---
/work/SRC/openSUSE:Factory/python-azure-identity/python-azure-identity.changes
2025-09-14 18:49:23.648132055 +0200
+++
/work/SRC/openSUSE:Factory/.python-azure-identity.new.11973/python-azure-identity.changes
2025-10-08 18:14:18.081849902 +0200
@@ -1,0 +2,8 @@
+Tue Oct 7 09:42:55 UTC 2025 - John Paul Adrian Glaubitz
<[email protected]>
+
+- New upstream release
+ + Version 1.25.1
+ + For detailed information about changes see the
+ CHANGELOG.md file provided with this package
+
+-------------------------------------------------------------------
Old:
----
azure_identity-1.25.0.tar.gz
New:
----
azure_identity-1.25.1.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-azure-identity.spec ++++++
--- /var/tmp/diff_new_pack.VKIu7f/_old 2025-10-08 18:14:18.589871221 +0200
+++ /var/tmp/diff_new_pack.VKIu7f/_new 2025-10-08 18:14:18.589871221 +0200
@@ -18,7 +18,7 @@
%{?sle15_python_module_pythons}
Name: python-azure-identity
-Version: 1.25.0
+Version: 1.25.1
Release: 0
Summary: Azure Identity client library for Python
License: MIT
++++++ azure_identity-1.25.0.tar.gz -> azure_identity-1.25.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/azure_identity-1.25.0/CHANGELOG.md
new/azure_identity-1.25.1/CHANGELOG.md
--- old/azure_identity-1.25.0/CHANGELOG.md 2025-09-12 02:13:14.000000000
+0200
+++ new/azure_identity-1.25.1/CHANGELOG.md 2025-10-06 21:11:24.000000000
+0200
@@ -1,5 +1,12 @@
# Release History
+## 1.25.1 (2025-10-06)
+
+### Other Changes
+
+- When `AZURE_TOKEN_CREDENTIALS` is set to `ManagedIdentityCredential`,
`DefaultAzureCredential` now skips the IMDS endpoint probe request and directly
attempts token acquisition with full retry logic, matching the behavior of
using `ManagedIdentityCredential` standalone.
([#43080](https://github.com/Azure/azure-sdk-for-python/pull/43080))
+- Improved error messages from `ManagedIdentityCredential` to include the full
error response from managed identity endpoints for better troubleshooting.
([#43231](https://github.com/Azure/azure-sdk-for-python/pull/43231))
+
## 1.25.0 (2025-09-11)
### Features Added
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/azure_identity-1.25.0/PKG-INFO
new/azure_identity-1.25.1/PKG-INFO
--- old/azure_identity-1.25.0/PKG-INFO 2025-09-12 02:13:56.980968700 +0200
+++ new/azure_identity-1.25.1/PKG-INFO 2025-10-06 21:12:11.365932000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.4
Name: azure-identity
-Version: 1.25.0
+Version: 1.25.1
Summary: Microsoft Azure Identity Library for Python
Author-email: Microsoft Corporation <[email protected]>
License-Expression: MIT
@@ -27,7 +27,7 @@
# Azure Identity client library for Python
-The Azure Identity library provides [Microsoft Entra
ID](https://learn.microsoft.com/entra/fundamentals/whatis) ([formerly Azure
Active Directory](https://learn.microsoft.com/entra/fundamentals/new-name))
token authentication support across the Azure SDK. It provides a set of
[`TokenCredential`][token_cred_ref]/[`SupportsTokenInfo`][supports_token_info_ref]
implementations, which can be used to construct Azure SDK clients that support
Microsoft Entra token authentication.
+The Azure Identity library provides [Microsoft Entra
ID](https://learn.microsoft.com/entra/fundamentals/whatis) token-based
authentication support across the Azure SDK. It provides a set of
[`TokenCredential`][token_cred_ref]/[`SupportsTokenInfo`][supports_token_info_ref]
implementations, which can be used to construct Azure SDK clients that support
Microsoft Entra token authentication.
[Source
code](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/identity/azure-identity)
| [Package (PyPI)](https://pypi.org/project/azure-identity/)
@@ -437,6 +437,13 @@
# Release History
+## 1.25.1 (2025-10-06)
+
+### Other Changes
+
+- When `AZURE_TOKEN_CREDENTIALS` is set to `ManagedIdentityCredential`,
`DefaultAzureCredential` now skips the IMDS endpoint probe request and directly
attempts token acquisition with full retry logic, matching the behavior of
using `ManagedIdentityCredential` standalone.
([#43080](https://github.com/Azure/azure-sdk-for-python/pull/43080))
+- Improved error messages from `ManagedIdentityCredential` to include the full
error response from managed identity endpoints for better troubleshooting.
([#43231](https://github.com/Azure/azure-sdk-for-python/pull/43231))
+
## 1.25.0 (2025-09-11)
### Features Added
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/azure_identity-1.25.0/README.md
new/azure_identity-1.25.1/README.md
--- old/azure_identity-1.25.0/README.md 2025-09-12 02:13:14.000000000 +0200
+++ new/azure_identity-1.25.1/README.md 2025-10-06 21:11:24.000000000 +0200
@@ -1,6 +1,6 @@
# Azure Identity client library for Python
-The Azure Identity library provides [Microsoft Entra
ID](https://learn.microsoft.com/entra/fundamentals/whatis) ([formerly Azure
Active Directory](https://learn.microsoft.com/entra/fundamentals/new-name))
token authentication support across the Azure SDK. It provides a set of
[`TokenCredential`][token_cred_ref]/[`SupportsTokenInfo`][supports_token_info_ref]
implementations, which can be used to construct Azure SDK clients that support
Microsoft Entra token authentication.
+The Azure Identity library provides [Microsoft Entra
ID](https://learn.microsoft.com/entra/fundamentals/whatis) token-based
authentication support across the Azure SDK. It provides a set of
[`TokenCredential`][token_cred_ref]/[`SupportsTokenInfo`][supports_token_info_ref]
implementations, which can be used to construct Azure SDK clients that support
Microsoft Entra token authentication.
[Source
code](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/identity/azure-identity)
| [Package (PyPI)](https://pypi.org/project/azure-identity/)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/azure_identity-1.25.0/azure/identity/_credentials/default.py
new/azure_identity-1.25.1/azure/identity/_credentials/default.py
--- old/azure_identity-1.25.0/azure/identity/_credentials/default.py
2025-09-12 02:13:14.000000000 +0200
+++ new/azure_identity-1.25.1/azure/identity/_credentials/default.py
2025-10-06 21:11:24.000000000 +0200
@@ -172,7 +172,8 @@
process_timeout = kwargs.pop("process_timeout", 10)
require_envvar = kwargs.pop("require_envvar", False)
- if require_envvar and not
os.environ.get(EnvironmentVariables.AZURE_TOKEN_CREDENTIALS):
+ token_credentials_env =
os.environ.get(EnvironmentVariables.AZURE_TOKEN_CREDENTIALS, "").strip().lower()
+ if require_envvar and not token_credentials_env:
raise ValueError(
"AZURE_TOKEN_CREDENTIALS environment variable is required but
is not set or is empty. "
"Set it to 'dev', 'prod', or a specific credential name."
@@ -274,18 +275,16 @@
ManagedIdentityCredential(
client_id=managed_identity_client_id,
_exclude_workload_identity_credential=exclude_workload_identity_credential,
+ _enable_imds_probe=token_credentials_env !=
"managedidentitycredential",
**kwargs,
)
)
if not exclude_shared_token_cache_credential and
SharedTokenCacheCredential.supported():
- try:
- # username and/or tenant_id are only required when the cache
contains tokens for multiple identities
- shared_cache = SharedTokenCacheCredential(
- username=shared_cache_username,
tenant_id=shared_cache_tenant_id, authority=authority, **kwargs
- )
- credentials.append(shared_cache)
- except Exception as ex: # pylint:disable=broad-except
- _LOGGER.info("Shared token cache is unavailable: '%s'", ex)
+ # username and/or tenant_id are only required when the cache
contains tokens for multiple identities
+ shared_cache = SharedTokenCacheCredential(
+ username=shared_cache_username,
tenant_id=shared_cache_tenant_id, authority=authority, **kwargs
+ )
+ credentials.append(shared_cache)
if not exclude_visual_studio_code_credential:
credentials.append(VisualStudioCodeCredential(tenant_id=vscode_tenant_id))
if not exclude_cli_credential:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/azure_identity-1.25.0/azure/identity/_credentials/imds.py
new/azure_identity-1.25.1/azure/identity/_credentials/imds.py
--- old/azure_identity-1.25.0/azure/identity/_credentials/imds.py
2025-09-12 02:13:14.000000000 +0200
+++ new/azure_identity-1.25.1/azure/identity/_credentials/imds.py
2025-10-06 21:11:24.000000000 +0200
@@ -82,6 +82,10 @@
class ImdsCredential(MsalManagedIdentityClient):
def __init__(self, **kwargs: Any) -> None:
+ # If set to True/False, _enable_imds_probe forces whether or not the
credential
+ # probes for the IMDS endpoint before attempting to get a token. If
None (the default),
+ # the credential probes only if it's part of a ChainedTokenCredential
chain.
+ self._enable_imds_probe = kwargs.pop("_enable_imds_probe", None)
super().__init__(retry_policy_class=ImdsRetryPolicy,
**dict(PIPELINE_SETTINGS, **kwargs))
self._config = kwargs
@@ -102,9 +106,9 @@
def _request_token(self, *scopes: str, **kwargs: Any) -> AccessTokenInfo:
- if within_credential_chain.get() and not self._endpoint_available:
- # If within a chain (e.g. DefaultAzureCredential), we do a quick
check to see if the IMDS endpoint
- # is available to avoid hanging for a long time if the endpoint
isn't available.
+ do_probe = self._enable_imds_probe if self._enable_imds_probe is not
None else within_credential_chain.get()
+ if do_probe and not self._endpoint_available:
+ # Probe to see if the IMDS endpoint is available to avoid hanging
for a long time if it's not.
try:
client = ManagedIdentityClient(_get_request,
**dict(PIPELINE_SETTINGS, **self._config))
client.request_token(*scopes, connection_timeout=1,
retry_total=0)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/azure_identity-1.25.0/azure/identity/_credentials/managed_identity.py
new/azure_identity-1.25.1/azure/identity/_credentials/managed_identity.py
--- old/azure_identity-1.25.0/azure/identity/_credentials/managed_identity.py
2025-09-12 02:13:14.000000000 +0200
+++ new/azure_identity-1.25.1/azure/identity/_credentials/managed_identity.py
2025-10-06 21:11:24.000000000 +0200
@@ -76,6 +76,7 @@
user_identity_info = validate_identity_config(client_id,
identity_config)
self._credential: Optional[SupportsTokenInfo] = None
exclude_workload_identity =
kwargs.pop("_exclude_workload_identity_credential", False)
+ self._enable_imds_probe = kwargs.pop("_enable_imds_probe", None)
managed_identity_type = None
if os.environ.get(EnvironmentVariables.IDENTITY_ENDPOINT):
@@ -136,7 +137,12 @@
managed_identity_type = "IMDS"
from .imds import ImdsCredential
- self._credential = ImdsCredential(client_id=client_id,
identity_config=identity_config, **kwargs)
+ self._credential = ImdsCredential(
+ client_id=client_id,
+ identity_config=identity_config,
+ _enable_imds_probe=self._enable_imds_probe,
+ **kwargs,
+ )
if managed_identity_type:
log_msg = f"{self.__class__.__name__} will use
{managed_identity_type}"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/azure_identity-1.25.0/azure/identity/_credentials/shared_cache.py
new/azure_identity-1.25.1/azure/identity/_credentials/shared_cache.py
--- old/azure_identity-1.25.0/azure/identity/_credentials/shared_cache.py
2025-09-12 02:13:14.000000000 +0200
+++ new/azure_identity-1.25.1/azure/identity/_credentials/shared_cache.py
2025-10-06 21:11:24.000000000 +0200
@@ -198,9 +198,9 @@
return token
except Exception as e: # pylint: disable=broad-except
if within_dac.get():
- raise CredentialUnavailableError( # pylint:
disable=raise-missing-from
+ raise CredentialUnavailableError(
message=getattr(e, "message", str(e)),
response=getattr(e, "response", None)
- )
+ ) from e
raise
raise
CredentialUnavailableError(message=NO_TOKEN.format(account.get("username")))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/azure_identity-1.25.0/azure/identity/_internal/interactive.py
new/azure_identity-1.25.1/azure/identity/_internal/interactive.py
--- old/azure_identity-1.25.0/azure/identity/_internal/interactive.py
2025-09-12 02:13:14.000000000 +0200
+++ new/azure_identity-1.25.1/azure/identity/_internal/interactive.py
2025-10-06 21:11:24.000000000 +0200
@@ -203,7 +203,7 @@
return token
except Exception as ex: # pylint:disable=broad-except
if not (isinstance(ex, AuthenticationRequiredError) and
allow_prompt):
- _LOGGER.warning(
+ _LOGGER.warning( # pylint: disable=do-not-log-raised-errors
"%s.%s failed: %s",
self.__class__.__name__,
base_method_name,
@@ -225,7 +225,7 @@
# this may be the first authentication, or the user may have
authenticated a different identity
self._auth_record = _build_auth_record(result)
except Exception as ex:
- _LOGGER.warning(
+ _LOGGER.warning( # pylint: disable=do-not-log-raised-errors
"%s.%s failed: %s",
self.__class__.__name__,
base_method_name,
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/azure_identity-1.25.0/azure/identity/_internal/msal_managed_identity_client.py
new/azure_identity-1.25.1/azure/identity/_internal/msal_managed_identity_client.py
---
old/azure_identity-1.25.0/azure/identity/_internal/msal_managed_identity_client.py
2025-09-12 02:13:14.000000000 +0200
+++
new/azure_identity-1.25.1/azure/identity/_internal/msal_managed_identity_client.py
2025-10-06 21:11:24.000000000 +0200
@@ -61,7 +61,7 @@
)
error_desc = ""
if result and "error" in result:
- error_desc = cast(str, result["error"])
+ error_desc = f"Token request error: ({result['error']})
{result.get('error_description', '')}"
error_message = self.get_unavailable_message(error_desc)
raise CredentialUnavailableError(error_message)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/azure_identity-1.25.0/azure/identity/_version.py
new/azure_identity-1.25.1/azure/identity/_version.py
--- old/azure_identity-1.25.0/azure/identity/_version.py 2025-09-12
02:13:14.000000000 +0200
+++ new/azure_identity-1.25.1/azure/identity/_version.py 2025-10-06
21:11:24.000000000 +0200
@@ -2,4 +2,4 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
# ------------------------------------
-VERSION = "1.25.0"
+VERSION = "1.25.1"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/azure_identity-1.25.0/azure/identity/aio/_credentials/default.py
new/azure_identity-1.25.1/azure/identity/aio/_credentials/default.py
--- old/azure_identity-1.25.0/azure/identity/aio/_credentials/default.py
2025-09-12 02:13:14.000000000 +0200
+++ new/azure_identity-1.25.1/azure/identity/aio/_credentials/default.py
2025-10-06 21:11:24.000000000 +0200
@@ -144,7 +144,8 @@
process_timeout = kwargs.pop("process_timeout", 10)
require_envvar = kwargs.pop("require_envvar", False)
- if require_envvar and not
os.environ.get(EnvironmentVariables.AZURE_TOKEN_CREDENTIALS):
+ token_credentials_env =
os.environ.get(EnvironmentVariables.AZURE_TOKEN_CREDENTIALS, "").strip().lower()
+ if require_envvar and not token_credentials_env:
raise ValueError(
"AZURE_TOKEN_CREDENTIALS environment variable is required but
is not set or is empty. "
"Set it to 'dev', 'prod', or a specific credential name."
@@ -235,18 +236,16 @@
ManagedIdentityCredential(
client_id=managed_identity_client_id,
_exclude_workload_identity_credential=exclude_workload_identity_credential,
+ _enable_imds_probe=token_credentials_env !=
"managedidentitycredential",
**kwargs,
)
)
if not exclude_shared_token_cache_credential and
SharedTokenCacheCredential.supported():
- try:
- # username and/or tenant_id are only required when the cache
contains tokens for multiple identities
- shared_cache = SharedTokenCacheCredential(
- username=shared_cache_username,
tenant_id=shared_cache_tenant_id, authority=authority, **kwargs
- )
- credentials.append(shared_cache)
- except Exception as ex: # pylint:disable=broad-except
- _LOGGER.info("Shared token cache is unavailable: '%s'", ex)
+ # username and/or tenant_id are only required when the cache
contains tokens for multiple identities
+ shared_cache = SharedTokenCacheCredential(
+ username=shared_cache_username,
tenant_id=shared_cache_tenant_id, authority=authority, **kwargs
+ )
+ credentials.append(shared_cache)
if not exclude_visual_studio_code_credential:
credentials.append(VisualStudioCodeCredential(tenant_id=vscode_tenant_id))
if not exclude_cli_credential:
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/azure_identity-1.25.0/azure/identity/aio/_credentials/imds.py
new/azure_identity-1.25.1/azure/identity/aio/_credentials/imds.py
--- old/azure_identity-1.25.0/azure/identity/aio/_credentials/imds.py
2025-09-12 02:13:14.000000000 +0200
+++ new/azure_identity-1.25.1/azure/identity/aio/_credentials/imds.py
2025-10-06 21:11:24.000000000 +0200
@@ -45,6 +45,10 @@
def __init__(self, **kwargs: Any) -> None:
super().__init__()
+ # If set to True/False, _enable_imds_probe forces whether or not the
credential
+ # probes for the IMDS endpoint before attempting to get a token. If
None (the default),
+ # the credential probes only if it's part of a ChainedTokenCredential
chain.
+ self._enable_imds_probe = kwargs.pop("_enable_imds_probe", None)
kwargs["retry_policy_class"] = AsyncImdsRetryPolicy
self._client = AsyncManagedIdentityClient(_get_request,
**dict(PIPELINE_SETTINGS, **kwargs))
if EnvironmentVariables.AZURE_POD_IDENTITY_AUTHORITY_HOST in
os.environ:
@@ -65,9 +69,9 @@
async def _request_token(self, *scopes: str, **kwargs: Any) ->
AccessTokenInfo:
- if within_credential_chain.get() and not self._endpoint_available:
- # If within a chain (e.g. DefaultAzureCredential), we do a quick
check to see if the IMDS endpoint
- # is available to avoid hanging for a long time if the endpoint
isn't available.
+ do_probe = self._enable_imds_probe if self._enable_imds_probe is not
None else within_credential_chain.get()
+ if do_probe and not self._endpoint_available:
+ # Probe to see if the IMDS endpoint is available to avoid hanging
for a long time if it's not.
try:
await self._client.request_token(*scopes,
connection_timeout=1, retry_total=0)
self._endpoint_available = True
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/azure_identity-1.25.0/azure/identity/aio/_credentials/managed_identity.py
new/azure_identity-1.25.1/azure/identity/aio/_credentials/managed_identity.py
---
old/azure_identity-1.25.0/azure/identity/aio/_credentials/managed_identity.py
2025-09-12 02:13:14.000000000 +0200
+++
new/azure_identity-1.25.1/azure/identity/aio/_credentials/managed_identity.py
2025-10-06 21:11:24.000000000 +0200
@@ -49,6 +49,7 @@
user_identity_info = validate_identity_config(client_id,
identity_config)
self._credential: Optional[AsyncSupportsTokenInfo] = None
exclude_workload_identity =
kwargs.pop("_exclude_workload_identity_credential", False)
+ self._enable_imds_probe = kwargs.pop("_enable_imds_probe", None)
managed_identity_type = None
if os.environ.get(EnvironmentVariables.IDENTITY_ENDPOINT):
if os.environ.get(EnvironmentVariables.IDENTITY_HEADER):
@@ -108,7 +109,12 @@
managed_identity_type = "IMDS"
from .imds import ImdsCredential
- self._credential = ImdsCredential(client_id=client_id,
identity_config=identity_config, **kwargs)
+ self._credential = ImdsCredential(
+ client_id=client_id,
+ identity_config=identity_config,
+ _enable_imds_probe=self._enable_imds_probe,
+ **kwargs,
+ )
if managed_identity_type:
log_msg = f"{self.__class__.__name__} will use
{managed_identity_type}"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/azure_identity-1.25.0/azure/identity/aio/_credentials/shared_cache.py
new/azure_identity-1.25.1/azure/identity/aio/_credentials/shared_cache.py
--- old/azure_identity-1.25.0/azure/identity/aio/_credentials/shared_cache.py
2025-09-12 02:13:14.000000000 +0200
+++ new/azure_identity-1.25.1/azure/identity/aio/_credentials/shared_cache.py
2025-10-06 21:11:24.000000000 +0200
@@ -151,9 +151,9 @@
return token
except Exception as e: # pylint: disable=broad-except
if within_dac.get():
- raise CredentialUnavailableError( # pylint:
disable=raise-missing-from
+ raise CredentialUnavailableError(
message=getattr(e, "message", str(e)),
response=getattr(e, "response", None)
- )
+ ) from e
raise
raise
CredentialUnavailableError(message=NO_TOKEN.format(account.get("username")))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/azure_identity-1.25.0/azure_identity.egg-info/PKG-INFO
new/azure_identity-1.25.1/azure_identity.egg-info/PKG-INFO
--- old/azure_identity-1.25.0/azure_identity.egg-info/PKG-INFO 2025-09-12
02:13:56.000000000 +0200
+++ new/azure_identity-1.25.1/azure_identity.egg-info/PKG-INFO 2025-10-06
21:12:11.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.4
Name: azure-identity
-Version: 1.25.0
+Version: 1.25.1
Summary: Microsoft Azure Identity Library for Python
Author-email: Microsoft Corporation <[email protected]>
License-Expression: MIT
@@ -27,7 +27,7 @@
# Azure Identity client library for Python
-The Azure Identity library provides [Microsoft Entra
ID](https://learn.microsoft.com/entra/fundamentals/whatis) ([formerly Azure
Active Directory](https://learn.microsoft.com/entra/fundamentals/new-name))
token authentication support across the Azure SDK. It provides a set of
[`TokenCredential`][token_cred_ref]/[`SupportsTokenInfo`][supports_token_info_ref]
implementations, which can be used to construct Azure SDK clients that support
Microsoft Entra token authentication.
+The Azure Identity library provides [Microsoft Entra
ID](https://learn.microsoft.com/entra/fundamentals/whatis) token-based
authentication support across the Azure SDK. It provides a set of
[`TokenCredential`][token_cred_ref]/[`SupportsTokenInfo`][supports_token_info_ref]
implementations, which can be used to construct Azure SDK clients that support
Microsoft Entra token authentication.
[Source
code](https://github.com/Azure/azure-sdk-for-python/blob/main/sdk/identity/azure-identity)
| [Package (PyPI)](https://pypi.org/project/azure-identity/)
@@ -437,6 +437,13 @@
# Release History
+## 1.25.1 (2025-10-06)
+
+### Other Changes
+
+- When `AZURE_TOKEN_CREDENTIALS` is set to `ManagedIdentityCredential`,
`DefaultAzureCredential` now skips the IMDS endpoint probe request and directly
attempts token acquisition with full retry logic, matching the behavior of
using `ManagedIdentityCredential` standalone.
([#43080](https://github.com/Azure/azure-sdk-for-python/pull/43080))
+- Improved error messages from `ManagedIdentityCredential` to include the full
error response from managed identity endpoints for better troubleshooting.
([#43231](https://github.com/Azure/azure-sdk-for-python/pull/43231))
+
## 1.25.0 (2025-09-11)
### Features Added
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/azure_identity-1.25.0/tests/test_default.py
new/azure_identity-1.25.1/tests/test_default.py
--- old/azure_identity-1.25.0/tests/test_default.py 2025-09-12
02:13:14.000000000 +0200
+++ new/azure_identity-1.25.1/tests/test_default.py 2025-10-06
21:11:24.000000000 +0200
@@ -313,7 +313,11 @@
def test_managed_identity_client_id():
"""the credential should accept a user-assigned managed identity's client
ID by kwarg or environment variable"""
- expected_args = {"client_id": "the-client",
"_exclude_workload_identity_credential": False}
+ expected_args = {
+ "client_id": "the-client",
+ "_exclude_workload_identity_credential": False,
+ "_enable_imds_probe": True,
+ }
with patch(DefaultAzureCredential.__module__ +
".ManagedIdentityCredential") as mock_credential:
DefaultAzureCredential(managed_identity_client_id=expected_args["client_id"])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/azure_identity-1.25.0/tests/test_default_async.py
new/azure_identity-1.25.1/tests/test_default_async.py
--- old/azure_identity-1.25.0/tests/test_default_async.py 2025-09-12
02:13:14.000000000 +0200
+++ new/azure_identity-1.25.1/tests/test_default_async.py 2025-10-06
21:11:24.000000000 +0200
@@ -262,7 +262,11 @@
def test_managed_identity_client_id():
"""the credential should accept a user-assigned managed identity's client
ID by kwarg or environment variable"""
- expected_args = {"client_id": "the-client",
"_exclude_workload_identity_credential": False}
+ expected_args = {
+ "client_id": "the-client",
+ "_exclude_workload_identity_credential": False,
+ "_enable_imds_probe": True,
+ }
with patch(DefaultAzureCredential.__module__ +
".ManagedIdentityCredential") as mock_credential:
DefaultAzureCredential(managed_identity_client_id=expected_args["client_id"])
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/azure_identity-1.25.0/tests/test_imds_credential.py
new/azure_identity-1.25.1/tests/test_imds_credential.py
--- old/azure_identity-1.25.0/tests/test_imds_credential.py 2025-09-12
02:13:14.000000000 +0200
+++ new/azure_identity-1.25.1/tests/test_imds_credential.py 2025-10-06
21:11:24.000000000 +0200
@@ -14,7 +14,6 @@
IMDS_AUTHORITY,
PIPELINE_SETTINGS,
)
-from azure.identity._internal.utils import within_credential_chain
from azure.core.pipeline import PipelineResponse
from azure.core.pipeline.policies import RetryPolicy
from azure.core.pipeline.transport import HttpRequest, HttpResponse
@@ -109,7 +108,7 @@
assert isinstance(token.expires_on, int)
@pytest.mark.parametrize("get_token_method", GET_TOKEN_METHODS)
- def test_managed_identity_aci_probe(self, get_token_method):
+ def test_enable_imds_probe(self, get_token_method):
access_token = "****"
expires_on = 42
expected_token = access_token
@@ -140,11 +139,9 @@
),
],
)
- within_credential_chain.set(True)
- credential = ImdsCredential(transport=transport)
+ credential = ImdsCredential(transport=transport,
_enable_imds_probe=True)
token = getattr(credential, get_token_method)(scope)
assert token.token == expected_token
- within_credential_chain.set(False)
def test_imds_credential_uses_custom_retry_policy(self):
credential = ImdsCredential()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/azure_identity-1.25.0/tests/test_imds_credential_async.py
new/azure_identity-1.25.1/tests/test_imds_credential_async.py
--- old/azure_identity-1.25.0/tests/test_imds_credential_async.py
2025-09-12 02:13:14.000000000 +0200
+++ new/azure_identity-1.25.1/tests/test_imds_credential_async.py
2025-10-06 21:11:24.000000000 +0200
@@ -18,7 +18,6 @@
from azure.core.pipeline import PipelineResponse
from azure.core.pipeline.policies import AsyncRetryPolicy
from azure.core.pipeline.transport import HttpRequest, HttpResponse
-from azure.identity._internal.utils import within_credential_chain
import pytest
from helpers import mock_response, Request, GET_TOKEN_METHODS
@@ -316,7 +315,7 @@
@pytest.mark.asyncio
@pytest.mark.parametrize("get_token_method", GET_TOKEN_METHODS)
- async def test_managed_identity_aci_probe(self, get_token_method):
+ async def test_enable_imds_probe(self, get_token_method):
access_token = "****"
expires_on = 42
expected_token = access_token
@@ -346,11 +345,9 @@
),
],
)
- within_credential_chain.set(True)
- credential = ImdsCredential(transport=transport)
+ credential = ImdsCredential(transport=transport,
_enable_imds_probe=True)
token = await getattr(credential, get_token_method)(scope)
assert token.token == expected_token
- within_credential_chain.set(False)
async def test_imds_credential_uses_custom_retry_policy(self):
credential = ImdsCredential()
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/azure_identity-1.25.0/tests/test_managed_identity.py
new/azure_identity-1.25.1/tests/test_managed_identity.py
--- old/azure_identity-1.25.0/tests/test_managed_identity.py 2025-09-12
02:13:14.000000000 +0200
+++ new/azure_identity-1.25.1/tests/test_managed_identity.py 2025-10-06
21:11:24.000000000 +0200
@@ -649,6 +649,82 @@
@pytest.mark.parametrize("get_token_method", GET_TOKEN_METHODS)
+def test_enable_imds_probe(get_token_method):
+ access_token = "****"
+ expires_on = 42
+ expected_token = access_token
+ scope = "scope"
+ transport = validating_transport(
+ requests=[
+ Request(base_url=IMDS_AUTHORITY + IMDS_TOKEN_PATH),
+ Request(
+ base_url=IMDS_AUTHORITY + IMDS_TOKEN_PATH,
+ method="GET",
+ required_headers={"Metadata": "true"},
+ required_params={"resource": scope},
+ ),
+ ],
+ responses=[
+ # probe receives error response
+ mock_response(status_code=400),
+ mock_response(
+ json_payload={
+ "access_token": access_token,
+ "expires_in": 42,
+ "expires_on": expires_on,
+ "ext_expires_in": 42,
+ "not_before": int(time.time()),
+ "resource": scope,
+ "token_type": "Bearer",
+ }
+ ),
+ ],
+ )
+ credential = ManagedIdentityCredential(transport=transport,
_enable_imds_probe=True)
+ token = getattr(credential, get_token_method)(scope)
+ assert token.token == expected_token
+
+
[email protected]("get_token_method", GET_TOKEN_METHODS)
+def test_imds_probe_enabled_in_chain(get_token_method):
+ access_token = "****"
+ expires_on = 42
+ expected_token = access_token
+ scope = "scope"
+ transport = validating_transport(
+ requests=[
+ Request(base_url=IMDS_AUTHORITY + IMDS_TOKEN_PATH),
+ Request(
+ base_url=IMDS_AUTHORITY + IMDS_TOKEN_PATH,
+ method="GET",
+ required_headers={"Metadata": "true"},
+ required_params={"resource": scope},
+ ),
+ ],
+ responses=[
+ # probe receives error response
+ mock_response(status_code=400),
+ mock_response(
+ json_payload={
+ "access_token": access_token,
+ "expires_in": 42,
+ "expires_on": expires_on,
+ "ext_expires_in": 42,
+ "not_before": int(time.time()),
+ "resource": scope,
+ "token_type": "Bearer",
+ }
+ ),
+ ],
+ )
+ credential = ManagedIdentityCredential(transport=transport)
+ within_credential_chain.set(True)
+ token = getattr(credential, get_token_method)(scope)
+ assert token.token == expected_token
+ within_credential_chain.set(False)
+
+
[email protected]("get_token_method", GET_TOKEN_METHODS)
def test_imds_text_response(get_token_method):
within_credential_chain.set(True)
response = mock.Mock(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/azure_identity-1.25.0/tests/test_managed_identity_async.py
new/azure_identity-1.25.1/tests/test_managed_identity_async.py
--- old/azure_identity-1.25.0/tests/test_managed_identity_async.py
2025-09-12 02:13:14.000000000 +0200
+++ new/azure_identity-1.25.1/tests/test_managed_identity_async.py
2025-10-06 21:11:24.000000000 +0200
@@ -751,6 +751,82 @@
@pytest.mark.asyncio
@pytest.mark.parametrize("get_token_method", GET_TOKEN_METHODS)
+async def test_enable_imds_probe(get_token_method):
+ access_token = "****"
+ expires_on = 42
+ expected_token = access_token
+ scope = "scope"
+ transport = async_validating_transport(
+ requests=[
+ Request(base_url=IMDS_AUTHORITY + IMDS_TOKEN_PATH),
+ Request(
+ base_url=IMDS_AUTHORITY + IMDS_TOKEN_PATH,
+ method="GET",
+ required_headers={"Metadata": "true"},
+ required_params={"resource": scope},
+ ),
+ ],
+ responses=[
+ mock_response(status_code=400),
+ mock_response(
+ json_payload={
+ "access_token": access_token,
+ "expires_in": 42,
+ "expires_on": expires_on,
+ "ext_expires_in": 42,
+ "not_before": int(time.time()),
+ "resource": scope,
+ "token_type": "Bearer",
+ }
+ ),
+ ],
+ )
+ credential = ManagedIdentityCredential(transport=transport,
_enable_imds_probe=True)
+ token = await getattr(credential, get_token_method)(scope)
+ assert token.token == expected_token
+
+
[email protected]
[email protected]("get_token_method", GET_TOKEN_METHODS)
+async def test_imds_probe_enabled_in_chain(get_token_method):
+ access_token = "****"
+ expires_on = 42
+ expected_token = access_token
+ scope = "scope"
+ transport = async_validating_transport(
+ requests=[
+ Request(base_url=IMDS_AUTHORITY + IMDS_TOKEN_PATH),
+ Request(
+ base_url=IMDS_AUTHORITY + IMDS_TOKEN_PATH,
+ method="GET",
+ required_headers={"Metadata": "true"},
+ required_params={"resource": scope},
+ ),
+ ],
+ responses=[
+ mock_response(status_code=400),
+ mock_response(
+ json_payload={
+ "access_token": access_token,
+ "expires_in": 42,
+ "expires_on": expires_on,
+ "ext_expires_in": 42,
+ "not_before": int(time.time()),
+ "resource": scope,
+ "token_type": "Bearer",
+ }
+ ),
+ ],
+ )
+ within_credential_chain.set(True)
+ credential = ManagedIdentityCredential(transport=transport)
+ token = await getattr(credential, get_token_method)(scope)
+ assert token.token == expected_token
+ within_credential_chain.set(False)
+
+
[email protected]
[email protected]("get_token_method", GET_TOKEN_METHODS)
async def test_imds_text_response(get_token_method):
async def send(request, **kwargs):
response = mock.Mock(
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/azure_identity-1.25.0/tests/test_token_credentials_env.py
new/azure_identity-1.25.1/tests/test_token_credentials_env.py
--- old/azure_identity-1.25.0/tests/test_token_credentials_env.py
2025-09-12 02:13:14.000000000 +0200
+++ new/azure_identity-1.25.1/tests/test_token_credentials_env.py
2025-10-06 21:11:24.000000000 +0200
@@ -3,6 +3,7 @@
# Licensed under the MIT License.
# ------------------------------------
import os
+import time
from unittest.mock import patch
import pytest
@@ -20,6 +21,8 @@
from azure.identity._credentials.broker import BrokerCredential
from azure.identity._constants import EnvironmentVariables
+from helpers import mock_response, Request, validating_transport,
GET_TOKEN_METHODS
+
def test_token_credentials_env_dev():
"""With AZURE_TOKEN_CREDENTIALS=dev, DefaultAzureCredential should use
only developer credentials"""
@@ -251,3 +254,35 @@
# Other dev credentials should still be present
assert AzurePowerShellCredential in actual_classes
assert AzureDeveloperCliCredential in actual_classes
+
+
[email protected]("get_token_method", GET_TOKEN_METHODS)
+def
test_imds_credential_skips_probe_when_token_credentials_env_set(get_token_method):
+ """Test that ImdsCredential skips the endpoint probe when
AZURE_TOKEN_CREDENTIALS is set to "managedidentitycredential" """
+
+ # Create a transport that would fail the probe but succeed for the actual
token request
+ token_response = mock_response(
+ json_payload={
+ "access_token": "token",
+ "expires_in": 42,
+ "expires_on": int(time.time()) + 42,
+ "ext_expires_in": 42,
+ "not_before": int(time.time()),
+ "resource": "scope",
+ "token_type": "Bearer",
+ }
+ )
+
+ # Use a transport that would normally fail the probe
(connection_timeout=1, retry_total=0)
+ # but should succeed for the actual token request
+ transport = validating_transport(
+ requests=[Request()], responses=[token_response] # Only expect one
request (no probe)
+ )
+
+ with patch.dict(os.environ, {EnvironmentVariables.AZURE_TOKEN_CREDENTIALS:
"managedidentitycredential"}):
+
+ credential = DefaultAzureCredential(transport=transport)
+
+ # This should succeed without calling the probe
+ token = getattr(credential, get_token_method)("scope")
+ assert token.token == "token"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/azure_identity-1.25.0/tests/test_token_credentials_env_async.py
new/azure_identity-1.25.1/tests/test_token_credentials_env_async.py
--- old/azure_identity-1.25.0/tests/test_token_credentials_env_async.py
2025-09-12 02:13:14.000000000 +0200
+++ new/azure_identity-1.25.1/tests/test_token_credentials_env_async.py
2025-10-06 21:11:24.000000000 +0200
@@ -3,6 +3,7 @@
# Licensed under the MIT License.
# ------------------------------------
import os
+import time
from unittest.mock import patch
import pytest
@@ -19,6 +20,9 @@
)
from azure.identity._constants import EnvironmentVariables
+from helpers import mock_response, Request, GET_TOKEN_METHODS
+from helpers_async import async_validating_transport
+
def test_token_credentials_env_dev():
"""With AZURE_TOKEN_CREDENTIALS=dev, DefaultAzureCredential should use
only developer credentials"""
@@ -249,3 +253,36 @@
# Other dev credentials should still be present
assert AzurePowerShellCredential in actual_classes
assert AzureDeveloperCliCredential in actual_classes
+
+
[email protected]
[email protected]("get_token_method", GET_TOKEN_METHODS)
+async def
test_imds_credential_skips_probe_when_token_credentials_env_set_async(get_token_method):
+ """Test that async ImdsCredential skips the endpoint probe when
AZURE_TOKEN_CREDENTIALS is set to "managedidentitycredential" """
+
+ # Create a transport that would fail the probe but succeed for the actual
token request
+ token_response = mock_response(
+ json_payload={
+ "access_token": "token",
+ "expires_in": 42,
+ "expires_on": int(time.time()) + 42,
+ "ext_expires_in": 42,
+ "not_before": int(time.time()),
+ "resource": "scope",
+ "token_type": "Bearer",
+ }
+ )
+
+ # Use a transport that would normally fail the probe
(connection_timeout=1, retry_total=0)
+ # but should succeed for the actual token request
+ transport = async_validating_transport(
+ requests=[Request()], responses=[token_response] # Only expect one
request (no probe)
+ )
+
+ with patch.dict(os.environ, {EnvironmentVariables.AZURE_TOKEN_CREDENTIALS:
"managedidentitycredential"}):
+
+ credential = DefaultAzureCredential(transport=transport)
+
+ # This should succeed without calling the probe
+ token = await getattr(credential, get_token_method)("scope")
+ assert token.token == "token"