Skip to main content

Incident Response

TSC mapping: CC7.3 (Incident evaluation), CC7.4 (Incident response), CC7.5 (Recovery from incidents)

SOC 2 auditors do not expect zero incidents. They expect a documented, tested process for detecting, classifying, containing, and recovering from incidents — and evidence that the process was followed.


1. Detection Pipeline​

Connect Defender for Cloud, Sentinel, and Azure Monitor into an automated alert pipeline.

Defender for Cloud Alert
Microsoft Sentinel Incident → Action Group / Logic App → PagerDuty / Teams / Email
Azure Monitor Alert

Create an Action Group for security notifications​

# Create an action group targeting the security team
az monitor action-group create \
--resource-group rg-security \
--name ag-security-oncall \
--short-name SecOncall \
--action email security-lead [email protected] \
--action sms oncall-sms +15555550100

Route Defender for Cloud HIGH alerts to an Action Group​

# Create a security alert rule for Defender HIGH/CRITICAL alerts
az rest --method PUT \
--uri "https://management.azure.com/subscriptions/<sub>/providers/Microsoft.Security/automations/route-high-alerts?api-version=2019-01-01-preview" \
--body '{
"location": "eastus",
"properties": {
"isEnabled": true,
"scopes": [{"scopePath": "/subscriptions/<sub>"}],
"sources": [{
"eventSource": "Alerts",
"ruleSets": [{
"rules": [{
"propertyJPath": "Severity",
"propertyType": "String",
"expectedValue": "High",
"operator": "Equals"
}]
}]
}],
"actions": [{
"actionType": "LogicApp",
"logicAppResourceId": "/subscriptions/<sub>/resourceGroups/rg-security/providers/Microsoft.Logic/workflows/logic-security-alert"
}]
}
}'

Route Microsoft Sentinel incidents to Teams via Logic App​

# Create a Logic App playbook for Sentinel incident notification
az logic workflow create \
--resource-group rg-security \
--name logic-sentinel-alert \
--definition @sentinel-teams-alert-playbook.json \
--location eastus

2. Incident Classification​

SeverityDefender for Cloud scoreExampleResponse SLA
P1 — Critical9–10Compromised credentials, cryptominer detected, data exfiltration30 minutes
P2 — High7–8Brute force attack, anomalous sign-in from new country, key vault access spike2 hours
P3 — Medium4–6Policy violations, misconfiguration alerts, exposed storage accounts24 hours
P4 — Low1–3Informational alerts, expected behaviour flagged as anomalousNext business day

3. Incident Response Runbook​

Document and maintain this runbook. Auditors will ask to see it and may ask responders to walk through it.

Step 1 — Contain​

# Isolate a compromised VM: detach its NIC and attach it to an isolation subnet
# First, get the NIC ID
NIC_ID=$(az vm show --resource-group rg-prod --name vm-compromised --query "networkProfile.networkInterfaces[0].id" -o tsv)

# Apply a quarantine NSG (deny all inbound and outbound)
az network nsg create \
--resource-group rg-security \
--name nsg-quarantine

# Associate the quarantine NSG with the NIC
az network nic update \
--ids $NIC_ID \
--network-security-group nsg-quarantine

# Disable a compromised Entra ID account immediately
az ad user update \
--account-enabled false

# Revoke all active sessions and refresh tokens for a user
az rest --method POST \
--uri "https://graph.microsoft.com/v1.0/users/<user-id>/revokeSignInSessions"

# Disable a compromised service principal
az ad sp update \
--id <service-principal-id> \
--set "accountEnabled=false"

Step 2 — Investigate​

# Query Entra ID audit logs for a specific user's activity (last 24 hours)
az monitor log-analytics query \
--workspace $WORKSPACE_ID \
--analytics-query "
AuditLogs
| where TimeGenerated > ago(24h)
| where InitiatedBy.user.userPrincipalName == '[email protected]'
| project TimeGenerated, OperationName, Result, TargetResources
| order by TimeGenerated desc
" --output table

# Query Azure Activity Log for operations from a specific IP
az monitor log-analytics query \
--workspace $WORKSPACE_ID \
--analytics-query "
AzureActivity
| where TimeGenerated > ago(24h)
| where CallerIpAddress == '<suspicious-ip>'
| project TimeGenerated, OperationNameValue, Caller, ResourceGroup, Level
| order by TimeGenerated desc
" --output table

# Get a Defender for Cloud alert detail
az security alert show \
--resource-group rg-prod \
--name <alert-name> \
--location eastus \
--query "{Name:alertName,Severity:severity,Description:description,RemediationSteps:remediationSteps}"

# Query Key Vault audit logs for unusual access
az monitor log-analytics query \
--workspace $WORKSPACE_ID \
--analytics-query "
AzureDiagnostics
| where ResourceType == 'VAULTS'
| where TimeGenerated > ago(24h)
| where OperationName in ('SecretGet', 'KeyDecrypt', 'KeyUnwrap')
| project TimeGenerated, identity_claim_oid_g, requestUri_s, ResultSignature
| order by TimeGenerated desc
" --output table

