Managed identities or service principals with secrets: choosing and auditing
Managed identities remove the most common problem with workload identities: a secret stored somewhere. They do not remove the risk that comes with the rights they are given, and they are often left out of privilege reviews.
What a managed identity is
A managed identity is a special service principal, created and managed by Azure, whose credentials are never exposed. The resource that uses it (virtual machine, App Service, Function, container, automation account) requests a token from the platform's local endpoint, and Azure handles rotation. There is no secret to store, no certificate to renew and no expiry to track.
The trade-off is that a managed identity can only be used from an Azure resource it is attached to, or from a server connected through Azure Arc. An application hosted elsewhere needs an app registration, ideally with workload identity federation rather than a secret.
System-assigned or user-assigned
| System-assigned | User-assigned | |
|---|---|---|
| Lifecycle | Tied to the resource, deleted with it | Standalone Azure resource |
| Sharing | A single resource | Can be attached to several resources |
| Typical use | Isolated workload | A fleet of resources sharing the same rights, rights prepared in advance |
A user-assigned identity is convenient, but every resource carrying it can obtain its tokens. Shared between a sensitive application and a poorly protected test machine, it exposes the former through the latter. Who can attach a user-assigned identity to a resource is also an Azure permissions question worth checking.
The secret has not gone, it has moved. Anyone able to run code on the resource, or change its code, can obtain a token for its managed identity. Contributors on a Function or an Automation account therefore effectively hold the rights of its identity.
Rights to audit
A managed identity can receive three families of rights, which need to be reviewed together:
- Azure RBAC roles: Owner or Contributor on a subscription or management group, User Access Administrator, key vault access;
- Application permissions on Microsoft Graph and other APIs: these cannot be assigned from the portal, only through PowerShell or the API, which makes them less visible;
- Entra ID directory roles, which can be assigned to a managed identity just like any service principal.
In the tenants we audit, we often find an Automation account whose managed identity holds broad Graph permissions for a user management script, while many people are contributors on the account.
When to keep a service principal with a secret
A classic service principal is still needed for applications outside Azure where federation is not possible, for some third-party software, or for a multi-tenant application. In those cases, prefer a certificate, limit owners and document where the credential lives. A service principal with a secret running inside an Azure resource, on the other hand, is an obvious candidate for migration.
Inventory method
- List service principals of the managed identity type in Entra ID;
- For each one, retrieve its app role assignments and directory role assignments;
- Retrieve its Azure RBAC assignments across all subscriptions and management groups;
- Identify the resources carrying it and the people who can run code on them.
What an audit checks
- Managed identities holding high Azure roles or sensitive Graph permissions.
- User-assigned identities shared between resources of different sensitivity.
- The people able to run code on resources that carry privileged identities.
- Service principals with secrets that could be replaced by a managed identity.