CAMPUX Cloud Bootcamp
Field notes · Identity
Managed identity vs service principal

Managed identity vs service principal: stop putting secrets in your app

By Victor Thomson16 July 20266 min read

They are the same kind of identity underneath — but one hands you a password to guard, and the other never does. Here is the honest difference, when to reach for each, and why the interview answer is almost always "managed identity."

Here is a scene that has leaked more Azure credentials than any hacker: an app needs to read a storage account, so someone pastes a connection string into a config file, the config file goes into Git, and eight months later that string is still valid and still in the history. The whole reason both service principals and managed identities exist is to end that scene. They are two answers to the same question — how does a piece of software prove who it is to Azure? — and the difference between them is entirely about who holds the keys.

Both are the same thing underneath

In Microsoft Entra ID, a human logs in as a user principal. An application logs in as a service principal — the security object that says "this app is allowed to do these things in this tenant." You grant it roles, it gets tokens, it accesses resources. That is the identity every non-human workload uses.

So where does managed identity fit? This is the sentence that makes the whole topic click: a managed identity is a special type of service principal that Azure creates and manages for you. Microsoft's own documentation lists "managed identity" as one of the three kinds of service principal. It is not a different species of thing. It is a service principal whose credentials you are never given, never see, and never have to rotate — because the platform does all of that on your behalf.

That single distinction — do you hold a credential, or does Azure? — is the entire decision.

The service principal: an identity with a password you own

When you register an application in Entra ID, you get an application object (the global blueprint) and a service principal (the local instance in your tenant that actually gets permissions). To let that app authenticate, you add a credential: a client secret or a certificate. Now your app can present its client ID plus that secret, get a token, and go.

The catch is right there in the last sentence. You created that secret, so you have to store it somewhere the app can read it, keep it out of source control, and rotate it before it expires. Every one of those is a place where things go wrong. A client secret is a password — and passwords in config files are exactly the leak we started with.

Service principals are still the right tool when there is no Azure resource to attach an identity to — most classically, code running outside Azure: a script on someone's laptop, an on-premises server, or historically a CI runner. They also back multi-tenant applications, where the same app object gets a service principal in every customer's tenant.

The managed identity: an identity with no password anyone holds

A managed identity is what you use when your code runs on an Azure resource — a Virtual Machine, App Service, Function, Container App, or an AKS pod through workload identity. You flip it on, and Azure quietly creates a service principal for that resource and manages its credentials invisibly. Your code asks the local Azure identity SDK for a token, the platform hands one over, and there is never a secret in your config, your Key Vault, or your Git history — because there is no secret to put anywhere.

Managed identities come in two flavours, and knowing the difference is a common interview follow-up:

The tell in an interview

If someone asks "how does your app authenticate to Key Vault?" and the answer contains the word secret, there is usually a better answer. "A system-assigned managed identity with the Key Vault Secrets User role" says you understand that the strongest credential is the one that does not exist.

So which do you use?

The rule is short: if your code runs on an Azure resource that supports managed identity, use a managed identity. No secret to leak, nothing to rotate, nothing to accidentally commit. You only fall back to a service principal with its own secret or certificate when nothing Azure-hosted is there to carry the identity for you — and even then, the modern move is to avoid the secret entirely.

That last point is worth naming, because it dissolves the most common "but I have to use a service principal" case: GitHub Actions deploying to Azure. You do not store a client secret for that anymore. You federate the pipeline to Azure with OpenID Connect, so the workflow trades a short-lived GitHub token for an Azure token at run time. Same identity model, zero stored secrets — a running gh secret list that returns nothing is the goal.

The strongest credential is the one that does not exist to be stolen.

The mental model to keep

Picture a building. A service principal is a contractor with a physical key card you cut, handed over, and now have to remember to deactivate when they leave. A managed identity is an employee whose badge the building's own security desk issues, rotates, and revokes automatically — you just say who they are and what floors they can reach. Both open doors. Only one leaves a key card in a drawer for someone else to find.

Get comfortable saying that out loud, assign roles to the identity rather than sprinkling secrets around, and you have removed an entire category of breach from your architecture before you have written a line of application code.

Further reading — the Microsoft docs
Drilled in Class 9 — Service Principals & Managed Identity. Next note: Private endpoints, explained without the fog →