Source: Microsoft — Passwordless connections for Azure services and Azure Identity client libraries.
Table of Contents: Golden Rule · Authentication by Environment · Why Not DefaultAzureCredential in Production? · Production Patterns · Local Development Setup · Environment-Aware Pattern · Security Checklist · Further Reading
Use managed identities and Azure RBAC in production. Reserve DefaultAzureCredential for local development only.
| Environment | Recommended Credential | Why |
|---|---|---|
| Production (Azure-hosted) | ManagedIdentityCredential (system- or user-assigned) |
No secrets to manage; auto-rotated by Azure |
| Production (on-premises) | ClientCertificateCredential or WorkloadIdentityCredential |
Deterministic; no fallback chain overhead |
| CI/CD pipelines | AzurePipelinesCredential / WorkloadIdentityCredential |
Scoped to pipeline identity |
| Local development | DefaultAzureCredential |
Chains CLI, PowerShell, and VS Code credentials for convenience |
- Unpredictable fallback chain — walks through multiple credential types, adding latency and making failures harder to diagnose.
- Broad surface area — checks environment variables, CLI tokens, and other sources that should not exist in production.
- Non-deterministic — which credential actually authenticates depends on the environment, making behavior inconsistent across deployments.
- Performance — each failed credential attempt adds network round-trips before falling back to the next.
using Azure.Identity;
var credential = Environment.GetEnvironmentVariable("AZURE_FUNCTIONS_ENVIRONMENT") == "Development"
? new DefaultAzureCredential() // local dev — uses CLI/VS credentials
: new ManagedIdentityCredential(); // production — deterministic, no fallback chain
// For user-assigned identity: new ManagedIdentityCredential("<client-id>")import { DefaultAzureCredential, ManagedIdentityCredential } from "@azure/identity";
const credential = process.env.NODE_ENV === "development"
? new DefaultAzureCredential() // local dev — uses CLI/VS credentials
: new ManagedIdentityCredential(); // production — deterministic, no fallback chain
// For user-assigned identity: new ManagedIdentityCredential("<client-id>")import os
from azure.identity import DefaultAzureCredential, ManagedIdentityCredential
credential = (
DefaultAzureCredential() # local dev — uses CLI/VS credentials
if os.getenv("AZURE_FUNCTIONS_ENVIRONMENT") == "Development"
else ManagedIdentityCredential() # production — deterministic, no fallback chain
)
# For user-assigned identity: ManagedIdentityCredential(client_id="<client-id>")import com.azure.identity.DefaultAzureCredentialBuilder;
import com.azure.identity.ManagedIdentityCredentialBuilder;
var credential = "Development".equals(System.getenv("AZURE_FUNCTIONS_ENVIRONMENT"))
? new DefaultAzureCredentialBuilder().build() // local dev — uses CLI/VS credentials
: new ManagedIdentityCredentialBuilder().build(); // production — deterministic, no fallback chain
// For user-assigned identity: new ManagedIdentityCredentialBuilder().clientId("<client-id>").build()DefaultAzureCredential is ideal for local dev because it automatically picks up credentials from developer tools:
- Azure CLI —
az login - Azure Developer CLI —
azd auth login - Azure PowerShell —
Connect-AzAccount - Visual Studio / VS Code — sign in via Azure extension
import { DefaultAzureCredential } from "@azure/identity";
// Local development only — uses CLI/PowerShell/VS Code credentials
const credential = new DefaultAzureCredential();Detect the runtime environment and select the appropriate credential. The key principle: use DefaultAzureCredential only when running locally, and a specific credential in production.
Tip: Azure Functions sets
AZURE_FUNCTIONS_ENVIRONMENTto"Development"when running locally. For App Service or containers, use any environment variable you control (e.g.NODE_ENV,ASPNETCORE_ENVIRONMENT).
import { DefaultAzureCredential, ManagedIdentityCredential } from "@azure/identity";
function getCredential() {
if (process.env.NODE_ENV === "development") {
return new DefaultAzureCredential(); // picks up az login / VS Code creds
}
return process.env.AZURE_CLIENT_ID
? new ManagedIdentityCredential(process.env.AZURE_CLIENT_ID) // user-assigned
: new ManagedIdentityCredential(); // system-assigned
}- Use managed identity for all Azure-hosted apps
- Never hardcode credentials, connection strings, or keys
- Apply least-privilege RBAC roles at the narrowest scope
- Use
ManagedIdentityCredential(notDefaultAzureCredential) in production - Store any required secrets in Azure Key Vault
- Rotate secrets and certificates on a schedule
- Enable Microsoft Defender for Cloud on production resources