Skip to content

Latest commit

 

History

History
130 lines (95 loc) · 6.51 KB

File metadata and controls

130 lines (95 loc) · 6.51 KB

Azure Authentication Best Practices

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

Golden Rule

Use managed identities and Azure RBAC in production. Reserve DefaultAzureCredential for local development only.

Authentication by Environment

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

Why Not DefaultAzureCredential in Production?

  1. Unpredictable fallback chain — walks through multiple credential types, adding latency and making failures harder to diagnose.
  2. Broad surface area — checks environment variables, CLI tokens, and other sources that should not exist in production.
  3. Non-deterministic — which credential actually authenticates depends on the environment, making behavior inconsistent across deployments.
  4. Performance — each failed credential attempt adds network round-trips before falling back to the next.

Production Patterns

.NET

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>")

TypeScript / JavaScript

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>")

Python

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>")

Java

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()

Local Development Setup

DefaultAzureCredential is ideal for local dev because it automatically picks up credentials from developer tools:

  1. Azure CLIaz login
  2. Azure Developer CLIazd auth login
  3. Azure PowerShellConnect-AzAccount
  4. 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();

Environment-Aware Pattern

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_ENVIRONMENT to "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
}

Security Checklist

  • 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 (not DefaultAzureCredential) 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

Further Reading