> 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_parent_customer.md).

# GCP\_PARENT\_CUSTOMER

## Summary

|                            |                                                                    |
| -------------------------- | ------------------------------------------------------------------ |
| **FSProtect ACL Alias**    | GCP\_PARENT\_CUSTOMER                                              |
| **GCP Alias**              | Entity Relation (Structural)                                       |
| **Affected Object Types**  | Organizations, Organizational Units, Groups, Users, Roles, Devices |
| **Exploitation Certainty** | Certain                                                            |

## Description

`GCP_PARENT_CUSTOMER` is a structural edge representing that a Google Workspace entity — an **Organization, Organizational Unit, Group, User, Role, or Device** — belongs to the **Customer root** of a GWS tenancy. The Customer is the top-level container identified by a Customer ID (e.g., `C0xxxxxxx`). It is the root above every object in the GWS directory and is linked 1:1 to a GCP Organization node.

The Customer is the common root for all GWS object types:

```
Customer (root)
├── Organization  ← GCP_PARENT_CUSTOMER  (linked GCP org)
├── OU (top-level)  ← GCP_PARENT_CUSTOMER
├── Group  ← GCP_PARENT_CUSTOMER
├── User  ← GCP_PARENT_CUSTOMER
├── Role (admin role definition)  ← GCP_PARENT_CUSTOMER
└── Device  ← GCP_PARENT_CUSTOMER
```

Each object type connects to the Customer differently:

* **Organization**: The GCP Organization is bound to the GWS Customer — the Customer is the identity root for the entire GCP org.
* **OUs**: Top-level OUs sit directly under the Customer; nested OUs inherit policies through the `GCP_PARENT_OU` chain.
* **Groups**: All GWS Groups are scoped to the Customer regardless of which OU their members belong to.
* **Users**: Every user in the GWS tenant is a Customer-level object; their OU placement is a policy-routing detail, not a containment boundary.
* **Roles**: Built-in and custom admin role definitions are defined at the Customer level and assigned to principals via role assignments.
* **Devices**: Devices enrolled through endpoint management belong to the Customer and inherit MDM policies based on the user's OU.

Admin roles and policies scoped to the **Customer level** are the broadest in Google Workspace — they apply to every object connected through this edge. `GCP_PARENT_CUSTOMER` enables the graph to trace the full blast radius of customer-scoped admin assignments across all object types.

## Identification

### GCP Console

1. **Customer ID**: Open **Google Admin Console** (`admin.google.com`) → **Account** → **Account settings** → **Profile**. The Customer ID (`C0xxxxxxx`) is listed there.
2. **OUs**: Go to **Directory** → **Organizational units** — root-level OUs have a `GCP_PARENT_CUSTOMER` edge.
3. **Groups**: Go to **Directory** → **Groups** — all groups are Customer-scoped.
4. **Users**: Go to **Directory** → **Users** — all users belong to the Customer regardless of their OU.
5. **Roles**: Go to **Account** → **Admin roles** — all role definitions are Customer-level objects.
6. **Devices**: Go to **Devices** → **Mobile & endpoints** → **Devices** — all enrolled devices belong to the Customer.

### gcloud CLI

```bash
# Get the Customer ID and linked GCP Organization
# (Access token should be authorized on scope: https://www.googleapis.com/auth/admin.directory.customer.readonly)
ACCESS_TOKEN="your-access-token"
curl -s \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  "https://admin.googleapis.com/admin/directory/v1/customers/my_customer" \
  | jq '{customerId: .id, customerDomain: .customerDomain}'

# List all top-level OUs (direct children of the Customer root)
# (Access token should be authorized on scope: https://www.googleapis.com/auth/admin.directory.orgunit.readonly)
curl -s \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  "https://admin.googleapis.com/admin/directory/v1/customer/my_customer/orgunits?type=children" \
  | jq '.organizationUnits[] | {name: .name, path: .orgUnitPath}'

# List all Customer-scoped groups
# (Access token should be authorized on scope: https://www.googleapis.com/auth/admin.directory.group.readonly)
curl -s \
  -H "Authorization: Bearer $ACCESS_TOKEN" \ 
  "https://admin.googleapis.com/admin/directory/v1/groups?customer=my_customer" \
  | jq '.groups[] | {email, name, directMembersCount}'

# List all users in the Customer
# (Access token should be authorized on scope: https://www.googleapis.com/auth/admin.directory.user.readonly)
curl -s \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  "https://admin.googleapis.com/admin/directory/v1/users?customer=my_customer&maxResults=500" \
  | jq '.users[] | {email: .primaryEmail, orgUnitPath: .orgUnitPath, isAdmin: .isAdmin}'

# Enumerate all admin role definitions at Customer scope
# (Access token should be authorized on scope: https://www.googleapis.com/auth/admin.directory.rolemanagement.readonly)
curl -s \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  "https://admin.googleapis.com/admin/directory/v1/customer/my_customer/roles" \
  | jq '.items[] | {roleId: .roleId, roleName: .roleName, isSystemRole: .isSystemRole}'

# Enumerate all admin role assignments at Customer scope
curl -s \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  "https://admin.googleapis.com/admin/directory/v1/customer/my_customer/roleassignments" \
  | jq '.items[] | {assignedTo: .assignedTo, roleId: .roleId, scopeType: .scopeType}'
```

## Exploitation

`GCP_PARENT_CUSTOMER` has no direct exploit — it is a structural edge. Its attack value is as a **reachability and blast-radius indicator** across all Customer-scoped object types:

