GraphRag
/
graphrag-ollama
/lib
/python3.12
/site-packages
/azure
/identity
/_credentials
/default.py
| # ------------------------------------ | |
| # Copyright (c) Microsoft Corporation. | |
| # Licensed under the MIT License. | |
| # ------------------------------------ | |
| import logging | |
| import os | |
| from typing import List, Any, Optional, cast | |
| from azure.core.credentials import AccessToken, AccessTokenInfo, TokenRequestOptions, SupportsTokenInfo, TokenCredential | |
| from .._constants import EnvironmentVariables | |
| from .._internal import get_default_authority, normalize_authority, within_dac | |
| from .azure_powershell import AzurePowerShellCredential | |
| from .browser import InteractiveBrowserCredential | |
| from .chained import ChainedTokenCredential | |
| from .environment import EnvironmentCredential | |
| from .managed_identity import ManagedIdentityCredential | |
| from .shared_cache import SharedTokenCacheCredential | |
| from .azure_cli import AzureCliCredential | |
| from .azd_cli import AzureDeveloperCliCredential | |
| from .vscode import VisualStudioCodeCredential | |
| from .workload_identity import WorkloadIdentityCredential | |
| _LOGGER = logging.getLogger(__name__) | |
| class DefaultAzureCredential(ChainedTokenCredential): | |
| """A credential capable of handling most Azure SDK authentication scenarios. See | |
| https://aka.ms/azsdk/python/identity/credential-chains#usage-guidance-for-defaultazurecredential. | |
| The identity it uses depends on the environment. When an access token is needed, it requests one using these | |
| identities in turn, stopping when one provides a token: | |
| 1. A service principal configured by environment variables. See :class:`~azure.identity.EnvironmentCredential` for | |
| more details. | |
| 2. WorkloadIdentityCredential if environment variable configuration is set by the Azure workload | |
| identity webhook. | |
| 3. An Azure managed identity. See :class:`~azure.identity.ManagedIdentityCredential` for more details. | |
| 4. On Windows only: a user who has signed in with a Microsoft application, such as Visual Studio. If multiple | |
| identities are in the cache, then the value of the environment variable ``AZURE_USERNAME`` is used to select | |
| which identity to use. See :class:`~azure.identity.SharedTokenCacheCredential` for more details. | |
| 5. The identity currently logged in to the Azure CLI. | |
| 6. The identity currently logged in to Azure PowerShell. | |
| 7. The identity currently logged in to the Azure Developer CLI. | |
| This default behavior is configurable with keyword arguments. | |
| :keyword str authority: Authority of a Microsoft Entra endpoint, for example 'login.microsoftonline.com', | |
| the authority for Azure Public Cloud (which is the default). :class:`~azure.identity.AzureAuthorityHosts` | |
| defines authorities for other clouds. Managed identities ignore this because they reside in a single cloud. | |
| :keyword bool exclude_workload_identity_credential: Whether to exclude the workload identity from the credential. | |
| Defaults to **False**. | |
| :keyword bool exclude_developer_cli_credential: Whether to exclude the Azure Developer CLI | |
| from the credential. Defaults to **False**. | |
| :keyword bool exclude_cli_credential: Whether to exclude the Azure CLI from the credential. Defaults to **False**. | |
| :keyword bool exclude_environment_credential: Whether to exclude a service principal configured by environment | |
| variables from the credential. Defaults to **False**. | |
| :keyword bool exclude_managed_identity_credential: Whether to exclude managed identity from the credential. | |
| Defaults to **False**. | |
| :keyword bool exclude_powershell_credential: Whether to exclude Azure PowerShell. Defaults to **False**. | |
| :keyword bool exclude_visual_studio_code_credential: Whether to exclude stored credential from VS Code. | |
| Defaults to **True**. | |
| :keyword bool exclude_shared_token_cache_credential: Whether to exclude the shared token cache. Defaults to | |
| **False**. | |
| :keyword bool exclude_interactive_browser_credential: Whether to exclude interactive browser authentication (see | |
| :class:`~azure.identity.InteractiveBrowserCredential`). Defaults to **True**. | |
| :keyword str interactive_browser_tenant_id: Tenant ID to use when authenticating a user through | |
| :class:`~azure.identity.InteractiveBrowserCredential`. Defaults to the value of environment variable | |
| AZURE_TENANT_ID, if any. If unspecified, users will authenticate in their home tenants. | |
| :keyword str managed_identity_client_id: The client ID of a user-assigned managed identity. Defaults to the value | |
| of the environment variable AZURE_CLIENT_ID, if any. If not specified, a system-assigned identity will be used. | |
| :keyword str workload_identity_client_id: The client ID of an identity assigned to the pod. Defaults to the value | |
| of the environment variable AZURE_CLIENT_ID, if any. If not specified, the pod's default identity will be used. | |
| :keyword str workload_identity_tenant_id: Preferred tenant for :class:`~azure.identity.WorkloadIdentityCredential`. | |
| Defaults to the value of environment variable AZURE_TENANT_ID, if any. | |
| :keyword str interactive_browser_client_id: The client ID to be used in interactive browser credential. If not | |
| specified, users will authenticate to an Azure development application. | |
| :keyword str shared_cache_username: Preferred username for :class:`~azure.identity.SharedTokenCacheCredential`. | |
| Defaults to the value of environment variable AZURE_USERNAME, if any. | |
| :keyword str shared_cache_tenant_id: Preferred tenant for :class:`~azure.identity.SharedTokenCacheCredential`. | |
| Defaults to the value of environment variable AZURE_TENANT_ID, if any. | |
| :keyword str visual_studio_code_tenant_id: Tenant ID to use when authenticating with | |
| :class:`~azure.identity.VisualStudioCodeCredential`. Defaults to the "Azure: Tenant" setting in VS Code's user | |
| settings or, when that setting has no value, the "organizations" tenant, which supports only Azure Active | |
| Directory work or school accounts. | |
| :keyword int process_timeout: The timeout in seconds to use for developer credentials that run | |
| subprocesses (e.g. AzureCliCredential, AzurePowerShellCredential). Defaults to **10** seconds. | |
| .. admonition:: Example: | |
| .. literalinclude:: ../samples/credential_creation_code_snippets.py | |
| :start-after: [START create_default_credential] | |
| :end-before: [END create_default_credential] | |
| :language: python | |
| :dedent: 4 | |
| :caption: Create a DefaultAzureCredential. | |
| """ | |
| def __init__(self, **kwargs: Any) -> None: # pylint: disable=too-many-statements, too-many-locals | |
| if "tenant_id" in kwargs: | |
| raise TypeError("'tenant_id' is not supported in DefaultAzureCredential.") | |
| authority = kwargs.pop("authority", None) | |
| vscode_tenant_id = kwargs.pop( | |
| "visual_studio_code_tenant_id", os.environ.get(EnvironmentVariables.AZURE_TENANT_ID) | |
| ) | |
| vscode_args = dict(kwargs) | |
| if authority: | |
| vscode_args["authority"] = authority | |
| if vscode_tenant_id: | |
| vscode_args["tenant_id"] = vscode_tenant_id | |
| authority = normalize_authority(authority) if authority else get_default_authority() | |
| interactive_browser_tenant_id = kwargs.pop( | |
| "interactive_browser_tenant_id", os.environ.get(EnvironmentVariables.AZURE_TENANT_ID) | |
| ) | |
| managed_identity_client_id = kwargs.pop( | |
| "managed_identity_client_id", os.environ.get(EnvironmentVariables.AZURE_CLIENT_ID) | |
| ) | |
| workload_identity_client_id = kwargs.pop("workload_identity_client_id", managed_identity_client_id) | |
| workload_identity_tenant_id = kwargs.pop( | |
| "workload_identity_tenant_id", os.environ.get(EnvironmentVariables.AZURE_TENANT_ID) | |
| ) | |
| interactive_browser_client_id = kwargs.pop("interactive_browser_client_id", None) | |
| shared_cache_username = kwargs.pop("shared_cache_username", os.environ.get(EnvironmentVariables.AZURE_USERNAME)) | |
| shared_cache_tenant_id = kwargs.pop( | |
| "shared_cache_tenant_id", os.environ.get(EnvironmentVariables.AZURE_TENANT_ID) | |
| ) | |
| process_timeout = kwargs.pop("process_timeout", 10) | |
| exclude_workload_identity_credential = kwargs.pop("exclude_workload_identity_credential", False) | |
| exclude_environment_credential = kwargs.pop("exclude_environment_credential", False) | |
| exclude_managed_identity_credential = kwargs.pop("exclude_managed_identity_credential", False) | |
| exclude_shared_token_cache_credential = kwargs.pop("exclude_shared_token_cache_credential", False) | |
| exclude_visual_studio_code_credential = kwargs.pop("exclude_visual_studio_code_credential", True) | |
| exclude_developer_cli_credential = kwargs.pop("exclude_developer_cli_credential", False) | |
| exclude_cli_credential = kwargs.pop("exclude_cli_credential", False) | |
| exclude_interactive_browser_credential = kwargs.pop("exclude_interactive_browser_credential", True) | |
| exclude_powershell_credential = kwargs.pop("exclude_powershell_credential", False) | |
| credentials: List[SupportsTokenInfo] = [] | |
| within_dac.set(True) | |
| if not exclude_environment_credential: | |
| credentials.append(EnvironmentCredential(authority=authority, _within_dac=True, **kwargs)) | |
| if not exclude_workload_identity_credential: | |
| if all(os.environ.get(var) for var in EnvironmentVariables.WORKLOAD_IDENTITY_VARS): | |
| client_id = workload_identity_client_id | |
| credentials.append( | |
| WorkloadIdentityCredential( | |
| client_id=cast(str, client_id), | |
| tenant_id=workload_identity_tenant_id, | |
| file=os.environ[EnvironmentVariables.AZURE_FEDERATED_TOKEN_FILE], | |
| **kwargs | |
| ) | |
| ) | |
| if not exclude_managed_identity_credential: | |
| credentials.append( | |
| ManagedIdentityCredential( | |
| client_id=managed_identity_client_id, | |
| _exclude_workload_identity_credential=exclude_workload_identity_credential, | |
| **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) | |
| if not exclude_visual_studio_code_credential: | |
| credentials.append(VisualStudioCodeCredential(**vscode_args)) | |
| if not exclude_cli_credential: | |
| credentials.append(AzureCliCredential(process_timeout=process_timeout)) | |
| if not exclude_powershell_credential: | |
| credentials.append(AzurePowerShellCredential(process_timeout=process_timeout)) | |
| if not exclude_developer_cli_credential: | |
| credentials.append(AzureDeveloperCliCredential(process_timeout=process_timeout)) | |
| if not exclude_interactive_browser_credential: | |
| if interactive_browser_client_id: | |
| credentials.append( | |
| InteractiveBrowserCredential( | |
| tenant_id=interactive_browser_tenant_id, client_id=interactive_browser_client_id, **kwargs | |
| ) | |
| ) | |
| else: | |
| credentials.append(InteractiveBrowserCredential(tenant_id=interactive_browser_tenant_id, **kwargs)) | |
| within_dac.set(False) | |
| super(DefaultAzureCredential, self).__init__(*credentials) | |
| def get_token( | |
| self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs: Any | |
| ) -> AccessToken: | |
| """Request an access token for `scopes`. | |
| This method is called automatically by Azure SDK clients. | |
| :param str scopes: desired scopes for the access token. This method requires at least one scope. | |
| For more information about scopes, see | |
| https://learn.microsoft.com/entra/identity-platform/scopes-oidc. | |
| :keyword str claims: additional claims required in the token, such as those returned in a resource provider's | |
| claims challenge following an authorization failure. | |
| :keyword str tenant_id: optional tenant to include in the token request. | |
| :return: An access token with the desired scopes. | |
| :rtype: ~azure.core.credentials.AccessToken | |
| :raises ~azure.core.exceptions.ClientAuthenticationError: authentication failed. The exception has a | |
| `message` attribute listing each authentication attempt and its error message. | |
| """ | |
| if self._successful_credential: | |
| token = cast(TokenCredential, self._successful_credential).get_token( | |
| *scopes, claims=claims, tenant_id=tenant_id, **kwargs | |
| ) | |
| _LOGGER.info( | |
| "%s acquired a token from %s", self.__class__.__name__, self._successful_credential.__class__.__name__ | |
| ) | |
| return token | |
| within_dac.set(True) | |
| token = super().get_token(*scopes, claims=claims, tenant_id=tenant_id, **kwargs) | |
| within_dac.set(False) | |
| return token | |
| def get_token_info(self, *scopes: str, options: Optional[TokenRequestOptions] = None) -> AccessTokenInfo: | |
| """Request an access token for `scopes`. | |
| This is an alternative to `get_token` to enable certain scenarios that require additional properties | |
| on the token. This method is called automatically by Azure SDK clients. | |
| :param str scopes: desired scopes for the access token. This method requires at least one scope. | |
| For more information about scopes, see https://learn.microsoft.com/entra/identity-platform/scopes-oidc. | |
| :keyword options: A dictionary of options for the token request. Unknown options will be ignored. Optional. | |
| :paramtype options: ~azure.core.credentials.TokenRequestOptions | |
| :rtype: AccessTokenInfo | |
| :return: An AccessTokenInfo instance containing information about the token. | |
| :raises ~azure.core.exceptions.ClientAuthenticationError: authentication failed. The exception has a | |
| `message` attribute listing each authentication attempt and its error message. | |
| """ | |
| if self._successful_credential: | |
| token_info = cast(SupportsTokenInfo, self._successful_credential).get_token_info(*scopes, options=options) | |
| _LOGGER.info( | |
| "%s acquired a token from %s", self.__class__.__name__, self._successful_credential.__class__.__name__ | |
| ) | |
| return token_info | |
| within_dac.set(True) | |
| token_info = cast(SupportsTokenInfo, super()).get_token_info(*scopes, options=options) | |
| within_dac.set(False) | |
| return token_info | |