Skip to main content

Event Information

  • Event purpose & scope
    • google.iam.admin.v1.UpdateServiceAccount is fired when a service account’s metadata is modified via the IAM Admin API (e.g., display name, description, disabled flag), not when its IAM policy (roles/bindings) is changed.
    • Typical sources: gcloud iam service-accounts update, Console edits, or API clients calling projects.serviceAccounts.patch.
  • Security & compliance relevance
    • Changes can affect how a service account is identified, whether it is enabled/disabled, and sometimes can indicate repurposing of an identity—important for SOC 2, ISO 27001, and internal IAM governance.
    • Track for anomalous edits (e.g., unexpected re-enabling of previously disabled accounts) and ensure only authorized roles (e.g., roles/iam.serviceAccountAdmin) are performing these actions.
  • Practical monitoring actions
    • In Cloud Logging, filter on protoPayload.@type="type.googleapis.com/google.iam.admin.v1.UpdateServiceAccount" and alert when:
      • authenticationInfo.principalEmail is outside approved admin groups, or
      • requestMetadata.callerSuppliedUserAgent or source IP is unusual, or
      • serviceAccount.disabled flips from true to false.
    • Feed these logs into SIEM / SCC, and use them as part of periodic IAM reviews and change-control evidence.

Examples

  • Privilege escalation via role change
    • An attacker updates a service account used by an internal app to add high-privilege roles (e.g., roles/owner, roles/iam.serviceAccountTokenCreator) on the project.
    • Impact: Full project takeover (read/write/delete of data, KMS use, billing changes). Violates least-privilege principles in ISO 27001, SOC 2, and CIS GCP.
  • Persistence by key/impersonation enablement
    • A malicious admin modifies a low-profile service account to allow key creation or to grant roles/iam.serviceAccountUser to another principal they control.
    • Impact: Long-lived credentials or impersonation path for persistent access, bypassing identity lifecycle controls (NIST 800-53 AC-2, AC-6).
  • Lateral movement via resource access expansion
    • The service account for a CI/CD pipeline is updated to include access to additional projects or sensitive APIs (e.g., BigQuery datasets with PII, Cloud Storage backups).
    • Impact: Cross-project lateral movement and data exfiltration, undermining data access controls required by GDPR, HIPAA, and PCI-DSS (principle of data minimization and access segregation).

Remediation

Using Console

  • Immediate containment & investigation (Console + IAM Recommender)
    • In IAM & Admin → IAM, sort by Type = Service account and locate the impacted accounts (by name/email). For each:
      • Click the pencil icon, remove high-privilege roles (roles/owner, roles/iam.admin, roles/iam.serviceAccountTokenCreator, broad *Admin roles) and any roles not required by the app; click Save.
      • In IAM & Admin → Role recommendations, review suggestions and apply least-privilege roles where possible; document all changes for ISO 27001/SOC 2 change records.
    • In IAM & Admin → Audit Logs, filter by Resource type = Service Account and Method name contains setIamPolicy or roles.setIamPolicy to identify who changed what and when; preserve logs for incident response and compliance (NIST 800‑53 AU-6, IR controls).
  • Lock down service account capabilities (keys, impersonation, lateral movement)
    • In IAM & Admin → Service Accounts:
      • Click each sensitive/low-profile service account → Keys tab → delete all unnecessary keys; disable “Enable key creation” for admins by removing roles/iam.serviceAccountKeyAdmin or similar from their identities in IAM.
      • On the Permissions tab, remove roles/iam.serviceAccountUser and roles/iam.serviceAccountTokenCreator grants to any untrusted or unnecessary principals to break impersonation paths; keep only specific workloads/principals that must impersonate (aligns with NIST AC‑2/AC‑6).
    • For CI/CD and cross-project access:
      • In each project’s IAM page, restrict the CI/CD service account to tightly scoped roles (e.g., dataset‑specific BigQuery roles, bucket‑level Storage roles) instead of project‑wide or multi-project high-privilege roles.
      • For BigQuery and Cloud Storage, use resource-level permissions: go to BigQuery → Dataset → Share or Cloud Storage → Bucket → Permissions, remove broad grants and add minimal needed roles (satisfies GDPR/HIPAA/PCI-DSS data minimization and segregation).
  • Prevent recurrence (guardrails & monitoring)
    • Implement predefined custom roles and groups: in IAM & Admin → Roles, create least-privilege custom roles for admins and CI/CD; then in IAM, assign these instead of primitive roles (Owner, Editor). Restrict who can assign high-privilege roles by limiting roles/iam.admin and roles/resourcemanager.projectIamAdmin to a small, controlled group.
    • In Security → Security Command Center (if enabled) and IAM → Audit Logs, set up alerts (via Cloud Logging → Logs Router → Sinks and Alerting) for:
      • Any assignment of roles/owner, roles/iam.serviceAccountUser, roles/iam.serviceAccountTokenCreator, roles/iam.serviceAccountKeyAdmin to service accounts or users.
      • New key creation events for service accounts and IAM policy changes to CI/CD or low-profile accounts.
    • Regularly review IAM → Policy Analyzer and IAM → Service Accounts for over-privileged accounts; formalize quarterly access reviews and approvals to support ISO 27001, SOC 2, CIS GCP, and NIST 800‑53 access review requirements.

