Google Enterprise Connection - Accessing Users API

TL;DR: Does Auth0’s google enterprise connection’s Enable Users API checkbox grant access to the Google Admin Users API — and if so why is my setup not attaching the right scopes to the google access token?



I’m working on setting up a google enterprise connection for my Auth0 app using these docs:

The connection in auth0 is working. I can also retrieve the Google access token for my generated auth0 user’s connections array and use it to access my generic user data within google.

However, as part of my flow I need to retrieve some of the google user’s custom attributes, which requires access to the Google Admin Directory/Users API, specifically the users.get endpoint.

So I stumbled upon this checkbox in the enterprise connection settings:

I assumed this would add the https://www.googleapis.com/auth/admin.directory.user scope to the authorization request, which would in turn grant access to the google users API (aka the one at https://admin.googleapis.com/admin/directory/v1/users/... — this is the only “users” API I know of in Google).

But when using the generated access token from my auth0 connections array to hit the /admin/directory/v1/users/{userID} endpoint, I get a 403:

{
    "error": {
        "code": 403,
        "message": "Request had insufficient authentication scopes.",
        "errors": [
            {
                "message": "Insufficient Permission",
                "domain": "global",
                "reason": "insufficientPermissions"
            }
        ],
        "status": "PERMISSION_DENIED",
        "details": [
            {
                "@type": "type.googleapis.com/google.rpc.ErrorInfo",
                "reason": "ACCESS_TOKEN_SCOPE_INSUFFICIENT",
                "domain": "googleapis.com",
                "metadata": {
                    "method": "ccc.hosted.frontend.directory.v1.DirectoryUsers.Get",
                    "service": "admin.googleapis.com"
                }
            }
        ]
    }
}

