Skip to content

This tool is not affiliated with, endorsed by or sponsored by Microsoft Corporation. Azure, Microsoft Azure and Microsoft Defender for Cloud are trademarks of the Microsoft group of companies. Other names are trademarks of their respective owners.

Azure subscription compromised? An incident response guide

Think your Azure subscription is compromised? Which logs to preserve first, the operations that betray an attacker, and how to go from Activity Log to verdict.

Published on 8 min read

TL;DR. Treat "is our Azure subscription compromised?" as three questions: which identity acted, what it did in the control plane (Activity Log), and what data it touched (Key Vault, storage and flow logs). Export everything before retention bites — the Activity Log keeps 90 days. Look first for a short list of operations: roleAssignments/write, elevateAccess/action, runCommand/action, listAccountSas/action, accessPolicies/write, diagnosticSettings/delete. If you can only do one thing today, export the Activity Log of every subscription involved and drop it into the Azure Forensics analyzer, which runs in your browser.

Most Azure incidents I see start the same way: someone notices a cost spike, a Defender for Cloud alert, or a role assignment nobody remembers creating. The temptation is to open the portal and click around. Resist it for ten minutes. Clicking does not preserve evidence, and the portal views are filtered by default. This guide is the order of operations I use.

What "compromised" means in Azure

An Azure subscription has two planes, and attackers use both.

PlaneWhat happens thereWhere it is loggedLogged by default?
Control plane (Azure Resource Manager)Create, change, delete resources; assign roles; run commands on VMs; mint SAS tokensActivity LogYes, 90 days
Data planeRead a secret, download a blob, open a TCP connectionResource logs (Key Vault AuditEvent, StorageRead), NSG / VNet flow logsNo — needs a diagnostic setting
IdentitySign-ins, MFA, new app secrets, consentMicrosoft Entra ID logsYes, retention depends on licence

Microsoft Learn is explicit about the split: the Activity Log records control-plane operations, while resource logs capture data-plane operations and "aren't collected by default". If Key Vault logging was never enabled, nobody can tell you which secrets were read. That is the first honest limit of any Azure investigation; the limitations article goes deeper.

Step 1: preserve before you investigate

Two things destroy Azure evidence: time and the attacker.

  • Time. Azure retains Activity Log events for 90 days and then deletes them. If the intrusion started 80 days ago, you have ten days.
  • The attacker. Deleting a diagnostic setting stops a resource from sending logs from that moment on. It is one of the first things a careful intruder does (defense evasion in Azure).

So, before anything else:

  1. Export the Activity Log of every subscription in scope for the suspected period plus at least a week before it. The week before is the baseline that tells normal from abnormal.
  2. Copy the storage-account containers that diagnostic settings write to: insights-activity-logs, insights-logs-auditevent, insights-logs-storageread, insights-logs-networksecuritygroupflowevent, insights-logs-flowlogflowevent.
  3. Export Log Analytics tables if they exist: AzureActivity, AzureDiagnostics (Key Vault), StorageBlobLogs.
  4. Export the tenant-level (Directory Activity) log too: elevateAccess lands there, not in the subscription log.

The exact commands, including the az monitor activity-log list default that silently returns only 50 events, are in how to export the Activity Log and resource logs.

Step 2: find the operations that matter

The Activity Log of a busy subscription is mostly deployments and tag writes. Attack activity hides in a handful of operation names. These are the ones the analyzer's rules key on, grouped by what the attacker is trying to do:

GoalOperation (Activity Log unless noted)MITRE ATT&CKRead more
EscalateMicrosoft.Authorization/roleAssignments/write (Owner, User Access Administrator, Contributor to a non-human identity)T1098.003Role assignment abuse
Escalate to every subscriptionMicrosoft.Authorization/elevateAccess/actionT1078.004same
Execute on VMsMicrosoft.Compute/virtualMachines/runCommand/action, extensions/write (Custom Script)T1651Run Command attacks
Steal secretsaccessPolicies/write, then SecretGet (Key Vault log)T1555.006Key Vault audit logs
Steal datalistAccountSas/action, listKeys/action, then GetBlob (storage log)T1530SAS and exfiltration
Copy disks outdisks/beginGetAccess/action, snapshots/writeT1537Run Command attacks
HidediagnosticSettings/delete, Microsoft.Security/pricings/write (Free tier), locks/deleteT1562.008Defense evasion
PersistAutomation runbooks and webhooks, federated credentials on managed identitiesT1098.001Managed identity abuse
MineVMs in regions never used before, outbound flows to mining-pool portsT1496Flow logs

