MSP Documentation
How to configure Google Workspace
Create a Google Cloud service account with domain-wide delegation that Dex can use to manage a customer's Google Workspace tenant. Takes about 10–15 minutes and requires both Google Cloud project owner and Workspace super admin access.
Overview
This guide walks you through creating a Google Cloud service account with domain-wide delegation that Dex can use to manage a customer's Google Workspace tenant. At the end you will have four values to paste into the Add tenant dialog:
- Service account email (e.g.,
dex@my-project.iam.gserviceaccount.com) - Private key (the
private_keyfield from the JSON key file) - Admin email (a Google Workspace super admin to impersonate)
- Primary domain (e.g.,
customer.com)
The process takes about 10–15 minutes and requires both Google Cloud project owner access and Google Workspace super admin access on the customer's tenant.
Service account + domain-wide delegation
Dex uses a service account with domain-wide delegation — not an OAuth user login. The service account impersonates a super admin to perform actions across the entire Workspace, which is required for autonomous remediation and scheduled discovery.
Before You Start
You will need:
- A user account with Super Administrator rights on the customer's Google Workspace tenant.
- Access to Google Cloud Console (https://console.cloud.google.com) — either an existing project for this customer or permission to create a new one.
- About 15 minutes.
Create (or select) a Google Cloud project
The service account lives inside a Google Cloud project. You can use an existing project or create a dedicated one. We recommend a dedicated project so it is easy to manage and revoke.
- Sign in to https://console.cloud.google.com.
- Click the project picker at the top of the page → New Project.
- Fill in:
- Project name:
Dex Integration(or any name you prefer). - Organization / Location: choose the customer's Google org if applicable.
- Project name:
- Click Create and wait a few seconds, then select the new project from the project picker.
Enable the Admin SDK API
Dex calls the Google Workspace Admin SDK Directory API. It must be enabled on the project.
- In the Cloud Console, go to APIs & Services → Library.
- Search for Admin SDK API.
- Click it, then click Enable.
Tip: You may also want to pre-enable other APIs Dex uses across various skills (Gmail, Calendar, Drive). The minimum required for Add tenant validation is the Admin SDK API. Additional APIs can be enabled later as you turn on more Dex skills.
Create the service account
- In the Cloud Console, go to IAM & Admin → Service Accounts.
- Click + Create Service Account.
- Fill in:
- Service account name:
dex - Service account ID: leave the auto-generated value (e.g.,
dex). - Description:
Dex integration service account
- Service account name:
- Click Create and Continue.
- On the Grant this service account access to project step — leave the roles blank and click Continue. (Dex does not need any Google Cloud IAM roles; all access is granted in Step 5 via domain-wide delegation in Workspace.)
- On the Grant users access to this service account step — leave blank and click Done.
You should now see your new service account in the list. Copy the email address that looks like:
dex@<your-project-id>.iam.gserviceaccount.comPaste it into the Dex Add tenant dialog as the Service account email field.
Create and download a JSON key
- In the service accounts list, click your new
dexservice account. - Open the Keys tab.
- Click Add Key → Create new key.
- Choose JSON and click Create.
- A JSON file is downloaded to your machine. Keep it safe — it grants admin-level access and Google does not store the private portion.
Open the downloaded JSON file in a text editor. You will see something like:
{
"type": "service_account",
"project_id": "my-project",
"private_key_id": "abc123…",
"private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQ…\n-----END PRIVATE KEY-----\n",
"client_email": "dex@my-project.iam.gserviceaccount.com",
"client_id": "123456789012345678901",
…
}From this file you will use two values:
| Field in JSON | Paste into Dex as |
|---|---|
private_key(the entire string, including -----BEGIN…----- and -----END…----- markers) | Private key |
client_id | (used in Step 5 below — not pasted into Dex) |
Important
Paste the private_key value exactly as it appears in the JSON, including the literal \n escape sequences. Dex normalizes them automatically. Do not reformat or unwrap the newlines manually.
Enable domain-wide delegation in Google Workspace
Domain-wide delegation lets the service account impersonate users in the customer's Workspace. This is the step that grants real access — the JSON key alone is not enough.
5a. Copy the service account's Client ID
You need the client_id value from the JSON file (a 21-digit number). You can also find it in Cloud Console → IAM & Admin → Service Accounts → click your service account → Details tab → Unique ID.
5b. Authorize the scopes in Workspace Admin
- Sign in to the Google Workspace Admin console at https://admin.google.com as a Super Administrator of the customer tenant.
- Go to Security → Access and data control → API controls.
- Under Domain-wide delegation, click Manage Domain Wide Delegation.
- Click Add new.
- Fill in:
- Client ID: paste the 21-digit Client ID from Step 5a.
- OAuth scopes: paste the comma-separated list from the table below — all six scopes.
- Click Authorize.
Required OAuth scopes
Dex's validator checks every one of these scopes. If any are missing, you will get an INSUFFICIENT_SCOPES error.
| Scope | Why Dex needs it |
|---|---|
https://www.googleapis.com/auth/admin.directory.user | Create, update, suspend, and delete users; reset passwords; manage aliases. |
https://www.googleapis.com/auth/admin.directory.group | Manage Google Groups (create, update, delete, list memberships). |
https://www.googleapis.com/auth/admin.directory.orgunit | Read and write organizational units used for policy targeting. |
https://www.googleapis.com/auth/admin.directory.device.mobile | Read and manage enrolled mobile devices (wipe, approve, block). |
https://www.googleapis.com/auth/admin.directory.rolemanagement.readonly | Read admin role assignments for privilege analysis. |
https://www.googleapis.com/auth/admin.directory.resource.calendar | Read and manage room and resource calendars. |
Copy-paste form (use this in the OAuth scopes field — comma-separated, no spaces):
https://www.googleapis.com/auth/admin.directory.user,https://www.googleapis.com/auth/admin.directory.group,https://www.googleapis.com/auth/admin.directory.orgunit,https://www.googleapis.com/auth/admin.directory.device.mobile,https://www.googleapis.com/auth/admin.directory.rolemanagement.readonly,https://www.googleapis.com/auth/admin.directory.resource.calendarPick a super admin to impersonate
The service account must impersonate a real Google Workspace super admin when calling the Directory API. This is the Admin email field in the Dex dialog.
- Sign in to https://admin.google.com.
- Go to Directory → Users.
- Find or create a super admin user (Account → Admin roles and privileges → must show Super Admin).
- Note this user's email address.
Best practice
Create a dedicated, named service account user (e.g., dex-admin@customer.com) with the Super Admin role and use that as the impersonated admin. This makes audit logs easier to read and lets you revoke Dex without touching a real person's account.
Paste this email into the Dex Add tenant dialog as the Admin email field.
Find the primary domain
The Primary domain is the customer's main verified domain in Workspace (e.g., customer.com, not customer.onmicrosoft.com).
- In the Workspace Admin console, go to Account → Domains → Manage domains.
- The row marked Primary is the value you need.
Paste it into the Dex Add tenant dialog as the Primary domain field.
Add the tenant in Dex
- Return to the Dex Add tenant dialog.
- Enter an Organization name (label for your MSP dashboard — does not need to match the Workspace name).
- Select Google Workspace.
- Paste the four values:
- Service account email → from Step 3
- Private key → the
private_keyfield from the JSON file (Step 4) - Admin email → super admin to impersonate (Step 6)
- Primary domain → customer's main domain (Step 7)
- Click Add Tenant.
Dex will:
Build and sign a JWT using the private key (rejects bad PEM early).
Exchange the JWT for an access token at Google's OAuth2 endpoint (proves the key, service account, and domain-wide delegation are all wired up correctly).
Call GET /admin/directory/v1/users?domain=<your-domain>&maxResults=1 to confirm the admin can read the directory and all six scopes are authorized.
Look up the customer record for a friendly display name.
If everything succeeds, the tenant appears in your MSP dashboard and Dex automatically starts a discovery scan.
Troubleshooting
INVALID_PRIVATE_KEY
- The private key field is not a valid RSA PEM. Open the JSON key file again and copy the entire
private_keyvalue, including the-----BEGIN PRIVATE KEY-----and-----END PRIVATE KEY-----markers and the literal\nescape sequences. Do not strip newlines or reformat.
DWD_NOT_CONFIGURED
Google's OAuth endpoint rejected the JWT with invalid_grant. Causes:
- Domain-wide delegation has not been authorized for this Client ID in Workspace Admin → Security → API controls → Manage Domain Wide Delegation. Repeat Step 5.
- The Admin email is not a real user in this Workspace, or is not a Super Administrator.
- The Service account email does not match the Client ID that was authorized in Workspace Admin.
- Clock skew on your machine when generating the JWT (rare — only an issue if your system clock is more than ~5 minutes off).
INSUFFICIENT_SCOPES
- The token was issued, but the Directory API returned 403. This means at least one required scope was not authorized in Workspace Admin. Go back to Manage Domain Wide Delegation, click your client row → Edit, paste the full comma-separated scope list from Step 5b, and click Authorize.
INVALID_CREDENTIALS
Google's OAuth endpoint rejected the JWT for a reason other than invalid_grant. Most commonly:
- The Service account email does not match the project the key was issued from.
- The Admin SDK API is not enabled on the project (Step 2).
TENANT_ALREADY_BOUND
- This Workspace domain is already linked to another Dex organization. Contact your Dex administrator.
Rotating the key later
Service account keys do not expire by default, but you should rotate them periodically per your security policy.
- In Cloud Console → IAM & Admin → Service Accounts, open the
dexservice account → Keys tab. - Click Add Key → Create new key → JSON to download a new key.
- In the Dex MSP dashboard, open the tenant and update the Private key field with the new
private_keyvalue. - Once Dex confirms the new key works, return to the Keys tab and delete the old key.
The service account email, Client ID, and authorized scopes remain unchanged — you only update the private key on both sides.
Summary checklist
- Created (or selected) a Google Cloud project.
- Enabled the Admin SDK API on the project.
- Created a service account and copied its email address.
- Created and downloaded a JSON key; kept the file safe.
- In Workspace Admin → API controls → Manage Domain Wide Delegation, added the service account's Client ID with all six required OAuth scopes.
- Identified a Super Administrator email for the service account to impersonate.
- Found the primary domain of the Workspace tenant.
- Pasted the four values into Dex Add tenant and clicked Add Tenant.