Skip to content

Conversation

devodev
Copy link

@devodev devodev commented May 18, 2025

Overview

Add support for retrieving groups the user is a member of without needing to configure a Service Account with Domain-Wide Delegation.

The Google connector has support for retrieving groups the user is a member of using the Admin SDK API. This API requires using an authenticated client sourced from a service account granted domain-wide delegation. This account would be highly-privileged and give access to all Workspace users, which is less than ideal.

This change adds an alternative method to retrieve group membership using the Cloud Identity API. When using the SearchDirectGroups API endpoint, we can provide an access token that has been authorized with the appropriate Cloud Identity API scope and search for direct and transitive membership.

In contrast to the existing method where the user is expected to specify the groups scope, this one relies on the user setting one of the required Cloud Identity scope explicitly:

This is similar to how Grafana provides this feature. Alternatively, we could also decide to support this feature by providing an explicit way in the config to choose which method to use.

This PR supersedes: #1896 which is now 4+ years old.

NOTE: contrary to what was mentioned in the above PR, this feature does NOT require Google Workspace Enterprise Standard, Enterprise Plus, Enterprise for Education, and Cloud Identity Premium accounts.

TODO: update documentation (supersede: dexidp/website#74).

Fixes: #3517

Google connector now supports retrieving group information without a service account.

Testing

I added a basic unit test that mirrors the coverage that the existing TestGetGroups provide.

Additionally, I tested the new changes with a free version of Google Workspace + Google Cloud

I configured ArgoCD with the following:

configs:
  cm:
    dex.config: |
      connectors:
        - id: google
          name: Google
          type: google
          config:
            issuer: https://accounts.google.com
            clientID: clientID
            clientSecret: clientSecret
            scopes: ["openid", "email", "profile", "https://www.googleapis.com/auth/cloud-identity.groups.readonly"]
            fetchTransitiveGroupMembership: true
  rbac:
    policy.default: role:readonly
    policy.csv: |
      g, admins@devodev.cloud, role:admin
    scopes: "[groups]"
dex:
  enabled: true
  image:
    repository: devodev/dex
    tag: v2.42.1-alpine-connectors-google-sa-less-groups
    imagePullPolicy: Always

To validate transitive group membership, I created the following group hierarchy:

  • group: admins@devodev.cloud
    • group: argocd-admins@devodev.cloud
      • user: alex@devodev.cloud

And after login, I see the following log (+ admin role assigned):

time=2025-05-18T04:00:01.646Z level=INFO msg="login successful" connector_id=google username="Alexandre Barone" preferred_username="" email=alex@devodev.cloud groups="[argocd-admins@devodev.cloud grafana-admins@devodev.cloud support@devodev.cloud gcp-developers@devodev.cloud gcp-security-admins@devodev.cloud gcp-billing-admins@devodev.cloud gcp-organization-admins@devodev.cloud gcp-network-admins@devodev.cloud gcp-devops@devodev.cloud admins@devodev.cloud]" request_id=00084f87-49f0-40b0-bc0d-b114d2e721a4

image

Special notes for your reviewer

Couple of changes on this PR that are not directly related to the new feature:

  • Update from recursive to iterative algorithm for fetching transitive dependencies.
  • Some cleanup/refactoring in tests (remove unused vars, use t.Context(), etc).
  • Update golang.org/x/exp to get access to new functions (slices.ContainsFunc).
  • Fix a failing test on Windows.

devodev added 3 commits May 18, 2025 00:43
Set the upstream context when making API call to the admin
service.

Signed-off-by: Alexandre Barone <abalexandrebarone@gmail.com>
The Google connector has support for retrieving groups the user email
is a member of using the Admin SDK API. This API requires using an
authenticated client sourced from a service account granted domain-wide
delegation. This account would be highly-privileged and give access to all
Workspace users, which is less than ideal.

This change adds an alternative method to retrieve group membership
using the Cloud Identity API. When using the SearchDirectGroups API
endpoint, we can provide an access token that has been authorized with
the appropriate Cloud Identity API scope and search for transitive
membership.

In contrast to the existing method where the user is expected to specify
the "groups" scope, this one relies on ther user setting one of the
required Cloud Identity scope explicitly:
- https://www.googleapis.com/auth/cloud-platform
- https://www.googleapis.com/auth/cloud-identity.groups
- https://www.googleapis.com/auth/cloud-identity.groups.readonly

Signed-off-by: Alexandre Barone <abalexandrebarone@gmail.com>
The google oauth2 package uses different heuristics to try and find
credentials. To avoid detecting user credentials, we already cover comon
locaction for unix-based systems such as HOME. On the other hand, on
windows it is possible tok find existing credentials under $APPDATA,
therefore to mitigate, set the env var to /tmp like we do for HOME.

Signed-off-by: Alexandre Barone <abalexandrebarone@gmail.com>
@devodev devodev marked this pull request as ready for review May 18, 2025 04:46
Copy link
Contributor

@cardoe cardoe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While I don't have a Google identity setup, this does seem correct to me from the description and the docs. Code wise it seems correct as well and adds a test.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Google connector doesn't support Workspace group auth without domain-wide delegation
2 participants