* **Organization**: The GCP Organization is bound 1:1 to the Customer. Compromising the Customer root means owning the identity layer for the entire GCP org — org-level IAM bindings, org policies, and all resource hierarchy controls become accessible.
* **OUs**: Enumerating top-level OUs reveals the organizational structure and the security policies in effect per business unit — which OUs enforce stricter MDM, have restricted app access, or apply tighter Context-Aware Access levels. Moving a user to a less-restricted OU bypasses controls scoped to their original OU.
* **Groups**: All GWS groups are Customer-scoped objects. Enumerating them via `GCP_PARENT_CUSTOMER` surfaces every group regardless of OU placement — including groups with GCP IAM bindings that can be targeted via [`GWS_ADD_GROUP_MEMBER`](https://docs.forestall.io/fsprotect/edges/gcp/gws_add_group_member).
* **Users**: All user accounts belong to the Customer. A customer-scoped admin can reset any user's password [`GWS_RESET_PASSWORD`](https://docs.forestall.io/fsprotect/edges/gcp/gws_reset_password), enumerate GCP-privileged users, and pivot into their project-level role bindings.
* **Roles**: Admin role definitions are Customer-level objects. An attacker who can modify role definitions (custom roles) or assign built-in roles at customer scope gains persistent, broadly-scoped administrative access. Creating a backdoor custom role with selected privileges is harder to detect than a new Super Admin assignment.

## Mitigation

1. **Minimize Super Admin assignments** — Super Admin is always customer-scoped; limit to two or three break-glass accounts with hardware MFA (security keys), dedicated recovery accounts, and no day-to-day usage.
2. **Use OU-scoped delegated admin roles** instead of Super Admin for routine operations — scope custom roles to specific OUs and object types rather than the full Customer.
3. **Audit customer-level role assignments** regularly and alert on any new Super Admin or custom role grants at customer scope:

   ```bash
   ACCESS_TOKEN="your-access-token"
   curl -s \
     -H "Authorization: Bearer $ACCESS_TOKEN" \
     "https://admin.googleapis.com/admin/directory/v1/customer/my_customer/roleassignments" \
     | jq '.items[] | select(.scopeType == "CUSTOMER") | {assignedTo: .assignedTo, roleId: .roleId}'
   ```
4. **Protect Super Admin accounts** with phishing-resistant MFA (hardware security keys), login challenges, and IP allowlisting where possible.
5. **Audit custom role definitions** — review all non-system roles for dangerous privilege combinations (`RESET_USER_PASSWORD` + `ASSIGN_ROLE` is equivalent to Super Admin escalation).
6. **Restrict customer-level policy changes** — treat relaxations of Customer-root settings (app access, sharing, Context-Aware Access defaults) as security events equivalent to org-level IAM changes in GCP.

## Detection

| Log Type       | Method                                         | Key Fields                                                                            |
| -------------- | ---------------------------------------------- | ------------------------------------------------------------------------------------- |
| Admin Activity | `ASSIGN_ROLE`                                  | Admin audit log, `ROLE_NAME=_SEED_ADMIN_ROLE`, `scopeType=CUSTOMER` — new Super Admin |
| Admin Activity | `CREATE_ROLE` / `UPDATE_ROLE`                  | Custom admin role created or modified at customer scope                               |
| Admin Activity | `CREATE_ORGANIZATIONAL_UNIT` / `MOVE_ORG_UNIT` | Top-level OU created or moved under Customer root                                     |
| Admin Activity | `ADD_GROUP_MEMBER` / `ADD_GROUP_OWNER`         | Group membership changes for Customer-scoped groups                                   |
| Admin Activity | `CHANGE_PASSWORD`                              | Password reset on any user — cross-reference with GCP-privileged accounts             |

```bash
# Monitor for new Super Admin role assignments (customer-scoped)
ACCESS_TOKEN="your-access-token"
curl -s \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  "https://admin.googleapis.com/admin/reports/v1/activity/users/all/applications/admin?eventName=ASSIGN_ROLE" \
  | jq '.items[]? | {actor: .actor.email, time: .id.time, params: (.events[].parameters | map({(.name): .value}) | add)}'
```

```bash
# Monitor for custom role creation and modification
curl -s \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  "https://admin.googleapis.com/admin/reports/v1/activity/users/all/applications/admin?eventName=CREATE_ROLE" \
  | jq '.items[]? | {actor: .actor.email, time: .id.time, params: (.events[].parameters | map({(.name): .value}) | add)}'
```

```bash
# Monitor for top-level OU creation and moves
curl -s \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  "https://admin.googleapis.com/admin/reports/v1/activity/users/all/applications/admin?eventName=CREATE_ORG_UNIT" \
  | jq '.items[]? | {actor: .actor.email, time: .id.time, params: (.events[].parameters | map({(.name): .value}) | add)}'
```

Alert on:

* New `_SEED_ADMIN_ROLE` (Super Admin) assignments — any new Super Admin is a critical security event.
* Custom role creation or modification with dangerous privilege combinations.
* Top-level OUs created or moved under the Customer root — hierarchy changes alter policy inheritance.
* Password resets on accounts holding GCP IAM bindings — cross-reference GWS audit logs with GCP IAM policy.

## References

* <https://developers.google.com/admin-sdk/directory/reference/rest/v1/orgunits>
* <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_parent_customer.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.