None of these is malicious on its own. A platform team assigns roles every week. What makes them suspicious is who (a service principal that normally deploys a web app), from where (an IP never seen during the baseline), when (02:14 UTC on a Sunday) and what follows (a Run Command three minutes later).

This is not theoretical. Microsoft's write-up of Storm-0501's cloud-based ransomware lists elevateAccess/action, roleAssignments/write, listkeys/action and locks/delete among the operations used before data was exfiltrated and resources deleted.

Step 3: pivot on the identity

Every Activity Log event carries the caller and, in the JSON exports, the token claims: object ID, application ID, and for a managed identity an xms_mirid claim pointing at the VM or app it belongs to. Once one suspicious event is found, pivot:

  • All events by the same caller, across all subscriptions, over the whole retention window. First appearance matters more than the loudest event.
  • All events from the same IP address, whatever the caller. Attackers reuse infrastructure across stolen identities.
  • The same identity in Key Vault and storage logs, where it shows up as an object ID or, for SAS access, as a token hash.
  • The same IP in flow logs, where a compromised VM talks back to it.

The identity itself — how the secret of a service principal leaked, who consented to what — is an Entra ID question. That investigation lives in the sibling tool m365forensics.com, which covers sign-ins, audit logs and app credentials.

Step 4: contain in the right order

Containment in Azure is mostly identity work. The analyzer's remediation checklist orders it roughly like this:

  1. Credentials. Rotate the secrets and certificates of the service principals involved; revoke sessions of the users. A rotated secret does not invalidate an access token already issued, so expect a short tail of activity.
  2. Role assignments. Remove every assignment created during the incident, and the User Access Administrator assignment at root scope (/) if elevateAccess was used.
  3. VMs. Isolate with a deny-all NSG, snapshot disks for forensics, then rebuild from a known-good image. A VM that ran an attacker's script is not "cleaned" by deleting the script.
  4. Secrets and keys. Rotate everything read from the affected vaults, and both storage account keys (this invalidates account and service SAS tokens).
  5. Logging. Restore deleted diagnostic settings and Defender plans, then protect them with a lock or Azure Policy.

Microsoft's incident response overview for Azure is the official reference for the broader process.

Step 5: get a first verdict fast

A first-pass triage should take minutes, not a week of KQL. The Azure Forensics analyzer reads Activity Log exports (portal CSV, az CLI / REST JSON, Log Analytics, storage-account export), Key Vault AuditEvent, StorageBlobLogs, NSG and VNet flow logs and Defender for Cloud alerts. It applies 35 documented rules and returns a verdict:

  • Compromised: at least two high-severity findings, or one critical.
  • Suspicious: at least one medium or high finding.
  • Clean: nothing above low — which only means nothing matched in the logs you provided.

Everything runs in a Web Worker as WebAssembly: no upload. The step-by-step guide shows how to read the findings, timeline and entity pivot, and the fictional incident walkthrough shows a complete chain on synthetic data.

FAQ

What is the first thing to do when an Azure subscription is compromised?

Preserve the logs before they age out (the Activity Log keeps 90 days), then contain: rotate the credentials of the principals involved, remove role assignments they created, and isolate affected VMs. Investigate in parallel, not afterwards.

Does the Activity Log show who read my Key Vault secrets or storage blobs?

No. The Activity Log records control-plane operations through Azure Resource Manager. Secret reads and blob downloads are data-plane operations, recorded only in Key Vault and storage resource logs, and only if a diagnostic setting was enabled before the incident.

Where do I investigate how the attacker got the credentials?

In Microsoft Entra ID: sign-in logs, audit logs, new application secrets and consents. Azure resource logs show what the identity did with its access, not how it was obtained.

Further reading

Related articles

Azure Activity Log retention is 90 days and resource logs are off by default. What each Azure log cannot tell you, and how to write an honest conclusion.
A fictional Azure breach investigated end to end: leaked app secret, self-assigned role, Run Command, stolen managed identity token, Key Vault and blob theft.
How attackers abuse Azure service principals and managed identities: leaked secrets, IMDS token theft, federated credentials, runbooks, and the log signals.

This tool is not affiliated with, endorsed by or sponsored by Microsoft Corporation. Azure, Microsoft Azure and Microsoft Defender for Cloud are trademarks of the Microsoft group of companies. Other names are trademarks of their respective owners.