Using CLI

  • Immediate containment & rollback (privilege escalation / persistence / lateral movement)
    • Identify the compromised service account and list its current bindings and keys:
      • gcloud iam service-accounts get-iam-policy SA_NAME@PROJECT_ID.iam.gserviceaccount.com --project=PROJECT_ID
      • gcloud iam service-accounts keys list --iam-account=SA_NAME@PROJECT_ID.iam.gserviceaccount.com --project=PROJECT_ID
    • Remove high-privilege or persistence-enabling roles from the service account and project-level IAM (ISO 27001 A.9, CIS GCP IAM):
      • From project IAM:
        • gcloud projects get-iam-policy PROJECT_ID > policy.yaml
        • Edit policy.yaml to remove bindings like roles/owner, roles/editor, roles/iam.serviceAccountTokenCreator, roles/iam.serviceAccountUser, or cross-project roles for the SA, then:
        • gcloud projects set-iam-policy PROJECT_ID policy.yaml
      • From SA IAM:
        • gcloud iam service-accounts get-iam-policy SA_NAME@PROJECT_ID.iam.gserviceaccount.com --project=PROJECT_ID > sa-policy.yaml
        • Edit to remove roles/iam.serviceAccountUser, roles/iam.serviceAccountKeyAdmin, or any unwanted member bindings:
        • gcloud iam service-accounts set-iam-policy SA_NAME@PROJECT_ID.iam.gserviceaccount.com sa-policy.yaml --project=PROJECT_ID
    • Disable or delete compromised keys and regenerate only if absolutely required (NIST 800-53 AC-2, AC-6; PCI-DSS key management):
      • gcloud iam service-accounts keys delete KEY_ID --iam-account=SA_NAME@PROJECT_ID.iam.gserviceaccount.com --project=PROJECT_ID
      • For CI/CD / lateral movement risk, also revoke unnecessary cross-project roles: use gcloud projects get-iam-policy on all linked projects and remove the SA from sensitive roles (e.g., BigQuery, Storage, KMS).
  • Hardening IAM to prevent recurrence (least privilege, data minimization)
    • Enforce least privilege per use-case and create dedicated service accounts with scoped roles instead of roles/owner/roles/editor or broad *Admin on the project (SOC 2 CC6, ISO 27001 A.9, GDPR data minimization):
      • Example tightening for CI/CD SA:
        • gcloud projects add-iam-policy-binding PROJECT_ID --member="serviceAccount:CI_SA@PROJECT_ID.iam.gserviceaccount.com" --role="roles/storage.objectAdmin"
        • Avoid adding global roles like roles/bigquery.admin, prefer dataset-level ACLs and per-project roles.
    • Restrict who can modify service accounts and grant impersonation/keys:
      • Limit roles/iam.serviceAccountAdmin, roles/iam.serviceAccountUser, roles/iam.serviceAccountTokenCreator, and roles/iam.serviceAccountKeyAdmin to a small break-glass admin group.
      • Example: remove broad group access:
        • gcloud projects get-iam-policy PROJECT_ID > policy.yaml
        • Remove group bindings for these roles, then: gcloud projects set-iam-policy PROJECT_ID policy.yaml
    • Use Org Policies and constraints to block risky patterns (supports CIS GCP, HIPAA/PCI segregation):
      • Disable SA key creation where possible:
        • gcloud resource-manager org-policies allow constraints/iam.disableServiceAccountKeyCreation TRUE --project=PROJECT_ID
      • Restrict who can impersonate all service accounts:
        • gcloud resource-manager org-policies allow constraints/iam.allowedPolicyMemberDomains ... (restrict to corporate domains)
        • Prefer using narrower custom roles instead of wide roles/iam.serviceAccountUser on projects/PROJECT_ID/serviceAccounts/*.
  • Detection, investigation & compliance alignment
    • Enable and monitor Cloud Audit Logs for IAM changes, SA key operations, and project-level policy changes; create log-based alerts for high-risk roles or impersonation grants (NIST 800-53 AU-2/AU-6, SOC 2 monitoring):
      • Example high-risk filter:
        • resource.type="project" AND protoPayload.methodName=("SetIamPolicy" OR "SetServiceAccountPolicy" OR "CreateServiceAccountKey") AND ("roles/owner" OR "roles/iam.serviceAccountUser" OR "roles/iam.serviceAccountTokenCreator" OR "roles/iam.serviceAccountKeyAdmin")
    • For suspected compromise, revoke active tokens and sessions and rotate upstream app credentials (e.g., CI/CD systems, internal apps) that use the impacted service accounts; re-run access reviews for BigQuery datasets with PII, backup buckets, and KMS keys (GDPR, HIPAA, PCI-DSS segregation).
    • Document the change and remediation steps, link to internal IAM standards (least privilege, no keys unless justified, impersonation controls), and feed lessons learned into access review and change-management processes to satisfy ISO 27001 A.12/A.18 and SOC 2 CC5/CC7.

Using Python

  • Immediately detect and revoke over-privileged / persistence-enabling role changes
    • Use Cloud Audit Logs + Python to detect suspicious role bindings (e.g., roles/owner, roles/iam.serviceAccountTokenCreator, roles/iam.serviceAccountUser, key creation roles) on service accounts, then automatically strip them from project or service account IAM policies.
    • This supports least-privilege and SoD requirements (ISO 27001 A.9, SOC 2 CC6, CIS GCP, NIST 800-53 AC-2/AC-6).
  • Lock down service account keys and impersonation paths; rotate if compromised
    • Enumerate service accounts, remove roles/iam.serviceAccountUser and key-admin roles from non-admin principals, disable key creation where not required, and rotate keys/credentials if abuse is suspected, aligning with NIST 800-53 AC-2/IA-5 and SOC 2 change management controls.
    • Use Python with the IAM Admin API to (a) remove risky members from service account IAM, (b) disable/delete user-managed keys.
  • Constrain lateral movement by scoping CI/CD and cross-project access; continuously verify
    • Review and constrain CI/CD service account permissions to least privilege (project- or resource-scoped roles instead of roles/editor/owner, no broad BigQuery/Storage access), and ensure separate accounts per environment/project to satisfy GDPR/HIPAA/PCI-DSS segregation and data-minimization.
    • Use Python to scan for CI/CD SAs with cross-project or high-risk roles and remove/replace them with narrower roles.