CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-azure-identity

Microsoft Azure Identity Library providing authentication credentials for Azure SDK clients.

Pending

Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

Overview
Eval results
Files

interactive.mddocs/

Interactive User Credentials

Enable user authentication through interactive flows including browser-based authentication, device code flow, and username/password authentication. These credentials are designed for applications that need to authenticate end users and operate on their behalf.

Capabilities

InteractiveBrowserCredential

Opens a web browser to interactively authenticate a user through Microsoft Entra ID. The most user-friendly authentication method for desktop and mobile applications with browser access.

from azure.identity._constants import DEVELOPER_SIGN_ON_CLIENT_ID

class InteractiveBrowserCredential:
    def __init__(
        self,
        *,
        client_id: str = DEVELOPER_SIGN_ON_CLIENT_ID,
        authority: Optional[str] = None,
        tenant_id: Optional[str] = None,
        redirect_uri: Optional[str] = None,
        authentication_record: Optional[AuthenticationRecord] = None,
        disable_automatic_authentication: bool = False,
        cache_persistence_options: Optional[TokenCachePersistenceOptions] = None,
        disable_instance_discovery: bool = False,
        enable_support_logging: bool = False,
        timeout: Optional[int] = None,
        parent_window_handle: Optional[int] = None,
        login_hint: Optional[str] = None,
        enable_msa_passthrough: bool = False,
        **kwargs
    ):
        """
        Create an InteractiveBrowserCredential for user authentication via web browser.
        
        Args:
            client_id: Client ID of a Microsoft Entra application (defaults to Azure development application)
            authority: Authority of a Microsoft Entra endpoint
            tenant_id: Microsoft Entra tenant ID (restricts authentication to this tenant)
            redirect_uri: Redirect URI for the application (default: http://localhost)
            authentication_record: AuthenticationRecord from previous authenticate() call
            disable_automatic_authentication: Raise AuthenticationRequiredError instead of automatically prompting
            cache_persistence_options: Configuration for persistent token caching
            disable_instance_discovery: Disable instance discovery and authority validation
            enable_support_logging: Enable additional support logging
            timeout: Request timeout in seconds
            parent_window_handle: Handle to parent window for embedded browser scenarios (Windows only)
            login_hint: Username hint to pre-fill during authentication
            enable_msa_passthrough: Enable Microsoft Account (MSA) passthrough
        """

    def authenticate(self, *scopes: str, claims: Optional[str] = None, **kwargs) -> AuthenticationRecord:
        """
        Interactively authenticate a user and return an AuthenticationRecord.
        
        Args:
            *scopes: Desired scopes for the access token
            claims: Additional claims required in the token
            
        Returns:
            AuthenticationRecord: Account information that can be used to create subsequent credentials
            
        Raises:
            ClientAuthenticationError: Authentication failed
        """

    def get_token(self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs) -> AccessToken:
        """
        Request an access token for the specified scopes.
        
        Args:
            *scopes: Desired scopes for the access token
            claims: Additional claims required in the token
            tenant_id: Optional tenant ID override
            
        Returns:
            AccessToken: The access token with expiration information
            
        Raises:
            AuthenticationRequiredError: Interactive authentication is required
        """

    def get_token_info(self, *scopes: str, options: Optional[dict] = None) -> dict:
        """
        Request access token with additional information.
        
        Args:
            *scopes: Desired scopes for the access token
            options: Additional options for token acquisition
            
        Returns:
            dict: Token information including access token and metadata
        """

Usage Example:

from azure.identity import InteractiveBrowserCredential
from azure.identity import AuthenticationRequiredError

# Basic browser authentication
credential = InteractiveBrowserCredential()

# Authenticate user and get account record
try:
    record = credential.authenticate(scopes=["https://graph.microsoft.com/.default"])
    print(f"Authenticated user: {record.username}")
except Exception as e:
    print(f"Authentication failed: {e}")

# Reuse authentication record in subsequent sessions
from azure.identity import InteractiveBrowserCredential

saved_credential = InteractiveBrowserCredential(
    authentication_record=record,
    disable_automatic_authentication=True  # Don't prompt if cache expires
)

# Tenant-specific authentication
tenant_credential = InteractiveBrowserCredential(
    tenant_id="your-tenant-id",
    client_id="your-app-client-id"
)

# Use with Azure SDK
from azure.storage.blob import BlobServiceClient

blob_client = BlobServiceClient(
    account_url="https://account.blob.core.windows.net",
    credential=credential
)

DeviceCodeCredential

Authenticates users through the device code flow, where users authenticate on a different device using a browser. Ideal for devices without browsers or in headless environments.

from azure.identity._constants import DEVELOPER_SIGN_ON_CLIENT_ID