Step 3 — Eradicate​

  • Remove malicious resources (VMs, app registrations, role assignments, runbooks created by attacker).
  • Revoke all active sessions via revokeSignInSessions.
  • Reset credentials for affected service principals; rotate Key Vault secrets and certificates.
  • Patch or redeploy the affected system from a known-good IaC state.
  • Verify no persistent access mechanisms remain (new admin accounts, new OAuth app consents, forwarding rules).
# Rotate a compromised Key Vault secret
az keyvault secret set \
--vault-name kv-soc2-prod \
--name compromised-secret \
--value "<new-strong-secret>"

# Remove a malicious role assignment
az role assignment delete \
--assignee <malicious-principal-id> \
--role Contributor \
--scope /subscriptions/<subscription-id>

Step 4 — Recover​

# Restore an Azure SQL Database to a point in time
az sql db restore \
--dest-name prod-db-restored \
--resource-group rg-prod \
--server sql-prod \
--name prod-db \
--time "2024-01-15T03:00:00Z"

# Restore a VM from an Azure Backup recovery point
az backup restore restore-azurevm \
--resource-group rg-prod \
--vault-name rsv-prod \
--container-name iaasvmcontainerv2;rg-prod;vm-prod \
--item-name vm;iaasvmcontainerv2;rg-prod;vm-prod \
--restore-mode OriginalLocation \
--rp-name <recovery-point-name>

# Redeploy infrastructure from Terraform (IaC — preferred)
terraform apply -target=module.vm_prod -auto-approve

Step 5 — Post-incident review​

Complete a post-incident review within 5 business days. Retain for audit evidence.

Incident ID: INC-YYYY-NNN
Date/Time detected:
Date/Time resolved:
Severity: P1 / P2 / P3 / P4

Timeline:
HH:MM — Alert triggered (Sentinel incident / Defender alert / manual detection)
HH:MM — On-call notified
HH:MM — Incident declared / severity assigned
HH:MM — Containment action taken
HH:MM — Root cause identified
HH:MM — System restored
HH:MM — Incident closed

Root cause:

Impact (systems affected, data involved, customers notified Y/N):

Containment actions taken:

Eradication actions taken:

Recovery actions taken:

Customer notification required? (Y/N)
If yes, date/method of notification:

Action items (owner, due date):
1.
2.

4. Microsoft Sentinel — Incident Management​

Sentinel provides a structured, auditable incident lifecycle — with built-in severity classification, assignment, investigation graph, and timeline — that directly generates evidence for SOC 2 CC7.3–CC7.5.

# List open Sentinel incidents (severity: High or Critical)
az rest --method GET \
--uri "https://management.azure.com/subscriptions/<sub>/resourceGroups/rg-security/providers/Microsoft.OperationalInsights/workspaces/law-soc2-prod/providers/Microsoft.SecurityInsights/incidents?api-version=2022-11-01&\$filter=properties/severity eq 'High' and properties/status eq 'Active'" \
--query "value[*].[properties.incidentNumber,properties.title,properties.severity,properties.status,properties.createdTimeUtc]"

# Assign an incident to a responder
az rest --method PATCH \
--uri "https://management.azure.com/subscriptions/<sub>/resourceGroups/rg-security/providers/Microsoft.OperationalInsights/workspaces/law-soc2-prod/providers/Microsoft.SecurityInsights/incidents/<incident-id>?api-version=2022-11-01" \
--body '{"properties":{"owner":{"assignedTo":"[email protected]"},"status":"Active"}}'

Reference: Microsoft Sentinel documentation → · Sentinel incident management → · Sentinel playbooks (Logic Apps) →


5. Customer Notification Requirements​

SOC 2 CC7.4 requires affected customers to be notified within a timeframe documented in your security policy and customer agreements:

  • Define the notification SLA in your Terms of Service or DPA (commonly 72 hours for personal data incidents, 30 days for others).
  • Identify who approves customer notifications (Legal, CISO, CEO).
  • Maintain a customer contact list accessible during an incident.
  • Prepare a notification email template in advance.

SOC 2 Evidence for Incident Response​

Evidence itemRetention
Documented incident response policyPermanent
Incident response runbook (version-controlled in Git)Permanent
Sentinel incident list and timelinesAvailable via Sentinel portal or Log Analytics
Defender for Cloud alert historyaz security alert list
Post-incident review reports3 years minimum
Tabletop or live IR exercise recordsAnnual, retained 3 years
Entra ID audit log for incident periodLog Analytics workspace (retain 1+ year)
Customer notification records (if applicable)3 years minimum
Logic App playbook run historyAzure portal → Logic App → Run History

Official references: