GCP IAM custom roles should not include permissions that allow privilege escalation to limit the impact of a compromised account.

Why is this an issue?

Certain GCP IAM permissions allow the holder to impersonate other principals or extend their own privileges, enabling privilege escalation. These include permissions such as iam.serviceAccounts.actAs, iam.serviceAccountKeys.create, and deploymentmanager.deployments.create, which can grant access to resources or credentials beyond the role’s intended scope. When a custom role includes such permissions, a compromised account can be used to gain access to more privileged accounts or resources. This rule raises an issue when a custom role grants one or more permissions that are known to enable privilege escalation.

What is the potential impact?

Privilege escalation and account takeover

If a GCP account with privilege escalation permissions is compromised, an attacker can impersonate more privileged service accounts or extend their own access rights. This can lead to full administrative control over GCP resources, data exfiltration, and the ability to cover tracks by modifying or deleting audit logs.

How to fix it

Replace privilege-escalation permissions with the minimum permissions necessary for the role’s intended purpose. If no predefined GCP role matches, create a custom role that omits any permission that enables impersonation or access delegation.

Code examples

The following code is vulnerable because the custom roles grant permissions that allow privilege escalation, such as iam.serviceAccounts.actAs and iam.serviceAccountKeys.create.

Noncompliant code example

resource "google_organization_iam_custom_role" "example" {
  permissions = [
    "iam.serviceAccounts.getAccessToken",     # Noncompliant
    "iam.serviceAccounts.getOpenIdToken",     # Noncompliant
    "iam.serviceAccounts.actAs",              # Noncompliant
    "iam.serviceAccounts.implicitDelegation", # Noncompliant
    "resourcemanager.projects.get",
    "resourcemanager.projects.list",
    "run.services.get",
    "run.services.list",
  ]
}
resource "google_project_iam_custom_role" "example" {
  permissions = [
    "iam.serviceAccountKeys.create",        # Noncompliant
    "deploymentmanager.deployments.create", # Noncompliant
    "cloudbuild.builds.create",             # Noncompliant
    "resourcemanager.projects.get",
    "resourcemanager.projects.list",
    "run.services.get",
    "run.services.getIamPolicy",
    "run.services.list",
  ]
}

Compliant solution

resource "google_organization_iam_custom_role" "example" {
  permissions = [
    "resourcemanager.projects.get",
    "resourcemanager.projects.list",
    "run.services.get",
    "run.services.list",
  ]
}
resource "google_project_iam_custom_role" "example" {
  permissions = [
    "resourcemanager.projects.get",
    "resourcemanager.projects.list",
    "run.services.get",
    "run.services.getIamPolicy",
    "run.services.list",
  ]
}

Resources

Documentation

Articles & blog posts

Standards