Logging & Monitoring
TSC mapping: CC2 (Information Quality), CC4 (Monitoring Activities), CC7.1 (Vulnerability Detection), CC7.2 (Security Event Monitoring), CC7.3 (Incident Evaluation)
SOC 2 auditors look for three things in this area: that logs exist, that they are tamper-protected, and that someone is actually watching them. All three must be evidenced.
1. Azure Activity Log โ Control Plane Audit Trailโ
The Azure Activity Log is the foundational audit log for all Azure Resource Manager (ARM) operations โ who did what, to which resource, when. It is the primary evidence source for CC2 and CC7.2.
Route Activity Logs to a Log Analytics workspaceโ
# Create a Log Analytics workspace (centralised logging hub)
az monitor log-analytics workspace create \
--resource-group rg-security \
--workspace-name law-soc2-prod \
--location eastus \
--retention-time 90
# Get the workspace resource ID
WORKSPACE_ID=$(az monitor log-analytics workspace show \
--resource-group rg-security \
--workspace-name law-soc2-prod \
--query id -o tsv)
# Route Activity Log from a subscription to the workspace
az monitor diagnostic-settings create \
--name activity-log-to-law \
--resource /subscriptions/<subscription-id> \
--workspace $WORKSPACE_ID \
--logs '[{"category":"Administrative","enabled":true},
{"category":"Security","enabled":true},
{"category":"ServiceHealth","enabled":true},
{"category":"Alert","enabled":true},
{"category":"Recommendation","enabled":true},
{"category":"Policy","enabled":true},
{"category":"Autoscale","enabled":true},
{"category":"ResourceHealth","enabled":true}]'
Retain Activity Logs for at least 90 daysโ
# Configure retention on the Log Analytics workspace (90โ730 days)
az monitor log-analytics workspace update \
--resource-group rg-security \
--workspace-name law-soc2-prod \
--retention-time 365
Reference: Azure Activity Log documentation โ ยท Azure Monitor overview โ
2. Entra ID Audit and Sign-in Logsโ
Entra ID audit logs record all identity events โ user creation, role assignments, group changes, MFA registration, and Conditional Access evaluations. These are direct evidence for CC6 controls.
Route Entra ID logs to Log Analyticsโ
# Configure Entra ID diagnostic settings to send to Log Analytics
az rest --method PUT \
--uri "https://management.azure.com/providers/microsoft.aadiam/diagnosticSettings/soc2-entra-logs?api-version=2017-04-01-preview" \
--body "{
\"properties\": {
\"workspaceId\": \"$WORKSPACE_ID\",
\"logs\": [
{\"category\": \"AuditLogs\", \"enabled\": true, \"retentionPolicy\": {\"enabled\": true, \"days\": 365}},
{\"category\": \"SignInLogs\", \"enabled\": true, \"retentionPolicy\": {\"enabled\": true, \"days\": 365}},
{\"category\": \"NonInteractiveUserSignInLogs\", \"enabled\": true, \"retentionPolicy\": {\"enabled\": true, \"days\": 365}},
{\"category\": \"ServicePrincipalSignInLogs\", \"enabled\": true, \"retentionPolicy\": {\"enabled\": true, \"days\": 365}},
{\"category\": \"RiskyUsers\", \"enabled\": true, \"retentionPolicy\": {\"enabled\": true, \"days\": 365}},
{\"category\": \"UserRiskEvents\", \"enabled\": true, \"retentionPolicy\": {\"enabled\": true, \"days\": 365}}
]
}
}"
Query sign-in failures (KQL):
SigninLogs
| where ResultType != "0"
| where TimeGenerated > ago(7d)
| summarize FailureCount = count() by UserPrincipalName, ResultDescription, IPAddress
| order by FailureCount desc
Reference: Entra ID audit logs โ ยท Sign-in logs โ
3. Resource Diagnostic Logsโ
Enable diagnostic logs on all critical Azure resources and send them to the central Log Analytics workspace.
# Enable diagnostic logs for an Azure Key Vault (audit all read/write operations)
az monitor diagnostic-settings create \
--name keyvault-diag \
--resource /subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.KeyVault/vaults/<vault-name> \
--workspace $WORKSPACE_ID \
--logs '[{"category":"AuditEvent","enabled":true}]' \
--metrics '[{"category":"AllMetrics","enabled":true}]'
# Enable diagnostic logs for Azure Storage Account
az monitor diagnostic-settings create \
--name storage-diag \
--resource /subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Storage/storageAccounts/<account>/blobServices/default \
--workspace $WORKSPACE_ID \
--logs '[{"category":"StorageRead","enabled":true},
{"category":"StorageWrite","enabled":true},
{"category":"StorageDelete","enabled":true}]'
# Enable diagnostic logs for Azure SQL Database
az monitor diagnostic-settings create \
--name sql-diag \
--resource /subscriptions/<sub>/resourceGroups/<rg>/providers/Microsoft.Sql/servers/<server>/databases/<db> \
--workspace $WORKSPACE_ID \
--logs '[{"category":"SQLSecurityAuditEvents","enabled":true},
{"category":"Errors","enabled":true}]'
Resources requiring diagnostic logs for SOC 2:
| Resource type | Required log categories |
|---|---|
| Key Vault | AuditEvent |
| Storage Accounts | StorageRead, StorageWrite, StorageDelete |
| Azure SQL / PostgreSQL | SQLSecurityAuditEvents, Errors |
| App Service / Function Apps | AppServiceHTTPLogs, AppServiceConsoleLogs |
| Azure Kubernetes Service | kube-audit, kube-audit-admin |
| Network Security Groups | Flow logs (see Network Security โ) |
Reference: Azure resource diagnostic logs โ
4. Microsoft Defender for Cloud โ Security Posture and Alertsโ
Defender for Cloud aggregates security recommendations, compliance scores, and threat alerts. Enable the Azure Security Benchmark (ASB) standard โ it maps directly to SOC 2 TSC criteria.
# Enable Defender for Cloud (free tier โ security posture)
az security auto-provisioning-setting update \
--name mma \
--auto-provision On
# Enable Defender plans for key services (paid tier โ threat protection)
az security pricing create --name VirtualMachines --tier Standard
az security pricing create --name StorageAccounts --tier Standard
az security pricing create --name SqlServers --tier Standard
az security pricing create --name KeyVaults --tier Standard
az security pricing create --name Containers --tier Standard
az security pricing create --name AppServices --tier Standard
# View current Defender for Cloud secure score
az security secure-scores list --query "[*].[displayName,score.current,score.max]" --output table
Enable the Azure Security Benchmark standard:
az security regulatory-compliance-standards list \
--query "[?name=='azure-security-benchmark'].name" \
--output table
Reference: Microsoft Defender for Cloud documentation โ ยท Azure Security Benchmark โ
5. Microsoft Sentinel โ SIEM and Threat Detectionโ
Microsoft Sentinel is the cloud-native SIEM. Connect it to your Log Analytics workspace to get ML-based threat detection, analytics rules, and an auditable incident lifecycle โ direct evidence for CC7.2 and CC7.3.
# Enable Sentinel on the Log Analytics workspace
az sentinel workspace create \
--resource-group rg-security \
--workspace-name law-soc2-prod
# Install data connectors โ Entra ID
az rest --method PUT \
--uri "https://management.azure.com/subscriptions/<sub>/resourceGroups/rg-security/providers/Microsoft.OperationalInsights/workspaces/law-soc2-prod/providers/Microsoft.SecurityInsights/dataConnectors/AzureActiveDirectory?api-version=2022-11-01" \
--body '{"kind":"AzureActiveDirectory","properties":{"tenantId":"<tenant-id>","dataTypes":{"alerts":{"state":"enabled"}}}}'
# Install data connectors โ Azure Activity
az rest --method PUT \
--uri "https://management.azure.com/subscriptions/<sub>/resourceGroups/rg-security/providers/Microsoft.OperationalInsights/workspaces/law-soc2-prod/providers/Microsoft.SecurityInsights/dataConnectors/AzureActivity?api-version=2022-11-01" \
--body '{"kind":"AzureActivity","properties":{"linkedResourceId":"/subscriptions/<sub>/providers/microsoft.insights/eventtypes/management"}}'
Enable key analytics rules (KQL examples):
// Detect impossible travel (sign-in from two geographies within 1 hour)
SigninLogs
| where ResultType == "0"
| summarize Locations = make_set(Location), IPs = make_set(IPAddress) by UserPrincipalName, bin(TimeGenerated, 1h)
| where array_length(Locations) > 1
// Detect Global Admin role assignment
AuditLogs
| where OperationName == "Add member to role"
| where TargetResources[0].displayName == "Global Administrator"
| project TimeGenerated, InitiatedBy = InitiatedBy.user.userPrincipalName, TargetUser = TargetResources[0].userPrincipalName
Reference: Microsoft Sentinel documentation โ ยท Sentinel analytics rules โ
6. Azure Monitor Alerts โ Critical Security Eventsโ
Configure alerts for the security events that SOC 2 auditors expect to be monitored actively.
# Create an action group (notification target)
az monitor action-group create \
--resource-group rg-security \
--name ag-security-alerts \
--short-name SecAlerts \
--action email security-team [email protected]
# Alert: Any Owner role assignment at subscription scope
az monitor activity-log alert create \
--name "Owner-role-assignment" \
--resource-group rg-security \
--scope /subscriptions/<subscription-id> \
--condition category=Administrative operationName=Microsoft.Authorization/roleAssignments/write \
--action-group /subscriptions/<sub>/resourceGroups/rg-security/providers/microsoft.insights/actionGroups/ag-security-alerts
# Alert: Key Vault access policy changes
az monitor activity-log alert create \
--name "KeyVault-policy-change" \
--resource-group rg-security \
--scope /subscriptions/<subscription-id> \
--condition category=Administrative operationName=Microsoft.KeyVault/vaults/accessPolicies/write \
--action-group /subscriptions/<sub>/resourceGroups/rg-security/providers/microsoft.insights/actionGroups/ag-security-alerts
Required alerts for SOC 2:
| Alert | Event to monitor |
|---|---|
| Owner/privileged role assignments | Microsoft.Authorization/roleAssignments/write |
| Key Vault deletion or access policy change | Key Vault operations |
| Security policy changes | Microsoft.Security/policies/write |
| Network Security Group changes | Microsoft.Network/networkSecurityGroups/write |
| Firewall rule changes | Microsoft.Network/azureFirewalls/write |
| Storage account public access enabled | Microsoft.Storage/storageAccounts/write |
| Sign-in failures exceeding threshold | Sentinel / Entra ID analytics rule |
| Defender for Cloud HIGH alerts | Defender alerts connector in Sentinel |
Reference: Azure Monitor alerts โ ยท Activity log alert rules โ
SOC 2 Evidence for Logging & Monitoringโ
| Evidence item | How to collect |
|---|---|
| Log Analytics workspace configuration | az monitor log-analytics workspace show |
| Activity log diagnostic settings | az monitor diagnostic-settings list --resource /subscriptions/<id> |
| Entra ID audit log export | Entra portal โ Monitoring โ Audit Logs โ Export |
| Defender for Cloud secure score | az security secure-scores list |
| Defender for Cloud recommendations | az security assessment list |
| Sentinel analytics rules list | Azure portal โ Sentinel โ Analytics โ Export |
| Azure Monitor alert rules | az monitor activity-log alert list |
| Key Vault audit log (past 90 days) | KQL: AzureDiagnostics | where ResourceType == "VAULTS" |