CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-com-azure--azure-identity

The Azure Identity library provides Microsoft Entra ID token authentication support across the Azure SDK with a comprehensive set of TokenCredential implementations.

Pending
Overview
Eval results
Files

advanced-authentication-flows.mddocs/

Advanced Authentication Flows

Advanced authentication flows support specialized scenarios including on-behalf-of delegation, workload identity federation, and Azure Pipelines service connections. These flows enable complex authentication patterns for service-to-service communication and cloud-native applications.

On-Behalf-Of (OBO) Flow

The on-behalf-of flow enables a service to call another service on behalf of a user, using a JWT assertion from the original user authentication.

import com.azure.identity.OnBehalfOfCredential;
import com.azure.identity.OnBehalfOfCredentialBuilder;

// Using client secret
TokenCredential oboCredential = new OnBehalfOfCredentialBuilder()
    .tenantId("tenant-id")
    .clientId("middle-tier-service-client-id")
    .clientSecret("client-secret")
    .userAssertion("jwt-token-from-original-user-auth")
    .build();

// Using client certificate
TokenCredential oboCertCredential = new OnBehalfOfCredentialBuilder()
    .tenantId("tenant-id")
    .clientId("middle-tier-service-client-id")
    .pfxCertificate("path/to/certificate.pfx", "certificate-password")
    .userAssertion("jwt-token-from-original-user-auth")
    .build();

Workload Identity Federation

Workload identity enables applications running in external identity systems (like Kubernetes) to authenticate to Azure without storing secrets.

import com.azure.identity.WorkloadIdentityCredential;
import com.azure.identity.WorkloadIdentityCredentialBuilder;

// Basic workload identity (reads from environment variables)
TokenCredential credential = new WorkloadIdentityCredentialBuilder().build();

// Manual configuration
TokenCredential manualCredential = new WorkloadIdentityCredentialBuilder()
    .tenantId("tenant-id")
    .clientId("client-id")
    .tokenFilePath("/var/run/secrets/azure/tokens/azure-identity-token")
    .build();

Azure Pipelines Service Connection

Authenticate using Azure Pipelines service connections for CI/CD scenarios.

import com.azure.identity.AzurePipelinesCredential;
import com.azure.identity.AzurePipelinesCredentialBuilder;

// Azure Pipelines credential
TokenCredential credential = new AzurePipelinesCredentialBuilder()
    .tenantId("tenant-id")
    .clientId("service-connection-client-id")
    .serviceConnectionId("service-connection-id")
    .systemAccessToken(System.getenv("SYSTEM_ACCESSTOKEN"))  // From pipeline variable
    .build();

Environment Variables for Advanced Flows

Workload Identity

  • AZURE_CLIENT_ID - Client ID of the managed identity or service principal
  • AZURE_TENANT_ID - Azure tenant ID
  • AZURE_FEDERATED_TOKEN_FILE - Path to the federated token file
  • AZURE_AUTHORITY_HOST - Microsoft Entra ID authority host

Azure Pipelines

  • SYSTEM_ACCESSTOKEN - System access token from Azure Pipelines
  • AZURE_CLIENT_ID - Client ID of the service connection
  • AZURE_TENANT_ID - Tenant ID
  • AZURESUBSCRIPTION_SERVICE_CONNECTION_ID - Service connection ID

Advanced OBO Scenarios

// OBO with additional scopes
TokenCredential oboCredential = new OnBehalfOfCredentialBuilder()
    .tenantId("tenant-id")
    .clientId("client-id")
    .clientSecret("client-secret")
    .userAssertion("user-jwt-token")
    .build();

// Get token for downstream service
AccessToken downstreamToken = oboCredential.getTokenSync(
    new TokenRequestContext()
        .addScopes("api://downstream-service/.default")
        .setTenantId("downstream-tenant-id")
);

Kubernetes Workload Identity Setup

For Azure Kubernetes Service (AKS) with workload identity:

# Kubernetes ServiceAccount with workload identity annotation
apiVersion: v1
kind: ServiceAccount
metadata:
  name: my-service-account
  namespace: default
  annotations:
    azure.workload.identity/client-id: "client-id-of-user-assigned-managed-identity"
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-application
spec:
  template:
    metadata:
      labels:
        azure.workload.identity/use: "true"
    spec:
      serviceAccountName: my-service-account
      containers:
      - name: my-app
        image: my-app-image
        env:
        - name: AZURE_CLIENT_ID
          value: "client-id-of-user-assigned-managed-identity"
// In the application running in Kubernetes
TokenCredential credential = new WorkloadIdentityCredentialBuilder().build();

// The credential automatically uses the federated token from the pod
AccessToken token = credential.getTokenSync(
    new TokenRequestContext().addScopes("https://graph.microsoft.com/.default")
);

Multi-Tenant OBO Flow

// Configure OBO for multi-tenant scenarios
TokenCredential oboCredential = new OnBehalfOfCredentialBuilder()
    .tenantId("primary-tenant-id")
    .clientId("client-id")
    .clientSecret("client-secret")
    .userAssertion("user-jwt-token")
    .additionallyAllowedTenants("*")  // Allow cross-tenant access
    .build();

Custom Authority Hosts

