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

service-principal.mddocs/

Service Principal Credentials

Authenticate applications and services using Azure Active Directory service principals. Service principals are non-interactive identities that represent applications, enabling secure authentication without user interaction. These credentials support client secrets, X.509 certificates, and custom client assertions.

Capabilities

ClientSecretCredential

Authenticates a service principal using a client secret. This is the most common form of service principal authentication, suitable for applications that can securely store secrets.

class ClientSecretCredential:
    def __init__(
        self,
        tenant_id: str,
        client_id: str, 
        client_secret: str,
        *,
        authority: Optional[str] = None,
        cache_persistence_options: Optional[TokenCachePersistenceOptions] = None,
        disable_instance_discovery: bool = False,
        additionally_allowed_tenants: List[str] = None,
        **kwargs
    ):
        """
        Create a ClientSecretCredential for service principal authentication.
        
        Args:
            tenant_id: ID of the service principal's tenant (directory ID)
            client_id: The service principal's client ID (application ID)
            client_secret: One of the service principal's client secrets
            authority: Authority of a Microsoft Entra endpoint. Default: login.microsoftonline.com
            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
        """

    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:
            ClientAuthenticationError: Authentication failed due to invalid credentials
        """

    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 ClientSecretCredential
from azure.keyvault.secrets import SecretClient

# Create service principal credential
credential = ClientSecretCredential(
    tenant_id="your-tenant-id",
    client_id="your-client-id",
    client_secret="your-client-secret"
)

# Use with Azure SDK client
secret_client = SecretClient(
    vault_url="https://vault.vault.azure.net/",
    credential=credential
)

# Multi-tenant configuration
multi_tenant_credential = ClientSecretCredential(
    tenant_id="primary-tenant-id", 
    client_id="your-client-id",
    client_secret="your-client-secret",
    additionally_allowed_tenants=["tenant-2", "tenant-3"]
)

CertificateCredential

Authenticates a service principal using an X.509 certificate. More secure than client secrets as certificates can be stored in secure hardware and have expiration dates.

class CertificateCredential:
    def __init__(
        self,
        tenant_id: str,
        client_id: str,
        certificate_path: Optional[str] = None,
        *,
        authority: Optional[str] = None,
        certificate_data: Optional[bytes] = None,
        password: Optional[Union[str, bytes]] = None,
        send_certificate_chain: bool = False,
        cache_persistence_options: Optional[TokenCachePersistenceOptions] = None,
        disable_instance_discovery: bool = False,
        additionally_allowed_tenants: List[str] = None,
        **kwargs
    ):
        """
        Create a CertificateCredential for certificate-based service principal authentication.
        
        Args:
            tenant_id: ID of the service principal's tenant
            client_id: The service principal's client ID
            certificate_path: Path to a certificate file in PEM or PKCS12 format
            authority: Authority of a Microsoft Entra endpoint
            certificate_data: The bytes of a certificate in PEM or PKCS12 format (alternative to certificate_path)
            password: The certificate's password (for PKCS12 certificates)
            send_certificate_chain: Send the complete public certificate chain in x5c header
            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
        """

    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 using certificate authentication.
        
        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: Authentication failed due to invalid certificate
            ValueError: Certificate path and data both provided or neither provided
        """

    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 CertificateCredential

# Certificate from file path
credential = CertificateCredential(
    tenant_id="your-tenant-id",
    client_id="your-client-id", 
    certificate_path="/path/to/certificate.pem"
)

# Certificate with password (PKCS12)
p12_credential = CertificateCredential(
    tenant_id="your-tenant-id",
    client_id="your-client-id",
    certificate_path="/path/to/certificate.p12",
    password="certificate-password"
)

# Certificate from bytes (loaded from secure storage)
with open("/path/to/certificate.pem", "rb") as cert_file:
    cert_data = cert_file.read()
    
data_credential = CertificateCredential(
    tenant_id="your-tenant-id",
    client_id="your-client-id",
    certificate_data=cert_data
)

# Include full certificate chain for validation
chain_credential = CertificateCredential(
    tenant_id="your-tenant-id", 
    client_id="your-client-id",
    certificate_path="/path/to/certificate.pem",
    send_certificate_chain=True
)

ClientAssertionCredential

Authenticates a service principal using a signed client assertion (JWT). Provides the most flexibility for custom authentication scenarios and integration with hardware security modules (HSMs) or custom signing mechanisms.

class ClientAssertionCredential:
    def __init__(
        self,
        tenant_id: str,
        client_id: str,
        func: Callable[[], str],
        *,
        authority: Optional[str] = None,
        cache_persistence_options: Optional[TokenCachePersistenceOptions] = None,
        disable_instance_discovery: bool = False,
        additionally_allowed_tenants: List[str] = None,
        **kwargs
    ):
        """
        Create a ClientAssertionCredential for custom assertion-based authentication.
        
        Args:
            tenant_id: ID of the application's Microsoft Entra tenant
            client_id: The application's client ID
            func: A callable that returns a client assertion (signed JWT)
            authority: Authority of a Microsoft Entra endpoint
            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
            
        Note:
            The func callable must return a valid JWT client assertion each time it's called.
            The assertion must be signed with the application's registered certificate or key.
        """

    def get_token(self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs) -> AccessToken:
        """
        Request an access token using the client assertion.
        
        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: Authentication failed due to invalid assertion
        """

    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 ClientAssertionCredential
import jwt
import time

def create_client_assertion():
    """Create a signed JWT client assertion."""
    now = int(time.time())
    payload = {
        'aud': f'https://login.microsoftonline.com/{tenant_id}/v2.0',
        'exp': now + 600,  # 10 minutes
        'iss': client_id,
        'jti': str(uuid.uuid4()),  # unique identifier
        'nbf': now,
        'sub': client_id
    }
    
    # Sign with your private key
    return jwt.encode(payload, private_key, algorithm='RS256')

