Granting highly privileged IAM roles on GCP resources reduces an organization’s ability to protect against account compromise and violates the principle of least privilege.

Why is this an issue?

When a GCP IAM policy, binding, or member assignment uses a highly privileged role such as roles/run.admin, it grants full administrative control over the resource to the assigned principal. If elevated access rights are abused or compromised, both the data that the affected resources work with and their access tracking are at risk. Overly broad permissions also prevent proper segregation of duties and create potentially critical attack vectors on affected resources. This rule raises an issue when an IAM role with broad administrative access is assigned to a GCP resource.

What is the potential impact?

Unauthorized access and data breach

If an account with highly privileged access to a GCP resource is compromised, an attacker gains full administrative control over that resource. This can lead to data exfiltration, unauthorized configuration changes, disruption of business-critical services, and loss of audit trail integrity.

How to fix it

Grant IAM policies or members the least permissive role necessary — in most cases, read-only privileges are sufficient. Separate tasks by creating multiple roles that do not use a full-access role for day-to-day work. If the predefined GCP roles do not include the specific permissions you need, create custom IAM roles.

Code examples

The following code is vulnerable because it grants the roles/run.admin role via an IAM policy data source and an IAM member resource, both of which provide full administrative access to the Cloud Run service.

Noncompliant code example

data "google_iam_policy" "admin" {
  binding {
    role = "roles/run.admin" # Noncompliant
    members = [
      "user:name@example.com",
    ]
  }
}

resource "google_cloud_run_service_iam_member" "member" {
  location = google_cloud_run_service.default.location
  project  = google_cloud_run_service.default.project
  service  = google_cloud_run_service.default.name
  role     = "roles/run.admin" # Noncompliant
  member   = "user:name@example.com"
}

Compliant solution

data "google_iam_policy" "admin" {
  binding {
    role = "roles/viewer"
    members = [
      "user:name@example.com",
    ]
  }
}

resource "google_cloud_run_service_iam_member" "member" {
  location = google_cloud_run_service.default.location
  project  = google_cloud_run_service.default.project
  service  = google_cloud_run_service.default.name
  role     = "roles/viewer"
  member   = "user:name@example.com"
}

Resources

Documentation

Standards