CalSync — Automate Outlook Calendar Colors

Auto-color-code events for your team using rules. Faster visibility, less admin. 10-user minimum · 12-month term.

CalSync Colors is a service by CPI Consulting

In this blog post Securely use Managed Identity in Production and Azure CLI Locally we will show a simple, safe way to authenticate apps in Azure without storing secrets, while keeping local development fast.

The idea is straightforward. In production, your app uses Azure Managed Identity to get tokens automatically from Azure Active Directory (Entra ID). Locally, developers sign in with the Azure CLI, and the same code picks up those credentials. One code path. Two environments. No secrets.

This pattern keeps operations secure and predictable, and it keeps developers unblocked. Let’s walk through the why, the tech behind it, and concrete steps to implement it.

The technology behind it

Managed Identity

Managed Identity (MI) is a first-class identity for Azure resources. Azure hosts and rotates its credentials. Your code requests an access token for a resource (like Key Vault or Storage) and Azure returns it if the identity has the right role. There are two types:

  • System-assigned: Tied to a single resource (VM, App Service, Function, Container App). Lifecycle follows the resource.
  • User-assigned: A reusable identity you can attach to multiple resources. Good for multi-app scenarios or AKS with Workload Identity.

OAuth 2.0 and tokens

Under the hood, Azure AD issues OAuth 2.0 access tokens for resource-specific scopes (for example, https://vault.azure.net/.default for Key Vault). The Azure SDKs handle token acquisition and refresh.

DefaultAzureCredential

The Azure SDKs offer DefaultAzureCredential, which tries multiple credential sources in order. In Azure, it finds Managed Identity. On a developer machine, it falls back to the Azure CLI (after checking environment variables and other developer tools). This lets the same code work everywhere.

Azure CLI for local development

Developers run az login to authenticate. The Azure SDK reads the CLI’s cached token via the AzureCliCredential step inside DefaultAzureCredential. No secrets, no config files with passwords.

Architecture at a glance

  • Production: App with Managed Identity → Azure AD issues tokens → App calls Azure services (Key Vault, Storage, SQL, etc.).
  • Local: Developer logs in with Azure CLI → Same code uses DefaultAzureCredential → App calls the same Azure services.

Production setup with Managed Identity

1) Choose identity type

  • Small, single app: system-assigned MI is simplest.
  • Multiple apps or AKS: user-assigned MI gives you reuse and separation of duties.

2) Create a user-assigned identity (optional)

Note the clientId (for code) and principalId (for role assignments).

3) Enable Managed Identity on your compute

  • App Service (system-assigned):
    az webapp identity assign -g <rg> -n <app-name>

  • App Service (user-assigned):
    az webapp identity assign -g <rg> -n <app-name> --identities <mi-resource-id>

  • VM or VMSS:
    az vm identity assign -g <rg> -n <vm-name>

  • Azure Container Apps:
    az containerapp identity assign -g <rg> -n <app-name> --system-assigned

  • AKS workloads: Use Azure AD Workload Identity with a user-assigned MI (recommended over deprecated AAD Pod Identity). Configure ServiceAccount, federated identity, and binding to the MI.

4) Assign least-privilege roles

Give the identity data-plane roles on the target resources. Examples:

  • Key Vault: Key Vault Secrets User
  • Storage (Blobs): Storage Blob Data Contributor

Prefer RBAC over legacy Key Vault access policies for new deployments.

Local development with Azure CLI

1) Sign in and select the right subscription

If you work across tenants, add --tenant <tenant-id> to az login.

2) Run the app with DefaultAzureCredential

DefaultAzureCredential will try Managed Identity in Azure. Locally, it will use your Azure CLI sign-in (unless you explicitly exclude it). That means the code below is the same in both places.

Code examples using DefaultAzureCredential

.NET (C#) — Key Vault secret and Blob listing

Python — Key Vault secret

Node.js — Blob listing

Environment-specific controls

  • Force-disable CLI in prod: use the SDK options shown above (ExcludeAzureCliCredential/exclude_cli_credential).
  • User-assigned MI selection: set AZURE_CLIENT_ID or pass the client ID via SDK options.
  • Configuration: store endpoints (Key Vault URI, Storage endpoint) in app settings or Azure App Configuration, not in code.

Step-by-step checklist

  1. Pick identity type (system-assigned or user-assigned).
  2. Enable MI on your compute.
  3. Assign least-privilege roles on each Azure resource your app needs.
  4. Use DefaultAzureCredential in code. No secrets, no connection strings.
  5. Locally: az login, set the right subscription, run the app.
  6. In production: optionally exclude CLI credential and pin user-assigned MI via client ID.
  7. Observe logs and verify access; adjust roles if you see 403s.

Common pitfalls and how to fix them

  • 403 Forbidden to a service: The MI lacks the data-plane role on that resource. Assign the correct role at the smallest scope.
  • It works locally but fails in prod: You may be using your personal CLI permissions. Exclude CLI in prod and ensure the MI has roles.
  • Multiple identities on one resource: Provide the user-assigned MI’s client ID to the SDK so it knows which one to use.
  • Key Vault using access policies: Prefer RBAC for new deployments to match how other services authorize.
  • Wrong subscription: Check az account show and set the intended subscription before testing locally.
  • AKS pods need identity: Use Azure AD Workload Identity with a user-assigned MI mapped to a Kubernetes ServiceAccount.

Security and operations tips

  • Least privilege everywhere. Avoid broad roles like Contributor for app identities.
  • Separate identities per app or boundary. This simplifies audits and incident response.
  • Log token usage paths. The Azure SDKs can emit helpful telemetry and request IDs.
  • Automate role assignments in IaC (Bicep/Terraform) to keep environments consistent.
  • Rotate nothing: one of the benefits of MI is Azure rotates credentials for you.

Putting it all together

This pattern keeps production secure and local development smooth. In production, Managed Identity eliminates secrets and centralizes authorization in Azure AD. Locally, Azure CLI lets developers authenticate with their own accounts while reusing the same code path. The glue is DefaultAzureCredential.

At CloudProinc.com.au we recommend adopting this approach as your default for new services. Start small: enable MI on one app, grant a single data-plane role, and switch the SDK to DefaultAzureCredential. You’ll get immediate security wins with minimal code changes.


Discover more from CPI Consulting -Specialist Azure Consultancy

Subscribe to get the latest posts sent to your email.