From f6aa8a66f2d5ffc05ef13f4e142a99027103cd81 Mon Sep 17 00:00:00 2001 From: aryu <153210755+Aryu-RU@users.noreply.github.com> Date: Mon, 1 Jun 2026 17:56:56 +0800 Subject: [PATCH 1/4] Add GCP service account impersonation role grant rule New Terms rule that flags when an impersonation role (serviceAccountTokenCreator, serviceAccountUser, or serviceAccountOpenIdTokenCreator) is granted on a service account via SetIamPolicy. Such grants let a principal mint tokens for or act as the target service account, enabling privilege escalation and key-less persistence. Registers the flattened request/response policy binding role sub-fields in the non-ECS schema so the query validates. --- detection_rules/etc/non-ecs-schema.json | 4 + ...vice_account_impersonation_role_grant.toml | 159 ++++++++++++++++++ 2 files changed, 163 insertions(+) create mode 100644 rules/integrations/gcp/persistence_gcp_service_account_impersonation_role_grant.toml diff --git a/detection_rules/etc/non-ecs-schema.json b/detection_rules/etc/non-ecs-schema.json index f1e9848d14f..8d226dcdd78 100644 --- a/detection_rules/etc/non-ecs-schema.json +++ b/detection_rules/etc/non-ecs-schema.json @@ -184,6 +184,10 @@ "google_workspace.token.scope.data.scope_name": "keyword", "google_workspace.device.account_state": "keyword" }, + "logs-gcp*": { + "gcp.audit.request.policy.bindings.role": "keyword", + "gcp.audit.response.bindings.role": "keyword" + }, "logs-ti_*": { "labels.is_ioc_transform_source": "keyword" }, diff --git a/rules/integrations/gcp/persistence_gcp_service_account_impersonation_role_grant.toml b/rules/integrations/gcp/persistence_gcp_service_account_impersonation_role_grant.toml new file mode 100644 index 00000000000..bf599f8bf27 --- /dev/null +++ b/rules/integrations/gcp/persistence_gcp_service_account_impersonation_role_grant.toml @@ -0,0 +1,159 @@ +[metadata] +creation_date = "2026/05/30" +integration = ["gcp"] +maturity = "production" +updated_date = "2026/05/30" + +[rule] +author = ["Elastic"] +description = """ +Identifies when a service account impersonation role is granted on a Google Cloud Platform (GCP) service account via a +SetIamPolicy operation. Roles such as `roles/iam.serviceAccountTokenCreator`, `roles/iam.serviceAccountUser`, and +`roles/iam.serviceAccountOpenIdTokenCreator` allow a principal to mint access or identity tokens for the target service +account, or to act as it when deploying resources. Adversaries who have obtained sufficient privileges may grant +themselves or an attacker-controlled principal one of these roles to impersonate a higher-privileged service account, +escalating privileges and establishing durable, key-less persistence that survives credential rotation. This is a New +Terms rule that alerts when the granting principal and target service account pair has not been observed performing this +action in the last 14 days. +""" +false_positives = [ + """ + Infrastructure-as-code tooling (e.g. Terraform), CI/CD pipelines, and platform automation routinely grant + serviceAccountUser or serviceAccountTokenCreator when wiring up workloads, deployments, or impersonation chains. + Identify the expected automation principals and target service accounts and add exceptions for them. + """, + """ + Administrators may grant impersonation roles when onboarding new applications or delegating access. Verify that the + grant aligns with a known change and that both the granting principal and the added member are expected. + """, +] +from = "now-9m" +index = ["filebeat-*", "logs-gcp*"] +language = "kuery" +license = "Elastic License v2" +name = "GCP IAM Service Account Impersonation Role Granted" +note = """## Triage and analysis + +### Investigating GCP IAM Service Account Impersonation Role Granted + +Granting an impersonation role on a service account lets the bound member obtain that service account's credentials +without creating a long-lived key. `roles/iam.serviceAccountTokenCreator` and `roles/iam.serviceAccountOpenIdTokenCreator` +allow minting OAuth2 access tokens and OpenID Connect identity tokens, while `roles/iam.serviceAccountUser` allows the +member to attach (actAs) the service account to new resources. Adversaries abuse these grants to pivot to a +higher-privileged identity, escalate privileges, and persist in a way that is unaffected by key rotation or password +resets. + +### Possible investigation steps + +- Identify the granting principal via `gcp.audit.authentication_info.principal_email` and confirm whether that identity +is expected to modify IAM policy on service accounts. +- Review the target service account in `gcp.audit.resource_name` and determine the permissions it holds. Impersonating a +service account with broad project or organization roles represents a significant escalation. +- Inspect the granted binding in `gcp.audit.request` / `gcp.audit.response` to identify the member that was added +(`user:`, `serviceAccount:`, `group:`, or an external domain). External or newly created members are higher risk. +- Examine `gcp.audit.request_metadata.caller_ip` and `gcp.audit.request_metadata.caller_supplied_user_agent` to assess +whether the change originated from an expected location or tool. +- Correlate with recent activity by the granting principal, such as service account key creation, custom role creation, +or `GenerateAccessToken` / `GenerateIdToken` calls that use the newly granted impersonation rights. + +### False positive analysis + +- Terraform, Deployment Manager, and CI/CD service accounts commonly grant serviceAccountUser and +serviceAccountTokenCreator as part of normal provisioning. Baseline these principals and exclude them with exceptions. +- One-time grants during application onboarding or delegation may be legitimate. Validate against change management +before escalating. + +### Response and remediation + +- If the grant is unauthorized, remove the impersonation binding from the service account's IAM policy. +- Revoke any access or identity tokens issued for the impacted service account and review its recent activity for abuse. +- Investigate the granting principal for compromise, rotate its credentials if necessary, and review what other IAM +changes it has made. +- Restrict who can set IAM policy on service accounts and require justification or approval for impersonation grants. + +## Setup + +The GCP Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule.""" +references = [ + "https://securitylabs.datadoghq.com/cloud-security-atlas/attacks/backdooring-service-account/", + "https://stratus-red-team.cloud/attack-techniques/GCP/gcp.persistence.backdoor-service-account-policy/", + "https://cloud.google.com/iam/docs/service-account-impersonation", + "https://cloud.google.com/iam/docs/audit-logging/examples-service-accounts", +] +risk_score = 47 +rule_id = "197d2757-eea1-46f9-9ebd-84646d2b45fa" +severity = "medium" +tags = [ + "Domain: Cloud", + "Data Source: GCP", + "Data Source: Google Cloud Platform", + "Use Case: Identity and Access Audit", + "Use Case: Threat Detection", + "Tactic: Persistence", + "Tactic: Privilege Escalation", + "Resources: Investigation Guide", +] +timestamp_override = "event.ingested" +type = "new_terms" + +query = ''' +data_stream.dataset: "gcp.audit" + and event.action: "google.iam.admin.v*.SetIAMPolicy" + and event.outcome: "success" + and ( + gcp.audit.request.policy.bindings.role: ( + "roles/iam.serviceAccountTokenCreator" or + "roles/iam.serviceAccountUser" or + "roles/iam.serviceAccountOpenIdTokenCreator" + ) + or gcp.audit.response.bindings.role: ( + "roles/iam.serviceAccountTokenCreator" or + "roles/iam.serviceAccountUser" or + "roles/iam.serviceAccountOpenIdTokenCreator" + ) + ) +''' + + +[[rule.threat]] +framework = "MITRE ATT&CK" + +[[rule.threat.technique]] +id = "T1098" +name = "Account Manipulation" +reference = "https://attack.mitre.org/techniques/T1098/" + +[[rule.threat.technique.subtechnique]] +id = "T1098.003" +name = "Additional Cloud Roles" +reference = "https://attack.mitre.org/techniques/T1098/003/" + +[rule.threat.tactic] +id = "TA0003" +name = "Persistence" +reference = "https://attack.mitre.org/tactics/TA0003/" + +[[rule.threat]] +framework = "MITRE ATT&CK" + +[[rule.threat.technique]] +id = "T1098" +name = "Account Manipulation" +reference = "https://attack.mitre.org/techniques/T1098/" + +[[rule.threat.technique.subtechnique]] +id = "T1098.003" +name = "Additional Cloud Roles" +reference = "https://attack.mitre.org/techniques/T1098/003/" + +[rule.threat.tactic] +id = "TA0004" +name = "Privilege Escalation" +reference = "https://attack.mitre.org/tactics/TA0004/" + +[rule.new_terms] +field = "new_terms_fields" +value = ["gcp.audit.authentication_info.principal_email", "gcp.audit.resource_name"] +[[rule.new_terms.history_window_start]] +field = "history_window_start" +value = "now-14d" From 0cead633b106092921b0ba66b9ba8bceb4093447 Mon Sep 17 00:00:00 2001 From: aryu <153210755+Aryu-RU@users.noreply.github.com> Date: Mon, 1 Jun 2026 17:56:56 +0800 Subject: [PATCH 2/4] Address review feedback Unquote the SetIAMPolicy event.action so the version wildcard matches, and key the new terms field on user.id (the authenticated principal). The GCP audit pipeline renames principalEmail/principalSubject to user.email/user.id and empties gcp.audit.authentication_info, so the previous principal_email field would not be populated. Updates the investigation guide accordingly. --- ...ence_gcp_service_account_impersonation_role_grant.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/rules/integrations/gcp/persistence_gcp_service_account_impersonation_role_grant.toml b/rules/integrations/gcp/persistence_gcp_service_account_impersonation_role_grant.toml index bf599f8bf27..83c89f2749d 100644 --- a/rules/integrations/gcp/persistence_gcp_service_account_impersonation_role_grant.toml +++ b/rules/integrations/gcp/persistence_gcp_service_account_impersonation_role_grant.toml @@ -45,8 +45,8 @@ resets. ### Possible investigation steps -- Identify the granting principal via `gcp.audit.authentication_info.principal_email` and confirm whether that identity -is expected to modify IAM policy on service accounts. +- Identify the granting principal via `user.email` and `user.id` and confirm whether that identity is expected to modify +IAM policy on service accounts. - Review the target service account in `gcp.audit.resource_name` and determine the permissions it holds. Impersonating a service account with broad project or organization roles represents a significant escalation. - Inspect the granted binding in `gcp.audit.request` / `gcp.audit.response` to identify the member that was added @@ -98,7 +98,7 @@ type = "new_terms" query = ''' data_stream.dataset: "gcp.audit" - and event.action: "google.iam.admin.v*.SetIAMPolicy" + and event.action: google.iam.admin.v*.SetIAMPolicy and event.outcome: "success" and ( gcp.audit.request.policy.bindings.role: ( @@ -153,7 +153,7 @@ reference = "https://attack.mitre.org/tactics/TA0004/" [rule.new_terms] field = "new_terms_fields" -value = ["gcp.audit.authentication_info.principal_email", "gcp.audit.resource_name"] +value = ["user.id"] [[rule.new_terms.history_window_start]] field = "history_window_start" value = "now-14d" From 9e6877d7c405afd88039a1c613bbf62de6ffa770 Mon Sep 17 00:00:00 2001 From: aryu <153210755+Aryu-RU@users.noreply.github.com> Date: Mon, 1 Jun 2026 18:30:24 +0800 Subject: [PATCH 3/4] Apply review suggestions Use the logs-gcp.audit-* data stream index (and matching non-ECS schema key), reduce the new terms history window to now-10d, add contributor to the author list, and update the description wording. --- detection_rules/etc/non-ecs-schema.json | 2 +- ...nce_gcp_service_account_impersonation_role_grant.toml | 9 ++++----- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/detection_rules/etc/non-ecs-schema.json b/detection_rules/etc/non-ecs-schema.json index 8d226dcdd78..6d093528ecf 100644 --- a/detection_rules/etc/non-ecs-schema.json +++ b/detection_rules/etc/non-ecs-schema.json @@ -184,7 +184,7 @@ "google_workspace.token.scope.data.scope_name": "keyword", "google_workspace.device.account_state": "keyword" }, - "logs-gcp*": { + "logs-gcp.audit-*": { "gcp.audit.request.policy.bindings.role": "keyword", "gcp.audit.response.bindings.role": "keyword" }, diff --git a/rules/integrations/gcp/persistence_gcp_service_account_impersonation_role_grant.toml b/rules/integrations/gcp/persistence_gcp_service_account_impersonation_role_grant.toml index 83c89f2749d..15de3b8482b 100644 --- a/rules/integrations/gcp/persistence_gcp_service_account_impersonation_role_grant.toml +++ b/rules/integrations/gcp/persistence_gcp_service_account_impersonation_role_grant.toml @@ -5,7 +5,7 @@ maturity = "production" updated_date = "2026/05/30" [rule] -author = ["Elastic"] +author = ["Elastic", "Aryu Zaw"] description = """ Identifies when a service account impersonation role is granted on a Google Cloud Platform (GCP) service account via a SetIamPolicy operation. Roles such as `roles/iam.serviceAccountTokenCreator`, `roles/iam.serviceAccountUser`, and @@ -13,8 +13,7 @@ SetIamPolicy operation. Roles such as `roles/iam.serviceAccountTokenCreator`, `r account, or to act as it when deploying resources. Adversaries who have obtained sufficient privileges may grant themselves or an attacker-controlled principal one of these roles to impersonate a higher-privileged service account, escalating privileges and establishing durable, key-less persistence that survives credential rotation. This is a New -Terms rule that alerts when the granting principal and target service account pair has not been observed performing this -action in the last 14 days. +Terms rule that alerts when the granting principal has not been observed performing this action in the last weeks. """ false_positives = [ """ @@ -28,7 +27,7 @@ false_positives = [ """, ] from = "now-9m" -index = ["filebeat-*", "logs-gcp*"] +index = ["logs-gcp.audit-*"] language = "kuery" license = "Elastic License v2" name = "GCP IAM Service Account Impersonation Role Granted" @@ -156,4 +155,4 @@ field = "new_terms_fields" value = ["user.id"] [[rule.new_terms.history_window_start]] field = "history_window_start" -value = "now-14d" +value = "now-10d" From c020944bf2b3b307717d66ac7caecd8d3aef152d Mon Sep 17 00:00:00 2001 From: aryu <153210755+Aryu-RU@users.noreply.github.com> Date: Thu, 4 Jun 2026 22:03:03 +0800 Subject: [PATCH 4/4] Apply review feedback Add the GCP Audit Logs data source tag, replace markdown backticks with quotes in the description (which does not render markdown), and drop the setup note since related_integrations is added at build time. --- ..._gcp_service_account_impersonation_role_grant.toml | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/rules/integrations/gcp/persistence_gcp_service_account_impersonation_role_grant.toml b/rules/integrations/gcp/persistence_gcp_service_account_impersonation_role_grant.toml index 15de3b8482b..7a357fa7f52 100644 --- a/rules/integrations/gcp/persistence_gcp_service_account_impersonation_role_grant.toml +++ b/rules/integrations/gcp/persistence_gcp_service_account_impersonation_role_grant.toml @@ -8,8 +8,8 @@ updated_date = "2026/05/30" author = ["Elastic", "Aryu Zaw"] description = """ Identifies when a service account impersonation role is granted on a Google Cloud Platform (GCP) service account via a -SetIamPolicy operation. Roles such as `roles/iam.serviceAccountTokenCreator`, `roles/iam.serviceAccountUser`, and -`roles/iam.serviceAccountOpenIdTokenCreator` allow a principal to mint access or identity tokens for the target service +SetIamPolicy operation. Roles such as "roles/iam.serviceAccountTokenCreator", "roles/iam.serviceAccountUser", and +"roles/iam.serviceAccountOpenIdTokenCreator" allow a principal to mint access or identity tokens for the target service account, or to act as it when deploying resources. Adversaries who have obtained sufficient privileges may grant themselves or an attacker-controlled principal one of these roles to impersonate a higher-privileged service account, escalating privileges and establishing durable, key-less persistence that survives credential rotation. This is a New @@ -68,11 +68,7 @@ before escalating. - Revoke any access or identity tokens issued for the impacted service account and review its recent activity for abuse. - Investigate the granting principal for compromise, rotate its credentials if necessary, and review what other IAM changes it has made. -- Restrict who can set IAM policy on service accounts and require justification or approval for impersonation grants. - -## Setup - -The GCP Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule.""" +- Restrict who can set IAM policy on service accounts and require justification or approval for impersonation grants.""" references = [ "https://securitylabs.datadoghq.com/cloud-security-atlas/attacks/backdooring-service-account/", "https://stratus-red-team.cloud/attack-techniques/GCP/gcp.persistence.backdoor-service-account-policy/", @@ -85,6 +81,7 @@ severity = "medium" tags = [ "Domain: Cloud", "Data Source: GCP", + "Data Source: GCP Audit Logs", "Data Source: Google Cloud Platform", "Use Case: Identity and Access Audit", "Use Case: Threat Detection",