> 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/gws_add_group_owner.md).

# GWS\_ADD\_GROUP\_OWNER

## Summary

|                                |                                                                                               |
| ------------------------------ | --------------------------------------------------------------------------------------------- |
| **FSProtect ACL Alias**        | GWS\_ADD\_GROUP\_OWNER                                                                        |
| **GWS Alias**                  | Add Group Owner                                                                               |
| **Affected Object Types**      | GWS Group                                                                                     |
| **Exploitation Certainty**     | Certain                                                                                       |
| **Granting Roles / Positions** | Google Workspace **Super Admin**, **Groups Admin** (directory role), existing **Group Owner** |

## Description

`GWS_ADD_GROUP_OWNER` represents the ability to add new owners to a Google Workspace Group. Granting the `OWNER` role transfers the highest level of group administrative authority — an owner can add or remove members, managers, and other owners; modify all group settings; and delete the group.

This is the highest-impact group management action edge in the GCP attack surface. An attacker who exercises it does not merely gain group membership — they transfer full administrative control. The new owner can then add controlled identities as members to inherit GCP IAM roles, open the group's join policy to `ALL_IN_DOMAIN_CAN_JOIN` (making any org user eligible to self-join and inherit roles without further admin action), or enable `allowExternalMembers=true` to bypass Domain-Restricted Sharing policies. An owner can also set `whoCanLeaveGroup = NONE_CAN_LEAVE` to prevent members from removing themselves, and add additional backdoor owner accounts to create a resilient foothold that survives partial remediation.

A less obvious risk is the naming collision attack: an attacker with the ability to create or manage groups can create a group whose email matches one an admin intends to bind to GCP IAM. If the admin later binds the wrong group, the attacker retroactively gains access. There is no dedicated detection rule for this pre-provisioning race condition.

All ownership changes and group settings modifications are recorded only in Google Workspace audit logs. GCP's `setIamPolicy` event is never triggered, so monitoring only GCP Cloud Audit Logs provides no visibility into this attack path.

## Identification

### gcloud CLI

```bash
# Find all GCP-bound groups across the organization (primary target list)
gcloud asset search-all-iam-policies \
    --scope='organizations/ORG_ID' \
    --query='memberTypes:group' \
    --format="table(resource, policy.bindings[].role, policy.bindings[].members)"
```

```bash
# Enumerate current owners on a specific group
GROUP_EMAIL="target-group@example.com"
gcloud identity groups memberships list \
  --group-email=$GROUP_EMAIL \
  --format="table(preferredMemberKey.id, roles[0].name)" | grep OWNER
```

### Google Admin Console

1. Open **Google Admin Console** (`admin.google.com`) → **Directory** → **Groups**.
2. Click on the target group → **Members** → filter by **Role: Owner**.
3. Check **Group settings** → **Who can join** and **Allow external members** to assess the current attack surface state.
4. Check **Admin roles** → **Groups Admin** for directory-level admins who can also assign owners.

## Exploitation

```bash
# Add attacker as OWNER of a privileged group
GROUP_EMAIL="privileged-group@example.com"
gcloud identity groups memberships add \
  --group-email=$GROUP_EMAIL \
  --member-email=attacker@example.com \
  --roles=OWNER

# After becoming owner: add a controlled member to inherit GCP IAM roles
gcloud identity groups memberships add \
  --group-email=$GROUP_EMAIL \
  --member-email=backdoor@example.com \
  --roles=MEMBER

# Wait 1-5 minutes for IAM propagation
gcloud projects list
```

## Mitigation

1. **Convert GCP-bound groups to security groups** — restricts all membership and settings changes to Super Admins only:

   ```bash
   gcloud identity groups update GROUP_EMAIL \
     --labels=cloudidentity.googleapis.com/groups.security=''
   ```
2. **Restrict owner assignment** — configure group settings so only Super Admins can assign the OWNER role, not existing owners.
3. **Limit the Groups Admin role** to the minimum required set of administrators via Google Admin Console → **Admin roles** → **Groups Admin** → **Admins**.
4. **Alert on all ownership changes** for groups with GCP IAM bindings — any OWNER assignment should trigger an immediate review.
5. **Audit existing owners on sensitive groups:**

   ```bash
   gcloud identity groups memberships list \
     --group-email=SENSITIVE_GROUP_EMAIL \
     --format="table(preferredMemberKey.id, roles[0].name)" | grep OWNER
   ```

## Detection

Monitor group membership and settings changes in **Google Workspace Audit Logs**. The most dangerous post-owner-add actions (join policy changes, external member enablement) appear as settings change events — a separate filter from membership events.

### Google Admin Console

1. Open **Google Admin Console** (`admin.google.com`) → **Reporting** → **Audit and investigation** → **Groups Enterprise log events**.
2. Filter by **Event Name: Add member** or **Update member** where role = OWNER.
3. Also filter by **Event Name: Change group settings** — look for changes to `whoCanJoin`, `allowExternalMembers`, `whoCanLeaveGroup`.

### Cloud Logging (GCP)

```bash
# Detect owner role assignments and group settings changes
gcloud logging read \
  'logName="organizations/ORG_ID/logs/cloudaudit.googleapis.com%2Factivity" AND protoPayload.serviceName="admin.googleapis.com" AND (protoPayload.methodName="google.admin.AdminService.addGroupMember" OR protoPayload.methodName="google.admin.AdminService.updateGroupMember" OR protoPayload.methodName="google.admin.AdminService.updateGroupSettings")' \
  --format="table(timestamp, protoPayload.authenticationInfo.principalEmail, protoPayload.request.groupKey, protoPayload.request.memberKey, protoPayload.request.role)"
```

## References

* <https://www.netspi.com/blog/technical-blog/cloud-pentesting/escalating-privileges-in-google-cloud-via-open-groups/>
* <https://cloud.google.com/iam/docs/groups-in-cloud-console>
* <https://developers.google.com/admin-sdk/directory/reference/rest/v1/members/insert>
* <https://cloud.google.com/identity/docs/reference/rest/v1/groups.memberships>
* <https://cloud.google.com/security-command-center/docs/concepts-event-threat-detection-overview>
* <https://support.google.com/a/answer/167430>
* <https://cloud.hacktricks.wiki/en/pentesting-cloud/workspace-security/gws-post-exploitation.html>


---

# 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/gws_add_group_owner.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.