class DeviceCodeCredential:
    def __init__(
        self,
        client_id: str = DEVELOPER_SIGN_ON_CLIENT_ID,
        *,
        timeout: Optional[int] = None,
        prompt_callback: Optional[Callable[[str, str, datetime], None]] = None,
        authority: Optional[str] = None,
        tenant_id: Optional[str] = None,
        authentication_record: Optional[AuthenticationRecord] = None,
        disable_automatic_authentication: bool = False,
        cache_persistence_options: Optional[TokenCachePersistenceOptions] = None,
        disable_instance_discovery: bool = False,
        enable_support_logging: bool = False,
        **kwargs
    ):
        """
        Create a DeviceCodeCredential for device code flow authentication.
        
        Args:
            client_id: Client ID of a Microsoft Entra application (defaults to Azure development application)
            timeout: Seconds to wait for user authentication completion
            prompt_callback: Function to display authentication instructions to the user
            authority: Authority of a Microsoft Entra endpoint
            tenant_id: Microsoft Entra tenant ID
            authentication_record: AuthenticationRecord from previous authenticate() call
            disable_automatic_authentication: Raise AuthenticationRequiredError instead of prompting
            cache_persistence_options: Configuration for persistent token caching
            disable_instance_discovery: Disable instance discovery and authority validation
            enable_support_logging: Enable additional support logging
        """

    def authenticate(self, *scopes: str, claims: Optional[str] = None, **kwargs) -> AuthenticationRecord:
        """
        Authenticate a user via device code flow and return an AuthenticationRecord.
        
        Args:
            *scopes: Desired scopes for the access token
            claims: Additional claims required in the token
            
        Returns:
            AuthenticationRecord: Account information for subsequent authentications
        """

    def get_token(self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs) -> AccessToken:
        """
        Request an access token using device code flow.
        
        Args:
            *scopes: Desired scopes for the access token
            claims: Additional claims required in the token
            tenant_id: Optional tenant ID override
            
        Returns:
            AccessToken: The access token with expiration information
            
        Raises:
            AuthenticationRequiredError: User authentication is required
        """

    def get_token_info(self, *scopes: str, options: Optional[dict] = None) -> dict:
        """
        Request access token with additional information.
        
        Args:
            *scopes: Desired scopes for the access token
            options: Additional options for token acquisition
            
        Returns:
            dict: Token information including access token and metadata
        """

Usage Example:

from azure.identity import DeviceCodeCredential
from datetime import datetime

def custom_prompt_callback(verification_uri: str, user_code: str, expires_on: datetime):
    """Custom function to display device code to user."""
    print("*" * 50)
    print("DEVICE CODE AUTHENTICATION REQUIRED")
    print(f"Please visit: {verification_uri}")
    print(f"Enter code: {user_code}")
    print(f"Code expires at: {expires_on}")
    print("*" * 50)

# Device code authentication with custom prompt
credential = DeviceCodeCredential(
    prompt_callback=custom_prompt_callback,
    timeout=300  # 5 minutes for user to complete authentication
)

# Authenticate and save account record
record = credential.authenticate(scopes=["https://graph.microsoft.com/.default"])

# Use credential with Azure SDK
from azure.mgmt.resource import ResourceManagementClient

resource_client = ResourceManagementClient(
    credential=credential,
    subscription_id="your-subscription-id"
)

# List resource groups
for rg in resource_client.resource_groups.list():
    print(rg.name)

UsernamePasswordCredential

Authenticates a user using username and password credentials. Generally not recommended due to security concerns, but useful for legacy scenarios and automated testing.

class UsernamePasswordCredential:
    def __init__(
        self,
        client_id: str,
        username: str,
        password: str,
        *,
        authority: Optional[str] = None,
        tenant_id: Optional[str] = None,
        cache_persistence_options: Optional[TokenCachePersistenceOptions] = None,
        disable_instance_discovery: bool = False,
        additionally_allowed_tenants: List[str] = None,
        **kwargs
    ):
        """
        Create a UsernamePasswordCredential for password-based user authentication.
        
        Args:
            client_id: The application's client ID
            username: The user's username (typically email address)
            password: The user's password
            authority: Authority of a Microsoft Entra endpoint
            tenant_id: Microsoft Entra tenant ID
            cache_persistence_options: Configuration for persistent token caching
            disable_instance_discovery: Disable instance discovery and authority validation
            additionally_allowed_tenants: Additional allowed tenants beyond the configured tenant
            
        Warning:
            Password-based authentication is less secure than interactive methods.
            Consider using InteractiveBrowserCredential or DeviceCodeCredential instead.
        """

    def authenticate(self, *scopes: str, claims: Optional[str] = None, **kwargs) -> AuthenticationRecord:
        """
        Authenticate the user and return an AuthenticationRecord.
        
        Args:
            *scopes: Desired scopes for the access token
            claims: Additional claims required in the token
            
        Returns:
            AuthenticationRecord: Account information for subsequent authentications
        """

    def get_token(self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs) -> AccessToken:
        """
        Request an access token using username and password.
        
        Args:
            *scopes: Desired scopes for the access token
            claims: Additional claims required in the token
            tenant_id: Optional tenant ID override
            
        Returns:
            AccessToken: The access token with expiration information
            
        Raises:
            ClientAuthenticationError: Invalid username or password
        """

    def get_token_info(self, *scopes: str, options: Optional[dict] = None) -> dict:
        """
        Request access token with additional information.
        
        Args:
            *scopes: Desired scopes for the access token
            options: Additional options for token acquisition
            
        Returns:
            dict: Token information including access token and metadata
        """

