Advanced authentication flows handle complex scenarios including credential chaining, on-behalf-of authentication, workload identity, and Azure Pipelines integration. These credentials enable sophisticated authentication patterns for enterprise applications and specialized deployment environments.
Combine multiple credentials with fallback logic, allowing custom authentication chains beyond DefaultAzureCredential.
/**
* Enables multiple `TokenCredential` implementations to be tried in order
* until one of the getToken methods returns an access token
*/
class ChainedTokenCredential implements TokenCredential {
constructor(...sources: TokenCredential[]);
getToken(scopes: string | string[], options?: GetTokenOptions): Promise<AccessToken>;
}Usage Examples:
import {
ChainedTokenCredential,
ClientSecretCredential,
ManagedIdentityCredential,
AzureCliCredential
} from "@azure/identity";
// Custom credential chain
const credential = new ChainedTokenCredential(
new ManagedIdentityCredential(), // Try managed identity first
new ClientSecretCredential(tenantId, clientId, clientSecret), // Then service principal
new AzureCliCredential() // Finally try Azure CLI
);
// Different chain for different environments
const developmentChain = new ChainedTokenCredential(
new AzureCliCredential(),
new ClientSecretCredential(tenantId, clientId, clientSecret)
);
const productionChain = new ChainedTokenCredential(
new ManagedIdentityCredential(),
new ClientSecretCredential(tenantId, clientId, clientSecret)
);
// Use based on environment
const credential = process.env.NODE_ENV === 'production'
? productionChain
: developmentChain;
// Get token - chain will try each credential until one succeeds
const token = await credential.getToken("https://graph.microsoft.com/.default");Authenticate on behalf of a user using an existing user token. This enables middle-tier applications to call downstream APIs while maintaining the user's identity.
/**
* Enables authentication to Microsoft Entra ID using the On-Behalf-Of flow
* Exchange a user's access token for an access token for a different resource
*/
class OnBehalfOfCredential implements TokenCredential {
constructor(options: OnBehalfOfCredentialSecretOptions);
constructor(options: OnBehalfOfCredentialCertificateOptions);
constructor(options: OnBehalfOfCredentialAssertionOptions);
getToken(scopes: string | string[], options?: GetTokenOptions): Promise<AccessToken>;
}
interface OnBehalfOfCredentialOptions extends TokenCredentialOptions {
/**
* The tenant ID of the application
*/
tenantId: string;
/**
* The client ID of the application
*/
clientId: string;
/**
* The user assertion (access token) to exchange
*/
userAssertionToken: string;
/**
* Allows specification of additional tenant IDs for multi-tenant authentication
*/
additionallyAllowedTenants?: string[];
}
interface OnBehalfOfCredentialSecretOptions extends OnBehalfOfCredentialOptions {
/**
* The client secret of the application
*/
clientSecret: string;
}
interface OnBehalfOfCredentialCertificateOptions extends OnBehalfOfCredentialOptions {
/**
* Path to the certificate file
*/
certificatePath: string;
/**
* Password for the certificate (if encrypted)
*/
certificatePassword?: string;
/**
* Option to include x5c header
*/
sendCertificateChain?: boolean;
}
interface OnBehalfOfCredentialAssertionOptions extends OnBehalfOfCredentialOptions {
/**
* Function that returns a client assertion JWT
*/
getAssertion: () => string;
}Usage Examples:
import { OnBehalfOfCredential } from "@azure/identity";
// On-behalf-of with client secret
const credential = new OnBehalfOfCredential({
tenantId: "12345678-1234-1234-1234-123456789012",
clientId: "12345678-1234-1234-1234-123456789012",
clientSecret: "your-client-secret",
userAssertionToken: "user-access-token-from-request"
});
// On-behalf-of with certificate
const certificateCredential = new OnBehalfOfCredential({
tenantId: tenantId,
clientId: clientId,
certificatePath: "/path/to/certificate.pem",
userAssertionToken: userToken,
sendCertificateChain: true
});
// On-behalf-of with custom assertion
const assertionCredential = new OnBehalfOfCredential({
tenantId: tenantId,
clientId: clientId,
userAssertionToken: userToken,
getAssertion: () => {
// Return custom JWT assertion
return generateClientAssertion();
}
});
// Use in middle-tier service
async function callDownstreamApi(userToken: string) {
const credential = new OnBehalfOfCredential({
tenantId: process.env.AZURE_TENANT_ID!,
clientId: process.env.AZURE_CLIENT_ID!,
clientSecret: process.env.AZURE_CLIENT_SECRET!,
userAssertionToken: userToken
});
const token = await credential.getToken("https://graph.microsoft.com/.default");
// Use token to call Microsoft Graph on behalf of the user
}Authenticate using workload identity in Kubernetes environments. This provides secure, keyless authentication for applications running in Azure Kubernetes Service (AKS).
/**
* Enables authentication to Microsoft Entra ID using workload identity for Kubernetes
* Uses federated identity credentials configured in Azure AD
*/
class WorkloadIdentityCredential implements TokenCredential {
constructor(options?: WorkloadIdentityCredentialOptions);
getToken(scopes: string | string[], options?: GetTokenOptions): Promise<AccessToken>;
}
interface WorkloadIdentityCredentialOptions extends TokenCredentialOptions {
/**
* The tenant ID of the application
*/
tenantId?: string;
/**
* The client ID of the application (user-assigned managed identity or app registration)
*/
clientId?: string;
/**
* Path to the projected service account token file
*/
tokenFilePath?: string;
}Usage Examples:
import { WorkloadIdentityCredential } from "@azure/identity";
// Basic workload identity (uses environment variables)
const credential = new WorkloadIdentityCredential();
// With explicit configuration
const explicitCredential = new WorkloadIdentityCredential({
tenantId: "12345678-1234-1234-1234-123456789012",
clientId: "12345678-1234-1234-1234-123456789012",
tokenFilePath: "/var/run/secrets/azure/tokens/azure-identity-token"
});
// Get token
const token = await credential.getToken("https://graph.microsoft.com/.default");Kubernetes Configuration:
# Kubernetes ServiceAccount configuration
apiVersion: v1
kind: ServiceAccount
metadata:
annotations:
azure.workload.identity/client-id: "12345678-1234-1234-1234-123456789012"
name: workload-identity-sa
namespace: defaultEnvironment Variables:
AZURE_TENANT_ID - The tenant IDAZURE_CLIENT_ID - The client IDAZURE_FEDERATED_TOKEN_FILE - Path to the projected token fileAuthenticate using Azure Pipelines service connections for CI/CD scenarios.
/**
* Enables authentication to Microsoft Entra ID using an Azure Pipelines service connection
* Uses the SYSTEM_ACCESSTOKEN and service connection configuration
*/
class AzurePipelinesCredential implements TokenCredential {
constructor(
tenantId: string,
clientId: string,
serviceConnectionId: string,
systemAccessToken: string,
options?: AzurePipelinesCredentialOptions
);
getToken(scopes: string | string[], options?: GetTokenOptions): Promise<AccessToken>;
}
interface AzurePipelinesCredentialOptions extends TokenCredentialOptions {
/**
* The Azure DevOps organization URL
*/
organizationUrl?: string;
}Usage Examples:
import { AzurePipelinesCredential } from "@azure/identity";
// Azure Pipelines authentication
const credential = new AzurePipelinesCredential(
"12345678-1234-1234-1234-123456789012", // tenant ID
"12345678-1234-1234-1234-123456789012", // client ID
"service-connection-id", // service connection ID
process.env.SYSTEM_ACCESSTOKEN!, // system access token
{
organizationUrl: "https://dev.azure.com/your-org"
}
);
// Get token for Azure resource access
const token = await credential.getToken("https://management.azure.com/.default");Pipeline Configuration:
# Azure Pipelines YAML
variables:
- name: azureServiceConnection
value: 'your-service-connection-name'
steps:
- task: AzureCLI@2
displayName: 'Run Azure CLI with Workload Identity'
inputs:
azureSubscription: $(azureServiceConnection)
scriptType: 'bash'
scriptLocation: 'inlineScript'
inlineScript: |
# Your application will use AzurePipelinesCredential automatically
node your-app.jsAuthenticate using environment variables. This credential is typically used as part of DefaultAzureCredential but can be used independently.
/**
* Enables authentication to Microsoft Entra ID using client secret or certificate
* details configured in environment variables
*/
class EnvironmentCredential implements TokenCredential {
constructor(options?: EnvironmentCredentialOptions);
getToken(scopes: string | string[], options?: GetTokenOptions): Promise<AccessToken>;
}
interface EnvironmentCredentialOptions extends TokenCredentialOptions {
/**
* Allows specification of additional tenant IDs for multi-tenant authentication
*/
additionallyAllowedTenants?: string[];
}Usage Examples:
import { EnvironmentCredential } from "@azure/identity";
// Uses environment variables for configuration
const credential = new EnvironmentCredential();
// With additional configuration
const credentialWithOptions = new EnvironmentCredential({
additionallyAllowedTenants: ["*"]
});
// Get token
const token = await credential.getToken("https://graph.microsoft.com/.default");import {
ChainedTokenCredential,
ManagedIdentityCredential,
ClientSecretCredential,
AzureCliCredential
} from "@azure/identity";
// Different credentials based on environment
function createCredential(): TokenCredential {
if (process.env.AZURE_CLIENT_SECRET) {
// Production with service principal
return new ClientSecretCredential(
process.env.AZURE_TENANT_ID!,
process.env.AZURE_CLIENT_ID!,
process.env.AZURE_CLIENT_SECRET
);
} else if (process.env.KUBERNETES_SERVICE_HOST) {
// Kubernetes with workload identity
return new WorkloadIdentityCredential();
} else {
// Development with fallback chain
return new ChainedTokenCredential(
new AzureCliCredential(),
new ManagedIdentityCredential()
);
}
}// Different credentials for different resources
const graphCredential = new ChainedTokenCredential(
new ManagedIdentityCredential(),
new ClientSecretCredential(tenantId, clientId, clientSecret)
);
const keyVaultCredential = new ChainedTokenCredential(
new ManagedIdentityCredential({ clientId: keyVaultClientId }),
new ClientCertificateCredential(tenantId, clientId, certificatePath)
);
// Use appropriate credential for each service
const graphToken = await graphCredential.getToken("https://graph.microsoft.com/.default");
const kvToken = await keyVaultCredential.getToken("https://vault.azure.net/.default");import {
ChainedTokenCredential,
AuthenticationError,
CredentialUnavailableError
} from "@azure/identity";
const resilientCredential = new ChainedTokenCredential(
new ManagedIdentityCredential(),
new ClientSecretCredential(tenantId, clientId, clientSecret),
new AzureCliCredential()
);
try {
const token = await resilientCredential.getToken(scopes);
} catch (error) {
if (error instanceof AuthenticationError) {
// All credentials failed with authentication errors
console.error("Authentication failed:", error.message);
} else if (error instanceof CredentialUnavailableError) {
// All credentials were unavailable
console.error("No credentials available:", error.message);
}
}