Key Vault Was Still Trusting an Identity — The VM Was Already Gone
The virtual machine had been deleted.
Its workload was supposed to be gone with it.
But while reviewing Key Vault access, Agent Foskett found an identity that appeared to belong to the old system.
The compute resource was gone.
The identity trail was not.
Was this simply historical telemetry?
A surviving user-assigned managed identity?
Or an authorization path nobody had cleaned up?

The Resource Was Gone. The Authorization Story Needed Rebuilding.
System-assigned and user-assigned managed identities have different lifecycles. Before calling an identity orphaned, Agent Foskett had to establish exactly which type existed and what Azure still knew about it.
The first assumption could have ruined the investigation
A user-assigned managed identity is different. It exists as its own Azure resource and can survive after a VM using it has been removed.
So Agent Foskett did not begin by calling the identity orphaned.
He began by identifying exactly what kind of principal the evidence referred to.
Start with the Key Vault access evidence
AZKVAuditLogs for recent data-plane operations and preserved the caller identity context available in the records.- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
AZKVAuditLogs
| where TimeGenerated > ago(30d)
| where OperationName has_any
("SecretGet", "KeyGet", "CertificateGet")
| project TimeGenerated,
OperationName,
ResultType,
CallerIpAddress,
Identity,
ResourceId,
CorrelationId
| order by TimeGenerated descA principal ID is more useful than a friendly name
Agent Foskett preserved the immutable identity identifiers present in the telemetry and compared them with the managed identities and service principals that still existed in the tenant.
The investigation followed the principal — not the label someone remembered.
Was the identity still present?
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
Resources
| where type =~
"microsoft.managedidentity/userassignedidentities"
| extend PrincipalId =
tostring(properties.principalId),
ClientId =
tostring(properties.clientId)
| project name,
resourceGroup,
subscriptionId,
PrincipalId,
ClientId,
idNot finding a user-assigned identity changed the hypothesis
Instead he checked the timestamp of the Key Vault event, the deletion timeline and whether the telemetry was historical.
An old access event can survive longer than the resource that generated it.
When was the VM actually deleted?
AzureActivity for deletion activity involving the known VM resource ID or name.- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
let VmName = "prod-app-vm01";
AzureActivity
| where TimeGenerated > ago(90d)
| where ResourceProviderValue =~
"MICROSOFT.COMPUTE"
| where Resource has VmName
| where OperationNameValue has
"virtualMachines/delete"
| project TimeGenerated,
Caller,
CallerIpAddress,
ResourceGroup,
ResourceId,
ActivityStatusValue,
CorrelationId
| order by TimeGenerated ascThe timestamps separated history from impossible behaviour
If access occurred after deletion, Agent Foskett had a different problem to solve.
For a system-assigned identity, post-deletion authentication using that deleted identity would conflict with its expected lifecycle and demand careful validation of the principal mapping and timestamps.
For a user-assigned identity, continued authentication could be entirely possible because the identity may have survived and been attached or used elsewhere.
The identity type determines what “after deletion” actually means.
Was the surviving identity attached somewhere else?
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
let IdentityName = "uami-prod-app";
Resources
| where isnotempty(identity)
| where tostring(identity) has IdentityName
| project name,
type,
resourceGroup,
subscriptionId,
identity,
id
| order by type ascThen inspect what still authorised the principal
Agent Foskett therefore checked the vault's authorization model before deciding where to look for the surviving permission.
Do not hunt an RBAC assignment when the vault is using access policies — and do not assume an access policy exists when RBAC is enabled.
Check Azure RBAC assignments for the principal
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
let PrincipalId =
"11111111-2222-3333-4444-555555555555";
AuthorizationResources
| where type =~
"microsoft.authorization/roleassignments"
| where tostring(properties.principalId)
=~ PrincipalId
| project roleAssignmentId = id,
scope = tostring(properties.scope),
roleDefinitionId =
tostring(properties.roleDefinitionId),
principalType =
tostring(properties.principalType)A surviving role assignment was not proof of recent use
It does not establish that the principal actually exercised that permission.
Agent Foskett kept authorization evidence and access telemetry separate.
Permission answers “could it?”
Audit evidence answers “did it?”
What if the vault used access policies?
The important question remained the same: did an authorization path still reference an identity that no longer matched the expected workload lifecycle?
Different authorization models. Same investigative requirement: identify exactly what still trusts the principal.
Could another resource now be using the same user-assigned identity?
The VM might have been deleted correctly while the user-assigned identity remained intentionally or accidentally available to another workload.
If Key Vault access continued after the VM deletion, the investigation shifted from “ghost VM” to “where is this identity being used now?”
The deleted VM was history. The surviving identity was the live asset.
Build the managed-identity timeline
What Agent Foskett checked
What the evidence can and cannot prove
AzureActivity can establish Azure control-plane events such as resource deletion. Azure Resource Graph can describe current resources and authorization objects.None of those sources alone proves malicious intent.
And current-state queries cannot reconstruct an object that has already been deleted unless historical telemetry or another retained source preserves its details.
Separate historical access, current identity state and current authorization. Then connect them with time.
The lesson
That did not automatically mean every identity and authorization object associated with the workload had disappeared with it.
Agent Foskett identified the principal, established the managed-identity type, reconstructed the VM deletion and checked what still authorised or used the identity.
When a workload disappears, verify the identity lifecycle separately from the resource lifecycle.
Related investigations
Final thought
Identity and authorization require their own investigation.
A system-assigned identity follows its resource lifecycle. A user-assigned identity does not have to.
So when old workload evidence points toward a managed identity, do not assume the identity vanished just because the VM did.
Find the principal. Establish the identity type. Reconstruct the deletion. Then determine what still trusts — and what may still be using — that identity.
The VM was gone.
The authorization path still had a story to tell.
Follow the evidence. Build the timeline.
The Logs Already Knew! 🔎