Usage Example:

from azure.identity import UsernamePasswordCredential

# Username/password authentication (use with caution)
credential = UsernamePasswordCredential(
    client_id="your-public-client-id",  # Must be a public client
    username="user@example.com",
    password="user-password"
)

# For automated testing scenarios
import os

test_credential = UsernamePasswordCredential(
    client_id=os.environ["TEST_CLIENT_ID"],
    username=os.environ["TEST_USERNAME"], 
    password=os.environ["TEST_PASSWORD"],
    tenant_id=os.environ["TEST_TENANT_ID"]
)

# Use with Azure SDK (not recommended for production)
from azure.keyvault.secrets import SecretClient

secret_client = SecretClient(
    vault_url="https://vault.vault.azure.net/",
    credential=credential
)

Interactive Credential Base

All interactive credentials extend a common base class that provides shared functionality:

class InteractiveCredential:
    """Base class for interactive user credentials."""
    
    def authenticate(self, *scopes: str, claims: Optional[str] = None, **kwargs) -> AuthenticationRecord:
        """
        Interactively authenticate a user and return account information.
        
        Args:
            *scopes: Desired scopes for authentication
            claims: Additional claims required
            
        Returns:
            AuthenticationRecord: Account information for caching and reuse
        """

    def get_token(self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs) -> AccessToken:
        """Request an access token, prompting for authentication if necessary."""

    def get_token_info(self, *scopes: str, options: Optional[dict] = None) -> dict:
        """Request access token with additional information."""

Authentication Flow Patterns

Silent Authentication Pattern

from azure.identity import InteractiveBrowserCredential, AuthenticationRequiredError

# Create credential with cached authentication record
credential = InteractiveBrowserCredential(
    authentication_record=saved_record,
    disable_automatic_authentication=True
)

try:
    # Try to get token silently from cache
    token = credential.get_token("https://graph.microsoft.com/.default")
    print("Silent authentication successful")
except AuthenticationRequiredError:
    # Cache expired or invalid, need interactive authentication
    print("Interactive authentication required")
    record = credential.authenticate("https://graph.microsoft.com/.default")
    # Save record for future silent authentication

Conditional Interactive Authentication

from azure.identity import DefaultAzureCredential

# Try DefaultAzureCredential first (non-interactive methods)
default_credential = DefaultAzureCredential(
    exclude_interactive_browser_credential=True
)

try:
    token = default_credential.get_token("https://graph.microsoft.com/.default")
    print("Non-interactive authentication successful")
except CredentialUnavailableError:
    # Fall back to interactive authentication
    from azure.identity import InteractiveBrowserCredential
    
    interactive_credential = InteractiveBrowserCredential()
    token = interactive_credential.get_token("https://graph.microsoft.com/.default")
    print("Interactive authentication successful")

Common Interactive Parameters

# Authentication record for silent authentication
authentication_record: Optional[AuthenticationRecord] = None

# Automatic vs. manual authentication control
disable_automatic_authentication: bool = False

# Tenant restriction
tenant_id: Optional[str] = None

# Token caching
cache_persistence_options: Optional[TokenCachePersistenceOptions] = None

# Authority customization
authority: Optional[str] = None

# Instance discovery
disable_instance_discovery: bool = False

# Additional logging
enable_support_logging: bool = False

# Client application configuration  
client_id: str = DEVELOPER_SIGN_ON_CLIENT_ID  # Default development app ID

# Multi-tenant support (UsernamePasswordCredential only)
additionally_allowed_tenants: List[str] = None

Security Considerations

Recommended Security Practices:

  1. Use InteractiveBrowserCredential for desktop applications
  2. Use DeviceCodeCredential for headless or constrained environments
  3. Avoid UsernamePasswordCredential in production - passwords are vulnerable
  4. Enable token caching to reduce authentication prompts
  5. Use authentication records to enable silent authentication
  6. Specify tenant_id to restrict authentication to specific tenants
  7. Enable support logging for troubleshooting authentication issues

Authentication Record Management:

# Serialize authentication record for storage
record = credential.authenticate(scopes)
serialized = record.serialize()

# Store in secure location (encrypted file, secure keystore, etc.)
with open("auth_record.json", "w") as f:
    f.write(serialized)

# Deserialize for reuse
with open("auth_record.json", "r") as f:
    serialized = f.read()

record = AuthenticationRecord.deserialize(serialized)
credential = InteractiveBrowserCredential(authentication_record=record)

Install with Tessl CLI

npx tessl i tessl/pypi-azure-identity

docs

advanced.md

async.md

azure-platform.md

core-credentials.md

developer.md

index.md

interactive.md

service-principal.md

tile.json