# Create credential with custom assertion function
credential = ClientAssertionCredential(
    tenant_id="your-tenant-id",
    client_id="your-client-id",
    func=create_client_assertion
)

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

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

OnBehalfOfCredential

Implements the OAuth 2.0 On-Behalf-Of flow for middle-tier services that need to access downstream APIs on behalf of a user. Commonly used in multi-tier application architectures.

class OnBehalfOfCredential:
    def __init__(
        self,
        tenant_id: str,
        client_id: str,
        *,
        client_secret: Optional[str] = None,
        user_assertion: Optional[str] = None,
        client_assertion: Optional[str] = None,
        client_assertion_func: Optional[Callable[[], str]] = None,
        authority: Optional[str] = None,
        cache_persistence_options: Optional[TokenCachePersistenceOptions] = None,
        disable_instance_discovery: bool = False,
        additionally_allowed_tenants: List[str] = None,
        **kwargs
    ):
        """
        Create an OnBehalfOfCredential for on-behalf-of authentication flow.
        
        Args:
            tenant_id: ID of the application's Microsoft Entra tenant
            client_id: The application's client ID
            client_secret: One of the application's client secrets (mutually exclusive with client_assertion)
            user_assertion: The access token the application will use to authenticate on behalf of the user
            client_assertion: Signed client assertion (mutually exclusive with client_secret)
            client_assertion_func: Function that returns a client assertion
            authority: Authority of a Microsoft Entra endpoint
            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
            
        Note:
            Either client_secret or client_assertion (or client_assertion_func) must be provided.
            The user_assertion is typically obtained from the incoming request's Authorization header.
        """

    def get_token(self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs) -> AccessToken:
        """
        Request an access token on behalf of a user.
        
        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: Authentication failed
        """

    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 OnBehalfOfCredential
from flask import Flask, request

app = Flask(__name__)

@app.route('/api/data')
def get_data():
    # Extract user token from Authorization header
    auth_header = request.headers.get('Authorization')
    user_token = auth_header.replace('Bearer ', '') if auth_header else None
    
    # Create OBO credential
    credential = OnBehalfOfCredential(
        tenant_id="your-tenant-id",
        client_id="your-client-id", 
        client_secret="your-client-secret",
        user_assertion=user_token
    )
    
    # Use credential to access downstream API on behalf of user
    from azure.storage.blob import BlobServiceClient
    
    blob_client = BlobServiceClient(
        account_url="https://account.blob.core.windows.net",
        credential=credential
    )
    
    # Access user's data
    containers = blob_client.list_containers()
    return [c.name for c in containers]

AuthorizationCodeCredential

Authenticates by redeeming an authorization code previously obtained from Microsoft Entra ID. Used in OAuth 2.0 authorization code flow scenarios, typically in web applications.

class AuthorizationCodeCredential:
    def __init__(
        self,
        tenant_id: str,
        client_id: str,
        authorization_code: str,
        redirect_uri: str,
        *,
        client_secret: Optional[str] = None,
        authority: Optional[str] = None,
        cache_persistence_options: Optional[TokenCachePersistenceOptions] = None,
        disable_instance_discovery: bool = False,
        additionally_allowed_tenants: List[str] = None,
        **kwargs
    ):
        """
        Create an AuthorizationCodeCredential for authorization code flow.
        
        Args:
            tenant_id: ID of the application's Microsoft Entra tenant
            client_id: The application's client ID
            authorization_code: The authorization code from the user's log-in
            redirect_uri: The application's redirect URI (must match registered URI)
            client_secret: One of the application's client secrets (required for confidential clients)
            authority: Authority of a Microsoft Entra endpoint
            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
        """

    def get_token(self, *scopes: str, claims: Optional[str] = None, tenant_id: Optional[str] = None, **kwargs) -> AccessToken:
        """
        Redeem the authorization code for an access token.
        
        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 authorization code or credentials
        """

    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 AuthorizationCodeCredential
from flask import Flask, request, redirect, session

app = Flask(__name__)

@app.route('/login')
def login():
    # Redirect to Microsoft Entra ID for authorization
    auth_url = (
        f"https://login.microsoftonline.com/{tenant_id}/oauth2/v2.0/authorize"
        f"?client_id={client_id}"
        f"&response_type=code"
        f"&redirect_uri={redirect_uri}"
        f"&scope=https://graph.microsoft.com/.default"
    )
    return redirect(auth_url)

@app.route('/callback')  
def callback():
    # Extract authorization code from callback
    code = request.args.get('code')
    
    # Create credential with authorization code
    credential = AuthorizationCodeCredential(
        tenant_id="your-tenant-id",
        client_id="your-client-id",
        authorization_code=code,
        redirect_uri="http://localhost:5000/callback",
        client_secret="your-client-secret"
    )
    
    # Store credential in session for subsequent requests
    session['credential'] = credential
    return "Authentication successful!"

Common Configuration

All service principal credentials support these common configuration options:

# Multi-tenant configuration
additionally_allowed_tenants: List[str] = None

# Authority customization  
authority: str = "https://login.microsoftonline.com"  # Public cloud (default)
# authority: str = "https://login.chinacloudapi.cn"    # Azure China
# authority: str = "https://login.microsoftonline.us"  # Azure Government

# Token caching
cache_persistence_options: Optional[TokenCachePersistenceOptions] = None

# Instance discovery (for custom domains)
disable_instance_discovery: bool = False

# Logging and debugging
enable_support_logging: bool = False

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