// Use different authority hosts for sovereign clouds
TokenCredential govCloudCredential = new OnBehalfOfCredentialBuilder()
    .tenantId("tenant-id")
    .clientId("client-id")
    .clientSecret("client-secret")
    .userAssertion("user-jwt-token")
    .authorityHost(AzureAuthorityHosts.AZURE_GOVERNMENT)
    .build();

Error Handling

try {
    OnBehalfOfCredential credential = new OnBehalfOfCredentialBuilder()
        .tenantId("tenant-id")
        .clientId("client-id")
        .clientSecret("client-secret")
        .userAssertion("user-jwt-token")
        .build();
    
    AccessToken token = credential.getTokenSync(
        new TokenRequestContext().addScopes("api://downstream/.default")
    );
    
    System.out.println("OBO authentication successful");
    
} catch (ClientAuthenticationException e) {
    System.err.println("OBO authentication failed: " + e.getMessage());
    // Common causes:
    // - Invalid user assertion
    // - Service principal lacks necessary permissions
    // - Downstream API not configured for OBO
} catch (CredentialUnavailableException e) {
    System.err.println("OBO credential unavailable: " + e.getMessage());
}

API Reference

class OnBehalfOfCredential implements TokenCredential {
    Mono<AccessToken> getToken(TokenRequestContext request);
    AccessToken getTokenSync(TokenRequestContext request);
}

class OnBehalfOfCredentialBuilder extends AadCredentialBuilderBase<OnBehalfOfCredentialBuilder> {
    OnBehalfOfCredentialBuilder userAssertion(String userAssertion);
    OnBehalfOfCredentialBuilder clientSecret(String clientSecret);
    OnBehalfOfCredentialBuilder pfxCertificate(String certificatePath, String clientCertificatePassword);
    OnBehalfOfCredentialBuilder pemCertificate(String certificatePath);
    OnBehalfOfCredentialBuilder clientAssertion(Supplier<String> clientAssertionSupplier);
    OnBehalfOfCredentialBuilder sendCertificateChain(boolean sendCertificateChain);
    OnBehalfOfCredential build();
}

class WorkloadIdentityCredential implements TokenCredential {
    Mono<AccessToken> getToken(TokenRequestContext request);
    AccessToken getTokenSync(TokenRequestContext request);
}

class WorkloadIdentityCredentialBuilder extends AadCredentialBuilderBase<WorkloadIdentityCredentialBuilder> {
    WorkloadIdentityCredentialBuilder tokenFilePath(String tokenFilePath);
    WorkloadIdentityCredential build();
}

class AzurePipelinesCredential implements TokenCredential {
    Mono<AccessToken> getToken(TokenRequestContext request);
    AccessToken getTokenSync(TokenRequestContext request);
}

class AzurePipelinesCredentialBuilder extends AadCredentialBuilderBase<AzurePipelinesCredentialBuilder> {
    AzurePipelinesCredentialBuilder systemAccessToken(String systemAccessToken);
    AzurePipelinesCredentialBuilder serviceConnectionId(String serviceConnectionId);
    AzurePipelinesCredential build();
}

Advanced Configuration

// Configure with detailed options
TokenCredential credential = new OnBehalfOfCredentialBuilder()
    .tenantId("tenant-id")
    .clientId("client-id")
    .clientSecret("client-secret")
    .userAssertion("user-jwt-token")
    .authorityHost(AzureAuthorityHosts.AZURE_PUBLIC_CLOUD)
    .disableInstanceDiscovery()
    .executorService(executorService)
    .httpClient(httpClient)
    .maxRetry(3)
    .build();

Best Practices

  1. Secure Assertion Handling: Protect user assertions and never log them
  2. Scope Minimization: Request only the minimum required scopes for downstream services
  3. Token Caching: Advanced credentials automatically handle token caching
  4. Permission Configuration: Ensure proper API permissions are configured for OBO scenarios
  5. Workload Identity Setup: Use workload identity federation instead of storing secrets in containers
  6. Service Connection Security: Protect Azure Pipelines service connection credentials
  7. Multi-Tenant Awareness: Carefully configure tenant access for cross-tenant scenarios
  8. Error Handling: Implement comprehensive error handling for complex authentication flows

Security Considerations

  1. User Assertion Validation: Validate user assertions before using them in OBO flows
  2. Downstream Permissions: Ensure downstream services are configured to accept OBO tokens
  3. Token Lifetime: Consider token lifetime implications in chained authentication scenarios
  4. Audit Logging: Enable audit logging for advanced authentication flows
  5. Network Security: Secure network communications between services in OBO scenarios

Install with Tessl CLI

npx tessl i tessl/maven-com-azure--azure-identity

docs

advanced-authentication-flows.md

authorization-code-authentication.md

azure-developer-cli-authentication.md

azure-pipelines-authentication.md

client-assertion-authentication.md

configuration-and-utilities.md

credential-chaining.md

default-azure-credential.md

developer-tool-credentials.md

environment-credential.md

index.md

interactive-user-authentication.md

managed-identity-credential.md

service-principal-authentication.md

shared-token-cache-authentication.md

username-password-authentication.md

visual-studio-code-authentication.md

tile.json