AWS dominates but Azure and GCP are major detection surfaces — especially in organizations with Microsoft 365 (which drives Azure/Entra adoption) and GCP for data engineering workloads. This lesson covers the unique characteristics of each.
Azure: Two Separate Telemetry Streams
Stream 1: Azure Activity Log
The Activity Log records control-plane operations on Azure resources. These are the API calls that change your infrastructure:
{
"time": "2024-03-15T09:23:14.882Z",
"operationName": {
"value": "Microsoft.Authorization/roleAssignments/write",
"localizedValue": "Create role assignment"
},
"status": {
"value": "Succeeded"
},
"caller": "attacker@victim.onmicrosoft.com",
"subscriptionId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"resourceId": "/subscriptions/.../resourceGroups/prod/providers/Microsoft.Compute/virtualMachines/web-01",
"properties": {
"requestbody": "{\"properties\":{\"roleDefinitionId\":\"/subscriptions/.../roleDefinitions/8e3af657-...\",\"principalId\":\"...\"}}",
"statusCode": "Created"
}
}
High-priority operationNames for detection:
| operationName | Why it matters |
|---|---|
roleAssignments/write | Privilege escalation — someone granted a role |
policyAssignments/write | Policy bypass — attacker exempting resources from compliance |
virtualMachines/runCommand/action | Code execution via Azure Run Command (T1059) |
managedIdentities/write | Persistence via managed identity |
deployments/write | ARM template deployment — could deploy backdoor |
networkSecurityGroups/securityRules/write | Firewall rule modification |
Stream 2: Entra ID (Azure Active Directory) Audit Logs
These capture identity plane operations:
{
"createdDateTime": "2024-03-15T09:23:14.882Z",
"operationName": "Add member to role",
"result": "success",
"initiatedBy": {
"user": {
"userPrincipalName": "attacker@victim.onmicrosoft.com",
"ipAddress": "203.0.113.55"
}
},
"targetResources": [
{
"displayName": "victim-user@victim.onmicrosoft.com",
"modifiedProperties": [
{
"displayName": "Role.DisplayName",
"newValue": "\"Global Administrator\""
}
]
}
]
}
High-priority Entra operations:
| operationName | ATT&CK technique |
|---|---|
Add member to role (Global Admin) | T1098 — Account Manipulation |
Consent to application | T1550.001 — App consent grant (OAuth persistence) |
Add service principal | T1136.003 — Create Cloud Account |
Update application — Certificates and secrets management (policy) | T1098 — new app credential |
Add federated identity credential to application | T1550 — Federated identity backdoor |
Azure: Forwarding to a SIEM
Azure telemetry reaches your SIEM via:
Azure Monitor → Diagnostic Settings → Event Hub → SIEM connector (Splunk/Elastic/QRadar)
→ Log Analytics Workspace → Microsoft Sentinel
→ Storage Account → Custom ingest pipeline
For Sentinel: everything flows through Log Analytics — Activity Log, Entra ID, Defender alerts, Microsoft 365 logs. For non-Microsoft SIEMs: Event Hub is the recommended forwarding path.
GCP: Unified Cloud Audit Logs
GCP structures its audit logging with a cleaner hierarchy than AWS:
projects/<project-id>/logs/cloudaudit.googleapis.com/
├── activity ← Admin Activity (always on)
├── data_access ← Data Access (opt-in)
└── system_event ← System events (always on)
High-priority GCP methodNames:
| methodName | Detection significance |
|---|---|
google.iam.admin.v1.CreateServiceAccountKey | New persistent credential (T1098) |
google.iam.admin.v1.SetIamPolicy | Permission change — check for overly permissive bindings |
google.iam.v1.IAMPolicy.SetIamPolicy | Resource-level IAM change |
compute.instances.setMetadata | Startup script modification — persistence via startup script |
compute.instances.oslogin.loginWithSecurityKey | OS Login authentication |
storage.objects.get | Object read (requires Data Access logging) |
GCP IAM Policy Change Detection
{
"protoPayload": {
"methodName": "SetIamPolicy",
"authenticationInfo": {
"principalEmail": "attacker@compromised-sa.iam.gserviceaccount.com"
},
"request": {
"policy": {
"bindings": [
{
"role": "roles/owner",
"members": ["user:attacker@gmail.com"]
}
]
}
}
}
}
A service account (@iam.gserviceaccount.com) granting the roles/owner role to an external Gmail account (@gmail.com) on a production project is a critical alert — it’s a complete project takeover from an identity outside your organization.