How Azure CLI handles your tokens and what you might be ignoring
Running az login
feels like magic. A browser pops up, you pick an account, and from then on, everything just works. No more passwords, no more pop-ups. It’s frictionless and we all love it. But convenience always has a price, and in this case, the price is understanding what the CLI actually does with your tokens behind the scenes.
What really happens when you log in
Azure CLI doesn’t stash your password somewhere clever. It does a full OAuth 2.0 handshake, picking up two pieces of gold: an access token and a refresh token. The access token is short-lived; the refresh token isn’t. The refresh token can quietly mint new access tokens whenever needed, which is why your login survives reboots, coffee breaks, and even mild existential crises.
Under the hood, Azure CLI leans on the Microsoft Authentication Library (MSAL). On Windows, MSAL stores tokens in your profile, usually in
C:\Users\<username>\.azure\msal_token_cache.bin
and encrypts them using DPAPI, bound to your Windows account.
Good to know though: Anything running under your user context can decrypt and use those tokens. That’s not a vulnerability per se, but how single sign-on (SSO). But it also means any shady script, extension, or compromised process running as you can impersonate you in Azure.
To mitigate risks, admins should enable Continuous Access Evaluation to kill risky sessions instantly.
Convenience that quietly overstays its welcome
Azure CLI keeps refreshing your tokens in the background, which means you get the infinite it still works experience. On your personal laptop, fine. On a shared VM, lab PC, or reused developer image: Absolutely not fine.
A forgotten .azure
folder or copied user profile can carry valid tokens into the next session. And since refresh tokens can mint new access tokens, anyone finding that cache gets to enjoy being you in Azure for as long as the token lives.
The fix is boring but effective: az logout
before leaving a machine. Better yet, nuke the .azure
folder if you’re done for good, especially before imaging VMs or sharing environments.
Device code flow & the silent broker
Obviously, there’s more than one way to sign in. The usual browser login is fine, but users will also meet device code flow and WAM (Web Account Manager) sessions.
Device code flow means you go to https://microsoft.com/devicelogin
and paste a code. Simple, but dangerously easy to abuse. If someone tricks you into entering a code, they just stole a token and your identity.
WAM goes even deeper, wiring the CLI straight into your Windows session. That’s again slick, invisible, and automatically grants other MSAL-based apps (VS Code, PowerShell, Visual Studio) access to the same credentials, as they all share the same cache. That’s why signing in once magically authenticates them all. It’s also why signing out of one doesn’t guarantee the others are clean 🤯.
If one tool or extension is compromised, your tokens are fair game. Restrict profile access, isolate testing environments, and don’t treat .azure
as harmless clutter.
Want guardrails? Use Conditional Access. Enforce MFA, block device code flow on unmanaged machines, and set token lifetimes that actually expire.
Scopes, tenants, and why does my script suddenly fail?
Not every token is equal. Each is tied to a specific resource (scope). By default, az account get-access-token
gets you one for Azure Resource Manager. Need Microsoft Graph or Key Vault? Ask explicitly.
Mixing tenants and subscriptions makes this messier. Old tokens hang around, new ones join the party, and suddenly you’re running commands in the wrong tenant. Always check az account show
before doing anything destructive. (Ask me how I know.)
Automation ≠ your personal login
User tokens don’t belong in pipelines. Ever. No, also not even for your cute little POC. We know those land in production. Always. Use Service principals, Managed identities, or Workload identity federation instead. In case you need a refresher:
- Service principals are fine-grained, auditable, secret-rotatable identities. Don’t know how to rotate a secret? I got you!
- Managed identities means no secrets at all; Azure handles the handshake for you. My preferred way!
- Workload identity federation for external platforms (like GitHub Actions) that authenticate to Entra ID without storing tokens.
Short version: Stop letting your personal refresh tokens sit in some build agent’s cache.
The bottom line
The Azure CLI is doing exactly what it should: making identity easy. The problem is that easy and secure don’t always overlap.
Know where your tokens live. Know how long they last. Separate human and machine identities. And stop trusting convenience to make security decisions for you.
You May Also Like
How Dev Proxy teaches you to make your apps more resilient
I added Microsoft Dev Proxy to my Mermaid → Dataverse converter expecting a quick resilience check—and ended up discovering everything that was quietly broken. From long-running rollbacks and Azure …
Building Azure functions that never store secrets — ever
Build Azure Functions that never store secrets by using Managed Identity. Request tokens from IMDS or the App Service identity endpoint and assign Microsoft Graph app roles at deploy time with …
Round Robin assignments in Power Automate
Tired of assigning tasks manually? Try a round robin setup in Power Automate! With SharePoint as memory and your Teams group as the source, this flow rotates assignments automagically 🦄.