Business Challenge
Post #34 ended on the problem an app registration hands you: a credential to store, rotate and eventually leak. Managed identities are the answer, and the pitch is genuinely as good as it sounds — you don't need to manage credentials, and better, credentials aren't even accessible to you. Post #31 established the other half: managed identities can be used at no extra cost.
So the interesting question is not whether to use them. It is which of the two kinds to use, and that choice is usually presented as a lifecycle preference — do you want the identity to die with the resource, or outlive it? That framing is accurate and almost useless, because it makes the decision sound reversible and local. It is neither.
The choice actually determines three things that have nothing to do with lifecycle: whether your deployment can create role assignments before the resources that need them, how many role assignments you will be maintaining at scale, and — the one almost nobody plans for — how long it takes to change a workload's permissions once it is running.
That last one is the subject of this post, because the documented answer overturns a pattern this series has recommended twice.
User-assigned managed identities, which are provisioned independently from compute and can be assigned to multiple compute resources, are the recommended managed identity type for Microsoft services. And in the best-practice guidance: user-assigned managed identities are more efficient in a broader range of scenarios than system-assigned managed identities. This is unusually direct for Azure documentation, which normally presents options as equals. The rest of the post is why.
Architecture
The two types, precisely
Both are service principals — the managed identity type from post #34, the one that doesn't have an associated app object. The difference is who owns the object's life.
System-assigned. A service principal of a special type is created in Microsoft Entra ID for the identity. The service principal is tied to the lifecycle of that Azure resource. When the Azure resource is deleted, Azure automatically deletes the service principal for you. And it is exclusive: by design, only that Azure resource can use this identity to request tokens from Microsoft Entra ID. A useful detail for auditing — the name of the system-assigned service principal is always the same as the name of the Azure resource it's created for.
User-assigned. You may also create a managed identity as a standalone Azure resource, whose service principal is managed separately from the resources that use it, and which can be used by multiple resources. Its life cycle is independent and it must be explicitly deleted — including the case that catches people: you need to manually delete a user-assigned identity when it's no longer required, even if no resources are associated with it.
And the two are not exclusive. Resources that support managed identities can have both a system-assigned identity and one or more user-assigned identities, which is the escape hatch when one workload needs both a shared permission set and a few of its own.
The deployment-ordering problem, which is the practical argument
This is the reason to reach for user-assigned first, and it is a sequencing problem rather than a preference.
User-assigned identities and their role assignments can be configured in advance of the resources that require them, so users who create the resources only require the access to assign a user-assigned identity, without the need to create new identities or role assignments.
The alternative fails in a specific, familiar way: as system-assigned identities are created and deleted along with the resource, role assignments can't be created in advance. This sequence can cause failures while deploying infrastructure if the user creating the resource doesn't also have access to create role assignments.
Read that against posts #18 and #24. Creating a role assignment requires Microsoft.Authorization/roleAssignments/write — which is User Access Administrator or Owner, not Contributor. So a system-assigned design quietly requires that whoever runs the deployment holds permission-granting rights. A user-assigned design lets a platform team pre-create the identity and its grants, and hands application teams a resource they may merely attach. That is the separation of duties the landing zone of post #30 was built for, and the identity type is what enables or prevents it.
The arithmetic
Microsoft's worked example: four virtual machines that each need access to the same two targets. With a system-assigned identity each, that is 4 × 2 = 8 role assignments to create, review and eventually clean up. With one shared user-assigned identity, two.
Post #18 established that role assignments are a per-scope budget. This is that budget being spent four times over for no additional security — the four machines do the same job and hold the same permissions either way. And the scaling is worse than it looks, because if you attempt to create multiple managed identities in a short space of time — for example, deploying multiple virtual machines each with their own system-assigned identity — you may exceed the rate limit for Microsoft Entra object creations, and the request fails with an HTTP 429 error.
Which makes system-assigned identities actively unsuitable for ephemeral compute, and the documentation says so, adding a detail worth knowing: while a deleted system-assigned identity is no longer accessible by any resource, it counts towards your limit until fully purged after 30 days. A scale-set that cycles nodes is creating directory objects that persist for a month after the node is gone.
Why This Architecture Holds Up
Because the 24-hour cache overturns the group pattern
Post #19 argued that you should assign roles to groups rather than users, and post #32 carried the same reasoning into Entra. For managed identities, the documentation says do not.
The mechanism: group and role membership travel as claims inside the access token, so a change only takes effect when a new token is issued. For a person that is bounded — the token lifetime is 1 hour by default, and they can always sign out and back in. For a managed identity, neither is true:
Managed identity tokens on the other hand are cached by the underlying Azure infrastructure for performance and resiliency purposes: the back-end services for managed identities maintain a cache per resource URI for around 24 hours. This means that it can take several hours for changes to a managed identity's group or role membership to take effect. Today, it isn't possible to force a managed identity's token to be refreshed before its expiry.
Removing a compromised workload from a privileged group is not a containment action. The identity keeps the permission for as many as several hours, and there is no supported way to shorten that. If you need the access gone now, you have to remove the thing the token is presented to — the role assignment at the target, the resource itself, or the identity — rather than the membership that granted it.
Microsoft's recommended alternative is the elegant part, and it reframes what a user-assigned identity is for:
To ensure that changes to permissions for managed identities take effect quickly, we recommend that you group Azure resources using a user-assigned managed identity with permissions applied directly to the identity, instead of adding to or removing managed identities from a Microsoft Entra group that has permissions.
Because a user-assigned managed identity can be used like a group — it can be assigned to one or more Azure resources to use it. So the identity is the group. Attaching and detaching resources changes who holds the permissions without changing any token claim, and the permission set lives directly on the identity where an edit takes effect on the next token rather than the next day. The assignment operation is itself governable, using the Managed Identity Contributor and Managed Identity Operator roles.
That is a genuinely different mental model from the human side of the directory, and it is the single most useful thing in this post: for workload identity, membership is expressed by attaching resources to an identity, not by putting identities into a group.
Because deleting an identity leaves its permissions behind
An asymmetry in the same family as #34's delete-and-restore: role assignments aren't automatically deleted when either system-assigned or user-assigned managed identities are deleted. These role assignments should be manually deleted so the limit of role assignments per subscription isn't exceeded.
The residue is visible but easy to ignore — such assignments are displayed with "Identity not found" when viewed in the portal and carry an ObjectType of Unknown. Post #23 described orphaned role assignments after a resource move; this is the same debris from a different cause, and it accumulates against the budget of post #18 rather than against anything anyone is watching.
The consequence for system-assigned identities is worth stating plainly, because it is the reverse of their supposed advantage: deleting the resource deletes the identity, which is tidy, and leaves every role assignment that identity held, which is not. "The permissions go away with the resource" is true of the identity object and false of the grants.
Because the identity's permissions belong to whoever can run code
The security note in the guidance generalises a principle this phase keeps rediscovering:
When an Azure resource, such as an Azure Logic App or a Virtual Machine, is assigned a managed identity, all the permissions granted to the managed identity are now available to the Azure resource — and therefore if a user has access to install or execute code on this resource, then the user has access to all the identities assigned/associated to the Azure resource.
And the second half, which is the one that makes identity assignment a privileged operation in its own right: if Alice has permissions to assign the managed identity herself, she can assign it to a different Azure resource and have access to all the permissions available to the managed identity.
Post #33 found that whoever can write an attribute controls a dynamic group's membership. This is the same shape: whoever can execute on a resource holds its identities' permissions, and whoever can attach an identity can move those permissions to a resource they control. Neither person appears in any list of role holders — which is exactly why both keep being missed.
The practical reading: a role that permits running code on a resource — Contributor on a VM, the ability to edit a Logic App — is an implicit grant of everything that resource's identities can do. The guidance says as much: consider if the role being assigned to the user can install or run code on the resource, and if yes only assign that role if the user really needs it.
Because there are still two good reasons to choose system-assigned
The recommendation is a default, not an absolute, and the two exceptions are both about wanting the identity to be indistinguishable from the resource:
- Audit logging. If you need to log which specific resource carried out an action, rather than which identity, use a system-assigned identity. A shared user-assigned identity is, by construction, an ambiguous actor in a log — you know the identity, not which of its resources used it. Where attribution matters more than administrative overhead, that settles it.
- Permissions lifecycle management. If you require that the permissions for a resource be removed along with the resource, use a system-assigned identity. With the caveat from above: what disappears is the identity, and the role assignments still need removing by hand.
Both are real requirements, and both are narrower than the instinct that produces system-assigned identities by default — which is usually that enabling one is a single toggle on a resource you were creating anyway.
Key Architecture Decisions
| Decision | What to do | Why |
|---|---|---|
| Default type | User-assigned, unless a stated exception applies | They are the recommended managed identity type for Microsoft services and more efficient in a broader range of scenarios. |
| Separation of duties in deployment | Pre-create the identity and its role assignments; let app teams attach it | System-assigned role assignments can't be created in advance, so the deployer needs permission-granting rights. |
| Changing a workload's permissions | Apply permissions directly to the identity; do not use Entra groups | The managed identity token cache is around 24 hours and it isn't possible to force a managed identity's token to be refreshed. |
| Grouping workloads | Use one user-assigned identity as the group; attach and detach resources | A user-assigned managed identity can be used like a group, and attaching changes no token claim. |
| Containing a compromised workload | Remove the role assignment or the resource, not the group membership | Membership changes can take several hours to take effect and cannot be accelerated. |
| Ephemeral or scaled compute | Never one system-assigned identity per instance | Rapid creation risks HTTP 429, and deleted identities count against the limit until fully purged after 30 days. |
| Deleting any managed identity | Remove its role assignments as an explicit step | They aren't automatically deleted, survive as Identity not found, and consume the #18 budget. |
| Granting access to a resource that runs code | Treat it as granting everything that resource's identities hold | Anyone who can install or execute code there has access to all the identities assigned to it. |
| Who may attach identities | Govern Managed Identity Contributor and Managed Identity Operator deliberately | Whoever can assign an identity can move its permissions to a resource they control. |
| When attribution matters | System-assigned, and accept the overhead | A shared identity cannot tell a log which specific resource carried out an action. |
Closing Thought
The pattern this phase keeps producing is that the Entra object model and the Azure resource model share vocabulary and disagree about mechanics. Containers that do not inherit. Rules that write privilege. Applications whose permissions live in an object you did not edit. This post adds the sharpest instance yet: groups, the mechanism the whole directory is built around, are the wrong tool for the identities that do most of the work.
Not because they fail, but because they are slow in a way that has no remedy. A human can sign out. A workload cannot, and the platform will not do it for them. So the guidance inverts the usual advice — put the permissions on the identity, and move resources rather than memberships — and in doing so turns the user-assigned managed identity into something more interesting than a lifecycle option. It becomes the unit of authorisation for everything that runs.
Which reframes the choice one last time. System-assigned asks "should this identity die with this resource?" User-assigned asks "which workloads should share a permission set, and who may join them to it?" The second is an architecture question. The first is a cleanup preference, and it is the reason so many estates are holding eight role assignments where two would do.
#36 takes the same identity to where it is actually consumed — VMs, App Service, Functions and AKS — where the endpoint, the token acquisition and the failure modes differ by host, and where AKS does something different enough to need its own treatment.
Comments