GCP_HAS_ROLE

Summary

FSProtect ACL Alias

GCP_HAS_ROLE

GCP Alias

Entity Relation (Structural)

Affected Object Types

Roles

Exploitation Certainty

Certain

Description

GCP_HAS_ROLE is a structural edge representing that a GCP identity (user, group, or service account) holds an IAM role binding. It connects principals to their role assignments in the graph. A role binding is a triple of (principal, role, resource). GCP_HAS_ROLE captures the principal → role binding relationship.

Identification

gcloud CLI

# List all roles granted to a specific user at project level
PROJECT_ID="my-project"
USER_EMAIL="[email protected]"
gcloud projects get-iam-policy $PROJECT_ID --format=json | \
  jq --arg user "user:$USER_EMAIL" '.bindings[] | select(.members[] | contains($user)) | .role'

# List all roles granted to a specific service account
SA_EMAIL="[email protected]"
gcloud projects get-iam-policy $PROJECT_ID --format=json | \
  jq --arg sa "serviceAccount:$SA_EMAIL" '.bindings[] | select(.members[] | contains($sa)) | .role'

# List all direct bindings for a principal across org, folder, and project scope
ORG_ID=$(gcloud organizations list --format="value(name)" | head -1)
echo "=== Org level ===" && gcloud organizations get-iam-policy $ORG_ID --format=json | \
  jq --arg user "user:$USER_EMAIL" '[.bindings[] | select(.members[] | contains($user)) | .role]'
echo "=== Project level ===" && gcloud projects get-iam-policy $PROJECT_ID --format=json | \
  jq --arg user "user:$USER_EMAIL" '[.bindings[] | select(.members[] | contains($user)) | .role]'

GCP Console

  1. Open GCP ConsoleIAM & AdminIAM.

  2. Each row in the IAM table represents a GCP_HAS_ROLE edge between the listed principal and the shown role.

  3. Use the Principal filter to view all roles held by a specific identity.

  4. The Inheritance tag indicates bindings from parent scope resources.

Exploitation

GCP_HAS_ROLE is the starting point for all privilege analysis. Every attack path edge in the system is derived from role bindings surfaced by this edge.

Key risk patterns:

  • Over-assignment: Identities accumulating many role bindings over time, especially after project migrations or team changes.

  • Stale bindings: Former employees or deprecated service accounts retaining GCP_HAS_ROLE edges to privileged roles.

  • Cross-project service accounts: A service account from Project A holding roles in Project B creates cross-project attack paths.

  • Conditional bindings: GCP IAM supports conditions on bindings (e.g., time-based access). GCP_HAS_ROLE edges may reflect conditional bindings that are inactive outside their condition window.

Mitigation

  1. Enforce least privilege — remove role bindings that are no longer needed. Conduct periodic access reviews, especially after team changes or project migrations.

  2. Eliminate stale bindings — disable or delete service accounts and user accounts that are no longer active before removing their role bindings.

  3. Scope bindings narrowly — prefer project-level bindings over folder- or org-level to limit blast radius.

  4. Review cross-project service account assignments — a service account from Project A holding roles in Project B creates cross-project attack paths; document and minimize these.

  5. Audit conditional bindings — verify that time-based or condition-based bindings are still appropriate and tightly scoped.

Detection

Log Type
Method
Key Fields

Admin Activity

SetIamPolicy

New role binding added to any principal

Alert on:

  • New privileged role bindings (roles/owner, roles/editor, admin roles) added to any identity.

  • Role bindings added at org or folder scope — these carry the highest blast radius.

  • Bindings added to external identities (Gmail accounts, federated identities outside the org domain).

References

  • https://cloud.google.com/iam/docs/overview

  • https://cloud.google.com/iam/docs/policies

  • https://cloud.google.com/iam/docs/conditions-overview

Last updated

Was this helpful?