GCP is less common than AWS in enterprise environments but dominant in ML/data workloads. Its detection model is nearly identical to AWS — control plane API logs, IAM analysis, and data plane visibility gaps.
GCP Cloud Audit Log Format
{
"insertId": "1abcdef2ghijk",
"logName": "projects/my-project/logs/cloudaudit.googleapis.com%2Factivity",
"protoPayload": {
"@type": "type.googleapis.com/google.cloud.audit.AuditLog",
"authenticationInfo": {
"principalEmail": "attacker@gmail.com"
},
"methodName": "google.iam.admin.v1.CreateServiceAccountKey",
"resourceName": "projects/my-project/serviceAccounts/webapp@my-project.iam.gserviceaccount.com",
"requestMetadata": {
"callerIp": "203.0.113.42",
"callerSuppliedUserAgent": "curl/7.68.0"
},
"status": {}
},
"resource": {
"type": "service_account",
"labels": {
"email_id": "webapp@my-project.iam.gserviceaccount.com",
"project_id": "my-project",
"unique_id": "123456789012345678901"
}
},
"severity": "NOTICE",
"timestamp": "2026-05-18T02:14:23Z"
}
Key detection fields: protoPayload.authenticationInfo.principalEmail, protoPayload.methodName, requestMetadata.callerIp.
Detection Pattern 1: Service Account Key Creation (Persistence)
title: GCP Service Account Key Created
logsource:
product: gcp
service: cloudaudit
detection:
selection:
protoPayload.methodName: "google.iam.admin.v1.CreateServiceAccountKey"
filter_known_automation:
protoPayload.authenticationInfo.principalEmail|contains:
- "terraform-sa@"
- "ci-pipeline@"
condition: selection and not filter_known_automation
falsepositives:
- Legitimate service account key rotation by infrastructure automation
level: high
Why this matters: Long-lived service account keys (JSON key files) are the GCP equivalent of AWS long-lived access keys. Any key creation outside known automation is a persistence attempt — attackers use these to maintain access after the initial vector is closed.
Detection Pattern 2: IAM Policy Modification
title: GCP IAM Policy Binding Modified — High Privilege Role
logsource:
product: gcp
service: cloudaudit
detection:
selection:
protoPayload.methodName|contains:
- "SetIamPolicy"
- "projects.setIamPolicy"
- "organizations.setIamPolicy"
selection_high_priv:
protoPayload.request.policy.bindings.role:
- "roles/owner"
- "roles/editor"
- "roles/iam.securityAdmin"
- "roles/iam.roleAdmin"
condition: selection and selection_high_priv
level: critical
Detection Pattern 3: Cloud Storage Exfiltration (Data Access Logging)
When Data Access audit logs are enabled for Cloud Storage:
title: GCP Cloud Storage Bucket — Unusual Bulk Access
logsource:
product: gcp
service: cloudaudit
detection:
selection:
protoPayload.methodName: "storage.objects.get"
protoPayload.resourceName|contains: "sensitive-bucket"
filter_known_service:
protoPayload.authenticationInfo.principalEmail|contains:
- "backup-sa@"
- "analytics-sa@"
condition: selection and not filter_known_service | count() > 50
level: high
GCP-Specific Attack Scenarios
| Attack | Log event | Detection |
|---|---|---|
| Service account key theft | CreateServiceAccountKey | Key created outside automation by unknown principal |
| Owner role escalation | SetIamPolicy with roles/owner | Any owner role grant outside known admin pipeline |
| Cloud Function backdoor | cloudfunctions.functions.create | New function created outside CI/CD service account |
| Project-level IAM grant | resourcemanager.projects.setIamPolicy | Unexpected principal added to project IAM |
| GCS object public access | storage.buckets.setIamPolicy with allUsers | Bucket made public |
| Secret Manager access | secretmanager.versions.access | Secret accessed by non-application principal |
Google Workspace Detection
Workspace audit logs via Admin SDK Reports API cover the SaaS layer:
# Detection: Google Drive file shared externally to 'anyone with link'
# Admin SDK event: drive_sharing_change with visibility = 'people_with_link'
# or 'public_on_the_web'
# Sigma representation (vendor-specific, adapt to SIEM connector format):
# logsource product: google_workspace service: drive
# detection:
# selection:
# eventName: change_document_access_scope
# visibility: ['people_with_link', 'public_on_the_web']
# condition: selection
# level: medium
High-priority Workspace events:
| Event | Why it matters |
|---|---|
drive: change_document_access_scope with public_on_the_web | Drive file made public |
admin: add_privilege for new admin role | Admin role granted to user |
token: authorize for new OAuth app | OAuth app granted scopes to access Workspace data |
gmail: create_filter with forward_to | Email forwarding rule created (exfil path) |
login: login_failure | Failed logins (spray/brute force detection) |