HIGH GCP Cloud Audit Log IAM Privilege Escalation LTR-0008 ✓ validated

Detect IAM Privilege Escalation in GCP Cloud Audit Logs

Published · Updated

MITRE ATT&CK: T1098T1078.004

Sigma Rule

title: GCP IAM Privilege Escalation
id: 5e7b2d94-1a63-4c08-9f21-8d3a6c1b4e08
status: experimental
description: >
  Detects GCP IAM actions commonly chained for privilege escalation and
  persistence — binding new roles (SetIamPolicy), minting service-account keys,
  and creating custom roles. Highest fidelity when scoped to principals outside
  your sanctioned IAM-administration set.
references:
  - https://attack.mitre.org/techniques/T1098/
author: LogTriage
date: 2026/07/01
modified: 2026/10/20
logsource:
  product: gcp
  service: gcp.audit
detection:
  selection:
    protoPayload.methodName|endswith:
      - 'SetIamPolicy'
      - '.CreateServiceAccountKey'
      - '.CreateRole'
      - '.CreateServiceAccount'
  filter_known_admins:
    protoPayload.authenticationInfo.principalEmail|endswith:
      - '@terraform-ci.iam.gserviceaccount.com'
      - '[email protected]'
  condition: selection and not filter_known_admins
falsepositives:
  - Sanctioned IAM admin / Terraform CI principals (add to filter_known_admins)
  - Landing-zone / project bootstrap
level: high
tags:
  - attack.privilege_escalation
  - attack.persistence
  - attack.t1098

What this rule detects

GCP privilege escalation shows up in Cloud Audit Logs as a small set of IAM-modifying protoPayload.methodName calls — SetIamPolicy (bind a new role), CreateServiceAccountKey (mint a durable credential), CreateRole/CreateServiceAccount — performed by a principal that has no business administering IAM.

This rule fires on those methods except when the caller is a known platform/CI admin (your filter_known_admins allowlist).

Detection logic

Same durable pattern as the CloudTrail rule: allowlist the admins, flag the rest. Treat sensitive IAM writes as alert-worthy from any principal outside your sanctioned set. CreateServiceAccountKey deserves special attention — it’s a long-lived, MFA-proof credential and a top persistence move.

For higher confidence, watch the chain: SetIamPolicy → CreateServiceAccountKey → storage.objects.list. LogTriage groups the events from one source address into a session and maps each step to ATT&CK; the CloudTrail privilege-escalation use case walks through the same chain on AWS.

Validated against a real sample

Validated against gcp_iam_escalation.json (shipped with LogTriage), which contains SetIamPolicy, CreateServiceAccountKey, and CreateRole from a compromised identity, followed by bucket enumeration. The rule fires on that sample and stays silent on the matching benign operations log.

False positives

Your IAM team and Terraform pipelines legitimately do this — that’s what filter_known_admins is for. Project bootstrap/landing-zone setup can also trip it; scope by project and known provisioning windows.

Frequently Asked Questions

Why is CreateServiceAccountKey such a strong signal?
A service-account key is a long-lived, exportable credential. Attackers mint one to establish durable access that survives password/session resets and evades MFA entirely. Outside your CI/automation, new SA keys are one of the highest-signal GCP persistence indicators.
How do I keep this from firing on my platform team?
Populate filter_known_admins with the principals (Terraform CI, platform-admin SAs) that legitimately manage IAM, and alert on everyone else. 'Allowlist the admins, flag the rest' is far more durable than enumerating malicious patterns.
Why match with endswith instead of the full method names?
Because Google writes the IAM admin methods as `google.iam.admin.v1.CreateServiceAccountKey`, `google.iam.admin.v1.CreateRole` and `google.iam.admin.v1.CreateServiceAccount`, while policy changes appear as `SetIamPolicy` on Cloud Resource Manager and under longer service-specific names on other APIs. Matching the end of the name catches every one of those forms without listing each service.
Does the sequence matter?
Yes — escalation often chains SetIamPolicy → CreateServiceAccountKey → data access (storage.objects.list). LogTriage groups the events from one source address into a session and maps each step to ATT&CK, so an escalation from a single source reads as one story rather than scattered API calls.

Related Resources

See this detection run on a real report

Try the live demo with a pre-loaded malicious log set — no signup required — or upload your own log file and get a full AI-reviewed threat report in minutes.