“We moved it to managed identity, so there are no credentials for an attacker to steal.”
That is a good reason to remove a secret. It is not a reason to stop the review.
If a compromised process can ask for a token as its assigned identity, the useful question becomes what that identity can do next. Maybe the answer is one read against one storage account. Maybe the same identity is attached to three workloads and can reach a shared service with much broader authority. Those are not the same incident, even if both designs say “managed identity” on the diagram.
The identity does not become a pivot because the feature is weak. It becomes one when the workload’s legitimate authority and its reachable dependencies combine into a route to something else.
The Mental Model
A managed identity changes how a workload obtains credentials. It does not decide what the workload is authorized to do, which other resources can answer it, or whether network controls will let it connect.
Think of the pivot as the join between three edges:
- Credential edge: can this compromised process request a token for the identity?
- Authority edge: which operations can that principal perform, at what scope, and through which service?
- Reachability edge: can the process contact the target or an intermediary that can act on the target?
The path matters only when its edges meet. A role assignment alone is not proof of network access. A reachable endpoint alone is not proof of data authorization. A token is not a map of every action the service will permit.
Secretless is a credential property. Contained is an outcome you still have to prove.
How It Really Works
First establish which identity is in play
Start in the workload’s execution context. Do not infer the principal from a deployment template or the identity settings on a resource that may not host the process. Record the actual principal ID and whether it is system-assigned or user-assigned.
That distinction affects the blast radius. A system-assigned managed identity is tied to the lifecycle of its Azure resource. A user-assigned identity is a separate resource and can be assigned to more than one Azure resource. Sharing one may simplify provisioning and role management. It also means compromise of any attached workload may expose the same identity authority, subject to the service’s identity-use behavior.
That isn’t a blanket argument against user-assigned identities. It is a design choice with a boundary attached. If a shared identity is used, reviewers should be able to name every workload that can use it and explain why those workloads belong in one compromise domain.
Follow the permission to the operation
“Reader” and “Contributor” often get discussed as though role names fully describe data access. They do not. For a Blob read, distinguish management-plane permissions on the Storage account from the data-plane authorization evaluated for the blob operation. A successful control-plane inventory is not proof that the application can read a particular object; a successful token request is not either.
Write down the operation the application needs. For example: read one known blob, list a container, or write an object. Then inspect the applicable role definition, assignment scope, inheritance, and conditions for the principal that actually makes the request. If the workload uses a broker or an intermediary service, follow that edge too. The workload may not have direct permission to the final data and still be able to invoke something that does.
Use a harmless test object and the same credential-selection behavior as the application. An engineer’s interactive sign-in can confirm that the engineer has access. It cannot establish what the managed identity can do.
Reachability is the other half
Once you know the target operation and principal, test where the workload can connect. Resolve the target hostname from the workload’s resolver context, record the address the client uses, and test the required protocol and port from the same source.
For a VM-based workload, Azure Network Watcher’s Connection troubleshoot can help diagnose supported TCP or ICMP connectivity to supported destinations. It can surface route, DNS, and network-security issues. It does not evaluate the Blob data permission or prove that application code uses the same identity and hostname. Treat it as one instrument in the investigation, not the answer.
If the data path includes a private endpoint, inspect its DNS resolution and network policy as part of the same path. A private address may reduce public exposure; it does not tell you how much data the identity is allowed to read after connection.
Real-World Impact
Imagine two applications attached to the same user-assigned identity. One processes uploaded images. The other performs a back-office reconciliation job. Both can obtain a token; both can reach the same Storage account.
If the identity has read access to every container because that was the easiest role to assign, a compromise in the lower-trust image processor can inherit authority intended for the reconciliation job. The pivot is not “managed identity was compromised” in isolation. It is the shared identity, broad operation scope, and reachable storage path taken together.
Now compare two fixes. Removing the identity from every workload may stop the immediate path, but also stop valid processing. Blocking all traffic to Storage can produce the same operational result. A narrower change might separate the identities, reduce data permissions to the required scope, and constrain the route. Which is right depends on whether the workloads genuinely share a trust boundary and what the application must do.
The test should make that choice visible. Record:
| Evidence | Question it answers |
|---|---|
| Principal ID from the workload | Which identity actually requested access? |
| Role definition, scope, inheritance, conditions | What operation is potentially authorized? |
| Target operation and response | Did this request succeed as that identity? |
| Resolver and client-used address | Where did the process direct the request? |
| Source, destination, protocol, port | Could this workload establish the tested connection? |
| Other attached workloads | Who shares the identity boundary? |
This is a review artifact, not a claim that every other path has been found. If there are multiple attached resources, network paths, or downstream services, show what was excluded and why.
Gotchas and Edge Cases
The term “pivot” can make ordinary service access sound more dramatic than the evidence supports. Keep the claim narrow: a pivot exists when a foothold can use authority or a reachable intermediary to move into a consequence-bearing operation. The word does not prove an attacker did so.
Sharing can be a feature and a risk at once
User-assigned identities can be useful when several resources need consistent authorization or a workload is recycled while its permissions remain stable. The same arrangement couples those resources’ compromise consequences. Count the attached workload resources and identify their owners before calling the identity “shared infrastructure.”
Scope is not just the assignment written on the resource
An assignment at a parent scope may apply lower down. Group membership and conditions can further affect effective access. Conversely, a role that sounds broad may not include the exact data action under review. Inspect role definitions and effective assignment paths; do not turn a role display name into a conclusion.
Token acquisition is not a permanent grant
Token handling and service authorization are distinct from network connectivity. Existing tokens, service-side authorization checks, caches, and established connections can make before/after behavior differ from the moment a control-plane change is submitted. Do not claim an exact revocation interval unless current service documentation and a measured test support it.
Intermediaries complicate the graph
A workload may reach a queue, function, or deployment service that then accesses the target with its own identity. The initial workload may have no direct Storage role, but that does not make the path irrelevant. Document the intermediary’s identity, authorization, and trust boundary instead of drawing an unexplained line from the application to the final data.
Best Practices
Begin with the operation, not the identity type. Ask what this workload must do, then prove the principal, authority, and destination used for that action. If multiple workloads share an identity, make the coupling an explicit architecture decision with named owners.
When a path is too broad, compare changes by what edge they remove. Separate identities when the workloads do not share a trust boundary. Narrow data permissions when the role exceeds the required operation. Restrict network paths when the source should not contact the target. Avoid using a network block to disguise excessive authority or an identity change to paper over an unintended route.
Finally, repeat the useful operation after the change and test one nearby operation that should remain denied. Capture exact request context and explain any propagation uncertainty. The goal is not to make every request fail. It is to preserve the needed dependency while removing the unnecessary pivot.