Summary
| Forestall ACL Alias | GWS_GROUP_OWNER |
| GWS Alias | Group Owner |
| Affected Object Types | GWS Group |
| Exploitation Certainty | Certain |
Description
GWS_GROUP_OWNER is a structural edge representing that an identity is an owner of a Google Workspace Group. Group owners have the highest level of control and can add or remove members, managers, and other owners; modify all group settings; and delete the group.
If the group is bound to GCP IAM roles, the owner can add a controlled identity as a member to immediately inherit those permissions at any resource scope. Beyond direct member addition, an owner can change whoCanJoin to ALL_IN_DOMAIN_CAN_JOIN, converting a restricted group into one where any org user can self-join via the Groups UI and inherit GCP IAM roles with no further admin action — a behavior Google has classified as “Won’t Fix (Intended Behavior).” An owner can also enable allowExternalMembers=true to allow identities from outside the organization, bypassing Domain-Restricted Sharing policies, or set whoCanLeaveGroup = NONE_CAN_LEAVE to prevent members from removing themselves.
When any new member is added, they immediately gain access to the group’s entire historical email archive. This access generates no audit event anywhere.
All group membership and settings changes are recorded only in Google Workspace audit logs. The GCP setIamPolicy event is never triggered by these actions.
Identification
gcloud CLI
# Find all GCP-bound groups across the organizationgcloud asset search-all-iam-policies \ --scope='organizations/ORG_ID' \ --query='memberTypes:group' \ --format="table(resource, policy.bindings[].role, policy.bindings[].members)"# List all members with OWNER role in a groupgcloud identity groups memberships list \ --group-email=$GROUP_EMAIL \ --format="table(preferredMemberKey.id, roles[0].name)" \ | grep OWNERGoogle Admin Console
- Open Google Admin Console (
admin.google.com) → Directory → Groups. - Click on the target group → Members → filter by Role: Owner.
- Check Group settings → Who can join and Allow external members.
Exploitation
# As a group owner, add a controlled identity as member to inherit all GCP IAM rolesgcloud identity groups memberships add \ --group-email=$GROUP_EMAIL \ --roles=MEMBER
# Wait 1-5 minutes for GCP IAM propagationgcloud projects listgcloud storage lsMitigation
- Convert GCP-bound groups to security groups — restricts all membership and settings changes to Super Admins only:
gcloud identity groups update GROUP_EMAIL \--labels=cloudidentity.googleapis.com/groups.security=''
- Minimize group owners — each GCP-bound group should have as few owners as necessary.
- Audit group ownership regularly:
gcloud identity groups memberships list \--group-email=SENSITIVE_GROUP_EMAIL \--format="table(preferredMemberKey.id, roles[0].name)" | grep OWNER
- Monitor group settings on GCP-bound groups for unauthorized changes to join policy or external member settings.
- Enable GWS audit log export to Cloud Logging — group settings changes are not visible in GCP without this export.
Detection
Monitor group membership and settings changes in Google Workspace Audit Logs. Settings changes (join policy, external members, leave policy) appear as a separate event from membership additions and require a different filter.
Google Admin Console
- Open Google Admin Console (
admin.google.com) → Reporting → Audit and investigation → Groups Enterprise log events. - Filter by Event Name: Add member or Update member (role changes).
- Also filter by Event Name: Change group settings — specifically
whoCanJoin,allowExternalMembers,whoCanLeaveGroup.
Cloud Logging (GCP)
# Monitor member additions and group settings changesgcloud 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.updateGroupSettings")' \ --format="table(timestamp, protoPayload.authenticationInfo.principalEmail, protoPayload.request.groupKey, protoPayload.request.memberKey)"References
- https://www.netspi.com/blog/technical-blog/cloud-pentesting/escalating-privileges-in-google-cloud-via-open-groups/
- https://hackersvanguard.com/the-hidden-google-groups-security-risks/
- https://cloud.google.com/iam/docs/groups-in-cloud-console
- https://developers.google.com/admin-sdk/directory/reference/rest/v1/members
- 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://cloud.hacktricks.wiki/en/pentesting-cloud/workspace-security/gws-post-exploitation.html
- https://support.google.com/a/answer/167430