gcp

Search Transitive Group Membership using Google Cloud Identity

2022-05-16

GCP’s IAM system allows you to authorize a google group to a resource and apply permissions to that binding. Groups can contain users and even other groups.

So…its imperative to know who are all the members in a group by searching the full nested tree…basically a transitive group membership search…

Well, that ability is now available in an easy-to-use API here:

This article is just a demo of that feature and an implementation of the search using golang.

This article also shows you how to the Workspace Directory API to enumerate google groups in an organization.

We’ll be using service accounts without domain delegation to access these apis:

Groups, group of groups

Setup

First assume you’ve created a service account called adminapi@project.iam.gserviceaccount.com

Then

  1. on the Workspace Console, make sure its authorized for read only operations for users and groups. in admin console, goto Admin -> Admin roles create custom role with user read and group read

Read only group

  1. Assign the service account to that group

Add Service Account to Read only group

thats it, now run the scripts to enumerate grups and search transitive groups:

Cloud Identity SearchTransitive Groups

Create a VM with the appropriate scopes and use that same service account:

gcloud compute instances create dwdvmci \
  --service-account=adminapi@project.iam.gserviceaccount.com \
  --scopes=https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/admin.directory.group.readonly

in vm, install go,

then,

## fist list the scopes on the VM
$ curl -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/scopes

## now list the service account
$ curl -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/email

## get an access token
export TOKEN=`curl -s -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token | jq -r '.access_token'`

# remember to change the query parameter for the member_key_id to the user to inspect
## eg URLEncode( query=member_key_id=='alice@domain.com'&&'cloudidentity.googleapis.com/groups.discussion_forum'+in+labels )

curl -H "Authorization: Bearer $TOKEN" "https://cloudidentity.googleapis.com/v1/groups/-/memberships:searchTransitiveGroups?alt=json&query=member_key_id%3D%3D%27alice%40domain.com%27%26%26%27cloudidentity.googleapis.com%2Fgroups.discussion_forum%27+in+labels"

I could not get the search transitive groups api to work with service accounts. While the docs for this api describe the error below being usually due to the caller not having admin privileges on all groups that entity is in, I ran this query as a domain super admin and this service account is new and only in one group anyway….meaning either its not supported or there’s a hidden group the super admin is not a member of..

from Querying group memberships

A group membership can belong to an individual, a service account, or another group.

The user or service account that is making the query must have permission to view the memberships of all groups that are part of the query, otherwise the request will fail. If the query returns an "PERMISSION_DENIED" error, it's likely that you don't have the correct permissions for one of the nested groups, especially if one of them is a group owned by another organization.
# running as domain superadmin (admin@domain.com)
$ gcloud identity groups memberships search-transitive-groups \
  --labels="cloudidentity.googleapis.com/groups.security" \
  --member-email="sa1-641@domain.iam.gserviceaccount.com"

ERROR: (gcloud.identity.groups.memberships.search-transitive-groups) User [admin@domain.com] does not have permission to access groups instance [-] (or it may not exist): Error(2028): Permission denied for resource sa1-641@domain.iam.gserviceaccount.com (or it may not exist).
- '@type': type.googleapis.com/google.rpc.ResourceInfo
  resourceName: sa1-641@domain.iam.gserviceaccount.com
  resourceType: entity


## however, i noticed that i can use that same api if i run it as the same service account (eg, query self)
###  needless to say, thats next to useless...but i think it shows there's a group that svc accounts are implicitly member of that is visible to "self"?
 $ gcloud auth activate-service-account --key-file=/path/to/svc_account.json
Activated service account credentials for: [sa1-641@domain.iam.gserviceaccount.com]

$ gcloud identity groups memberships search-transitive-groups   --labels="cloudidentity.googleapis.com/groups.security"   --member-email="sa1-641@domain.iam.gserviceaccount.com"
memberships:
- displayName: securitygroup1
  group: groups/03o7alnk3mnc3vc
  groupKey:
    id: securitygroup1@domain.com
  labels:
    cloudidentity.googleapis.com/groups.discussion_forum: ''
    cloudidentity.googleapis.com/groups.security: ''
  relationType: DIRECT
  roles:
  - role: MEMBER

List Groups using Workspace Directory API

Now use the GCP Directory API to simply list the groups. You can use these apis to do pretty much anything with your Workspace setup as long as the service account you’re using is in the correct groups.

Create a VM with the appropriate scopes:

gcloud compute instances create dwdvmci \
  --service-account=adminapi@project.iam.gserviceaccount.com \
  --scopes=https://www.googleapis.com/auth/cloud-platform,https://www.googleapis.com/auth/admin.directory.group.readonly

then on the vm,

## fist list the scopes on the VM
$ curl -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/scopes

## now list the service account
$ curl -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/email

## get an access token
export TOKEN=`curl -s -H "Metadata-Flavor: Google" http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/default/token | jq -r '.access_token'`

#Use the access token list the domain groups
curl -H "Authorization: Bearer $TOKEN" https://admin.googleapis.com/admin/directory/v1/groups?domain=yourdomain.com

This site supports webmentions. Send me a mention via this form.