dex icon indicating copy to clipboard operation
dex copied to clipboard

google: add support for groups access without service account

Open devodev opened this issue 7 months ago • 0 comments

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:

  • https://www.googleapis.com/auth/cloud-platform
  • https://www.googleapis.com/auth/cloud-identity.groups
  • https://www.googleapis.com/auth/cloud-identity.groups.readonly

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: https://github.com/dexidp/dex/pull/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: https://github.com/dexidp/website/pull/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, [email protected], 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:

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 protected] groups="[[email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected] [email protected]]" 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 avatar May 18 '25 04:05 devodev