A few days ago, I was talking about secrets and how to handle them in Azure, and of course, I easily got into a discussion regarding Managed Identities. Another friend joined, but the problem was that that person was not a developer. That was when things got complicated.
Explain the problem
If you’ve worked with public clouds long enough, you’ve probably handled more secrets than you’d like to admit. Connection strings in app settings. Client secrets in pipelines. Certificates that expire quietly and break production at the worst possible time.
Managed identities exist to remove that entire type of problem, and once you understand how they actually work, it becomes hard to justify not using them for Azure workloads.
The real problem with secrets
Secrets are fragile by design. They need to be created, stored, rotated, secured, copied, and eventually revoked. Every step adds operational overhead, and in every step, you get the chance for something to go wrong. Secrets get checked into source control, pasted into tickets, or left unrotated for years because “it still works.” Let’s not even talk about what happens when a team member leaves the company or project.
Ok, but what’s managed identity?
A managed identity is an identity in Microsoft Entra ID (ex Azure AD), managed directly by Azure. The “flow” is that you create an identity in Entra, you tie it to a lifecycle (or not) of a resource, and it handles the credentials behind the scenes. No client secrets, no passwords, no certificates, nothing that you can copy, export or leak. It asks Azure for a token, and Azure vouches for the resource’s identity. That’s the entire story.
Yeah, but there are 2 types
Yes, there are 2 types of managed identities: system-assigned and user-assigned. Here is where initially I got blocked with my explanations, but after a while, I remembered a video I watched from here in which Varun Karandikar explained it beautifully. In short words (but I strongly suggest watching the video), he says to think about a car (your azure resource) that needs to get into a garage (access another resource). You can use your keys (username and password), which you can lose, you can use a button on the mirror (a system assigned managed identity) which will go away when you sell your car (the system assigned will be deleted when the azure resource gets deleted), or you can have a remote control (user asigned managed identity), that will remain even if you sell the car (and you could use it for other “devices”, in our case other Azure services also).
Ok, but from the tech point of view?
Here, the other dev interrupted and asked for technical clarifications.
System-assigned managed identity
- It is enabled directly on the resource, so it is created and deleted with that resource
- One identity per resource
TL.DR. If the app goes away, the identity goes away. No cleanup required.
User-assigned managed identity
- It is created separately from the Azure resource
- Can be “attached” to multiple resources
- It has its own lifecycle.
TL.DR. This makes sense when you need an identity to be shared across resources or deployments.
My humble opinion
If you don’t have a clear reason for a user-assigned identity, use system-assigned.
Explain the magic
There are 4 steps in which your authentication is done
- Your Azure resource requests an access token from Azure
- Azure validates the resource’s identity
- Entra ID issues a short-lived access token
- The resource uses that token to access the target service
Role assignments, not secrets, so your app never sees any credentials. It simply requests a token scoped to a specific resource, retrieves it, and that’s it. All of this happens over standard OAuth 2.0 flows, so nothing proprietary.
Where did I use it in practice
Of course, this question appeared pretty fast.
- Accessing Azure Key Vault — instead of storing access keys and client secrets, I assigned a managed identity to the app, granted a role to the Key Vault and requested secrets directly using the identity
- Azure SQL — no SQL passwords, no connection string with secrets, just tie the authentication to the Entra id and role assignments.
- The same for Azure Storage, ServiceBus, Azure Monitor, and I could go on and on.
Sounds simple
Yeah, but it only sounds like that. When you do it for the first time, it can be pretty hard. After that, it’s simple. You can’t even imagine how many times I messed up and added wrong scopes, forgot about permissions, and got denied errors.
Things to consider
- Managed identity gives access automatically — well, not really! You need role assignments. Identity and authorization are 2 separate things.
- User-assigned identities are more secure — again, not really. They are just different. Apples and oranges are both fruits, but not the same. Overusing them often makes environments harder to understand.
- It won’t work locally — well, it does, but you need to have the same rights as the identity (use your developer identity locally). The SDK handles the differences. You can see it as it’s a little bit different, but it’s not an argument not to use them. You shouldn’t hardcode secrets just because you’re running code on your laptop.
When managed identities are not the right tool
- When you need to authenticate across multiple cloud providers. You can do some kind of “magic”, but I wouldn’t “force” it.
- When your app runs outside Azure. Let’s use tools from Azure when we talk about Azure. This is not a Swiss Army Knife.
- The target system doesn’t support Entra ID. Github, Stripe, SendGrid, Twilio, Datadog, New Relic and I could go on and on. Here I’d include the legacy and self-hosted apps. If you have a REST API on-prem and have an API Key, just use that one, and do not over-complicate things.
Conclusion
Use managed identities if you answer with yes to the next 3 questions:
- Does your workload run in Azure?
- The target system trusts Entra ID?
- Does the protocol support token-based authentication?
If your answer to one of those is no, go back to secrets, certificates, or some other credential. Don’t overcomplicate your life.
Comments
Loading comments…