> For the complete documentation index, see [llms.txt](https://docs.forestall.io/fsprotect/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.forestall.io/fsprotect/edges/gcp/gcp_role_scoped_to.md).

# GCP\_ROLE\_SCOPED\_TO

## Summary

|                            |                                  |
| -------------------------- | -------------------------------- |
| **FSProtect ACL Alias**    | GCP\_ROLE\_SCOPED\_TO            |
| **GCP Alias**              | Entity Relation (Structural)     |
| **Affected Object Types**  | Organizations, Folders, Projects |
| **Exploitation Certainty** | Certain                          |

## Description

`GCP_ROLE_SCOPED_TO` is a structural edge connecting an **IAM role binding** to the **GCP resource it is scoped to**. In GCP, every IAM role assignment has three components: a principal (who), a role (what), and a resource (where). This edge represents the "where" — the resource scope of the binding.

Understanding scope is critical for assessing the blast radius of a role assignment:

* A binding scoped to an **organization** grants the role across every folder, project, and service account in the organization.
* A binding scoped to a **folder** grants the role across every project and service account in that folder and all its subfolders.
* A binding scoped to a **project** grants the role only within that project.

The `GCP_ROLE_SCOPED_TO` edge enables scope-aware attack path traversal: an attack path that starts at an org-scoped binding fans out to affect every resource in the entire hierarchy, whereas a project-scoped binding affects only that single project.

## Identification

### gcloud CLI

```bash
# Get all role bindings at org scope
ORG_ID=$(gcloud organizations list --format="value(name)" | head -1)
gcloud organizations get-iam-policy $ORG_ID --format=json | \
  jq '.bindings[] | {scope: "organization", role: .role, members: .members}'

# Get all role bindings at folder scope
FOLDER_ID="folders/123456789"
gcloud resource-manager folders get-iam-policy $FOLDER_ID --format=json | \
  jq '.bindings[] | {scope: "folder", role: .role, members: .members}'

# Get all role bindings at project scope
PROJECT_ID="my-project"
gcloud projects get-iam-policy $PROJECT_ID --format=json | \
  jq '.bindings[] | {scope: "project", role: .role, members: .members}'
```

```bash
# Find all org-level bindings for a specific user (highest blast radius)
USER_EMAIL="user@example.com"
gcloud organizations get-iam-policy $ORG_ID --format=json | \
  jq --arg user "user:$USER_EMAIL" '.bindings[] | select(.members[] | contains($user)) | {role: .role, scope: "organization"}'
```

### GCP Console

1. Open **GCP Console** → **IAM & Admin** → **IAM**.
2. The current resource selector at the top shows the scope — switch between organization, folder, and project views.
3. The **InheritANCE** column in the IAM table shows bindings inherited from parent resources (scoped at a higher level).

## Exploitation

The scope of a role binding determines how dangerous it is:

* **Org-scoped bindings** are the highest-risk: a single org-scoped `roles/owner` binding grants full control of the entire GCP organization.
* **Folder-scoped bindings** affect all projects and SAs within the folder hierarchy — common in large orgs where teams share a folder.
* **Project-scoped bindings** are the most constrained — least blast radius.

Attack path analysis traversal uses `GCP_ROLE_SCOPED_TO` to determine which resources an attack path edge targets:

* Org-scoped `roles/owner` → `GCP_CAN_SET_ORG_IAMPOLICY` edge targets the org + `GCP_CAN_SET_PROJECT_IAMPOLICY` edges fan out to ALL projects.
* Folder-scoped `roles/owner` → edges fan out to all projects within the folder hierarchy.
* Project-scoped `roles/owner` → edges target only that specific project.

## Mitigation

1. **Prefer project-scoped bindings** — assign roles at the project level by default. Use folder scope only when the role genuinely needs to apply to all projects in the folder, and org scope only for infrastructure automation accounts.
2. **Audit all org-scoped bindings** — these carry the highest blast radius; each should have a documented owner, purpose, and justification.
3. **Use Privileged Access Manager (PAM)** for just-in-time activation of org- and folder-scoped privileged bindings instead of standing assignments.
4. **Remove over-broad legacy bindings** that were scoped to org or folder but should be project-scoped.

## Detection

| Log Type       | Method                         | Key Fields                             |
| -------------- | ------------------------------ | -------------------------------------- |
| Admin Activity | `SetIamPolicy` at org scope    | Binding added to organization resource |
| Admin Activity | `SetIamPolicy` at folder scope | Binding added to folder resource       |

```bash
ORG_ID=$(gcloud organizations list --format="value(name)" | head -1)
gcloud logging read \
  'protoPayload.methodName="SetIamPolicy" AND resource.type="organization"' \
  --organization=$ORG_ID \
  --format="table(timestamp, protoPayload.authenticationInfo.principalEmail, protoPayload.serviceData.policyDelta.bindingDeltas)"

gcloud logging read \
  'protoPayload.methodName="SetIamPolicy" AND protoPayload.resourceName=~"folders/"' \
  --organization=$ORG_ID \
  --format="table(timestamp, protoPayload.authenticationInfo.principalEmail, protoPayload.resourceName)"
```

Alert on:

* New privileged role bindings added at org or folder scope.
* Any org-scoped `SetIamPolicy` call — org-level policy changes should be exceptionally rare and require change management approval.

## References

* <https://cloud.google.com/iam/docs/resource-hierarchy-access-control>
* <https://cloud.google.com/iam/docs/overview#cloud-iam-policy>
* <https://cloud.google.com/resource-manager/docs/cloud-platform-resource-hierarchy>


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.forestall.io/fsprotect/edges/gcp/gcp_role_scoped_to.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