When using Google’s /tokeninfo endpoint (https://oauth2.googleapis.com/tokeninfo?access_token=...) I do see that the generated token only has these scopes, so the 403 isn’t unexpected.

  "scope": "https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile openid"

But(!) the checkbox in the Auth0 connections ettings clearly states that it needs access to the Google Admin SDK, which leads me to believe it is intended to grant access to the users API I’m trying to access.

Any ideas what’s off in my config? Or is it that the tokens associated with a user aren’t the tokens that can access the google admin API?

Hi @zschaffter,

You can add additional scopes via the /authorize endpoint using the connection_scope parameter. Please review this document which will demonstrate further: Add Scopes/Permissions to Call Identity Provider APIs

Let me know if that helps!

Thanks,

Mary Beth

@marybeth.hunter Thanks for the reply!

I’d reviewed those docs, but this is actually for an SSO implementation that another platform will be using (Twilio Flex authenticating users through Google Workspace by way of Auth0), so I’m not sure I can directly modify the authorize endpoint twilio’s hitting.

I also found this post, which suggests manually modifying the connection via the management API to set upstream scopes, which may work.

That post actually led me to looking at the connection manually, where I found that it’s assigned an admin_access_token that does grant access to the Google users API.

So I’m still a bit confused by what that checkbox in the google enterprise connection settings does — is it meant to:

  1. add the google admin user API scopes to the access_token associated with the individual user who is logging in
  2. add the scope to the admin_access_token associated with the connection itself
  3. Something else?

(In hindsight it seems a bit odd that an individual’s access token would gain access to the entirety of the google admin API, but if it attaches a readonly version of the scope it might make sense?)

Edit: Looks like the admin_access_token on the connection expires, and individual user logins don’t refresh it, so may be a false start, there.

Okay, I think this is sorted!

Ah, bummer, close but no cigar — this only works if the individual logging in has admin permissions. If not, the access token has the specified scope, but you get this error when trying to use it:

{
    "error": {
        "code": 403,
        "message": "Not Authorized to access this resource/api",
        "errors": [
            {
                "message": "Not Authorized to access this resource/api",
                "domain": "global",
                "reason": "forbidden"
            }
        ]
    }
}
  


(Original post)

Turns out using the Auth0 management API to manually add the additional https://www.googleapis.com/auth/admin.directory.user.readonly scope to upstream_params was the secret.

This appears to modify the connection so that the retrieved google access token that’s stored in each auth0 user’s identities array can retrieve data from the Google admin users API.

So for anyone searching this thread, this is what I did:

  1. Setup the google enterprise connection per these docs
  2. Use the ‘Try’ option to test the login on this screen:
    • This will create a user in auth0 via the workspace connection.
  3. Use the auth0 management API to get the user data for the user created in step 2.
    • Note: Be sure the auth0 client you’re using to fetch the data has the read:user_idp_tokens permission for the management API, otherwise you won’t see the access tokens.
  4. From the auth0 user data, find the access_token within the identities array of the response.
  5. Run that token through google’s tokeninfo endpoint to verify the scopes it was requested with: https://oauth2.googleapis.com/tokeninfo?access_token=...
  6. Finally, update the connection directly via the Management API, adding this object to options (follow these docs):
"upstream_params": {
      "scope": {
          "value": "(add whatever scopes were returned in step 5 along with...) https://www.googleapis.com/auth/admin.directory.user.readonly"
      }
  },

From there, the access token on the Auth0 user should allow readonly access to the google admin users API.

Once the connection is updated, you can repeat steps 2-5, and the tokeninfo response from google should say the token has the new https://www.googleapis.com/auth/admin.directory.user.readonly scope necessary to retrieve the google user profile & custom attributes.

If you’re like me and wanting to retrieve the google user data via an auth0 action, you’ll still need to use the Auth0 management API to fetch the auth0 user’s full data to retrieve the google access token, then use that to call google’s API. You can refer to this doc for more details on that.

I gave up and ended up using a google service account with domain-wide delegation to retrieve the google workspace user custom attributes.

From what I can tell this checkbox in the Auth0 google workspace enterprise settings appears to set the https://www.googleapis.com/auth/admin.directory.user.readonly scope on the connection’s access token, not the user’s.

But I’m not sure how that’s intended to benefit the integration, since that access token is being managed by Auth0.

One could retrieve the access token from Auth0 via the management API (I tested this), and presumably use the refresh token stored alongside it to keep it valid and make requests to the google admin API, but at that point you’re jumping through hoops to replicate something a GCP service account does in an (arguably) simpler fashion.

Using Auth0 connection’s token approach:

  1. Parse connection ID from login attempt
  2. Fetch auth0 connection by connection ID from Auth0 Management API
  3. Get google access_token + refresh_token from response
  4. Refresh access_token if necessary, and (I’m assuming) update auth0 connection with new token
  5. Use refreshed token to authenticate
  6. Retrieve user data from Google admin API

Using a GCP Service account approach:

  1. Store GCP service account credentials JSON as auth0 action secret
  2. Use service account credentials to authenticate with google API
  3. Retrieve user data from Google admin API

On the off-chance someone with internal Auth0 knowledge is reading this and has context on how the setting is meant to be used, that info would be super helpful!

Hi,

Thanks for your patience and replies! I apologize for the delay - I reached out internally about this a few days ago and pinged the team again for an update to get further clarification on the Enable Users API setting. I will keep you updated.

Thanks,

Mary Beth

Hi @zschaffter,

A PM has confirmed that the Enable Users API setting only adds the https://www.googleapis.com/auth/admin.directory.user.readonly scope to the admin access token Auth0 receives.

Thanks,

Mary Beth

Thanks Mary Beth! That answers what it does, though I’m still confused on why the option is offered. It seems like there must be some way for auth0 to leverage that expanded scope, otherwise why present it as a configuration setting?

Does anything under the hood change if auth0 is granted that scope? Or could it be that some of the additional user details you can select (below) require the additional scope?

Hi @zschaffter,

From the PM: The setting is useful for customers who want to leverage the access token Auth0 receives to make their own calls to Google’s API. See the docs below for more info:

When Enable Users API is selected, indicates that you require the ability to make calls to the Google Directory API.

To retrieve additional user and group details beyond what Auth0 retrieves by default, you can use the access tokens returned from Google to call Google’s APIs. To securely access these tokens, follow the guidelines provided in Identity Provider Access Tokens.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.