At a glance

VendorGoogle Workspace
Source typegoogle_workspace
Vendor ID (slug)google-workspace
Base URLhttps://admin.googleapis.com, fixed for every Workspace tenant
Auth methodoauth2, Authorization: Bearer <access_token> minted per run from a domain-wide-delegated service account JWT
Schedule defaultdaily
AvailabilityStable, presentation refreshed 2026-04-18.

Required scopes & roles

Draxis authenticates as a GCP service account with domain-wide delegation, impersonating a read-only Workspace admin. The service account needs exactly these three read-only OAuth scopes, nothing more:

  • https://www.googleapis.com/auth/admin.directory.user.readonly, list users, 2SV enrollment state, admin flags, suspended/archived state. Backs the /admin/directory/v1/users call.
  • https://www.googleapis.com/auth/admin.reports.audit.readonly, read Admin, Token, and Drive audit logs. Backs the /admin/reports/v1/activity/users/all/applications/{admin,token,drive} calls.
  • https://www.googleapis.com/auth/admin.reports.usage.readonly, reserved for future usage-based KRIs; included now so you don’t need a second consent pass later.

On the Workspace side, the impersonated subject must be a user with a role that can read those APIs. The Google-provided “Services admin” predefined role works; for tighter least-privilege, create a custom admin role that grants only Admin API Privileges → Users → Read and Reports.

Do not grant the service account the Super Admin role, none of these scopes require it, and it would also grant write access.

Setup steps

  1. Create a GCP project and service account. In the Google Cloud Console, pick (or create) a project dedicated to third-party integrations, then go to IAM & Admin → Service Accounts → Create Service Account. Name it draxis-workspace-reader. Skip the “Grant this service account access to project” step, it needs zero GCP IAM roles.
  2. Enable the Admin SDK API on the project. APIs & Services → Library → Admin SDK API → Enable.
  3. Generate a JSON key. On the service account’s Keys tab, Add Key → Create new key → JSON. Save the file, you’ll paste the entire contents into Draxis in the final step. Treat it like a password.
  4. Enable domain-wide delegation. On the service account’s Details page, copy its Unique ID (OAuth 2.0 Client ID), a numeric string. You’ll paste it in the next step.
  5. Authorize the scopes in the Workspace Admin Console. Go to admin.google.comSecurity → Access and data control → API controls → Manage Domain Wide Delegation → Add new. Paste the numeric Client ID from step 4, then paste these three scopes (comma-separated):
    https://www.googleapis.com/auth/admin.directory.user.readonly,https://www.googleapis.com/auth/admin.reports.audit.readonly,https://www.googleapis.com/auth/admin.reports.usage.readonly
    Click Authorize.
  6. Pick (or create) a read-only admin user to impersonate. In the Admin Console, Directory → Users → Add new user, e.g. draxis-reader@your-domain.com. Assign it the Services admin role (or the custom read-only role described above). This is the email you’ll put in the Draxis Client ID field, Draxis impersonates this user when calling Google.
  7. Verify the customer ID (optional). Most tenants can leave customer_id as my_customer. If you’re a Workspace reseller or manage multiple customers, find the real customer ID under Account → Account settings and put it in the Draxis Extra Config JSON as {"customer_id":"C01xxxxxx"}.

Wire it into Draxis

  1. Open Settings → Integrations in your tenant.
  2. Click Add integration and pick Google Workspace as the source type.
  3. The vendor dropdown auto-selects Google Workspace (Admin SDK + Reports), and Draxis auto-fills the base URL, the OAuth auth method, the daily schedule, and seeds extra_config_json with {"customer_id":"my_customer"}.
  4. In Client ID, paste the admin email from step 6 above (e.g. draxis-reader@your-domain.com). This is the user Draxis impersonates, not the service-account numeric ID.
  5. In Client Secret, paste the entire contents of the JSON key file from step 3, every character including the enclosing { … }. Draxis encrypts it server-side with encryption.key before storage.
  6. Click Test. Green means Draxis minted a JWT, exchanged it for an access token, and hit the Directory API successfully.
  7. Under KRIs to import, tick the KRIs you want Draxis to manage. All seven gws_* KRIs are checked by default; uncheck any you don’t need. Selected rows are created on save with the seeded thresholds (tunable later in the KRIs tab). Unchecking a previously-imported KRI deletes it on save.
  8. Save. The connector runs daily by default; use Run now from run history to trigger the first sync immediately.

KRIs produced

SlugMeaningDerivation
gws_2sv_enrollment_pct % of active users enrolled in 2-Step Verification round(count(active[].isEnrolledIn2Sv) / count(active), 1) where active = users[!suspended && !archived]
gws_super_admin_count Count of users flagged isAdmin=true in the Directory API count(users[].isAdmin == true)
gws_ext_shared_sensitive_files Drive ACL changes that set visibility to an external audience, last 7 days count(drive_events where name in (change_user_access, change_acl_editors, change_document_visibility) and visibility in (people_with_link, public_on_the_web, public_in_the_domain_with_link, shared_externally))
gws_oauth_high_risk_apps Distinct OAuth client_ids authorized with high-risk scopes in the last 7 days distinct(token_events[authorize].client_id where any(scope matches mail.google.com | gmail.send|modify|insert | drive | admin.directory | admin.reports | cloud-platform | cloud_search))
gws_suspended_active_ratio_pct Suspended users as a % of active users round(count(suspended) / count(active) * 100, 1)
gws_admin_audit_anomalies_7d Count of privileged admin events in the last 7 days count(admin_events where name or type in (ASSIGN_ROLE, UNASSIGN_ROLE, CREATE_ROLE, DELETE_ROLE, UPDATE_ROLE, DELEGATED_ADMIN_SETTINGS, GRANT_ADMIN_PRIVILEGE, REVOKE_ADMIN_PRIVILEGE, TOGGLE_2SV_ENFORCEMENT, CHANGE_ALLOWED_TWO_STEP_VERIFICATION_METHODS, SSO_PROFILE_CREATED, SSO_PROFILE_DELETED))
gws_dlp_violations_7d Count of Drive DLP rule-violation events in the last 7 days count(drive_events where name startsWith 'dlp_' or type contains 'dlp')

Each row is a slug the connector writes to. Draxis creates the matching kri rows automatically when you check them in the KRIs to import section of the integration form, no manual API call or seed script needed. Thresholds shown in the table are the seeded defaults; you can edit them freely in the KRIs tab afterwards.

Vendor quirks

  • Domain-wide delegation is mandatory. Without it the JWT-bearer token exchange returns unauthorized_client. The scope list in Workspace must match exactly, a typo in one scope silently blocks access to that API.
  • Service-account impersonation is how Google Workspace does least-privilege. The service account itself has no powers; the impersonated subject’s Workspace role is what actually gates access. Keep that subject on a read-only custom role if you want the strictest least-privilege posture.
  • Reports API has a ~20-minute lag. Events appearing in the Admin Console may take up to ~20 minutes to surface through /admin/reports/v1/activity. Draxis’s 7-day window always trails real time, so this is invisible in practice.
  • customer_id=my_customer works for almost everyone. Only resellers or multi-customer setups need the real numeric customer ID. If Test returns HTTP 400 with “Invalid Input: customer”, replace it with your real ID from the Admin Console’s account settings.
  • Pagination is capped at 200 pages per endpoint. At 500 users/page that’s 100k users; at default Reports page sizes it’s well past any 7-day window we’ve seen. Very large tenants that hit the cap should open a support request, we’ll tune the window or paginate in chunks.
  • Service-account JSON keys are credentials. If a key is ever exposed, revoke it in the GCP console (Keys → Delete) and generate a new one, the old key stops working immediately, so do this only after you’re ready to update Draxis.

Troubleshooting

  • HTTP 401 unauthorized_client at the token exchange, domain-wide delegation isn’t set up, or the scope list in the Workspace Admin Console doesn’t match the three scopes above. Re-check the numeric Client ID and the exact scope strings.
  • HTTP 403 on Directory or Reports calls, the impersonated user’s Workspace role is too narrow. Grant them Services admin (or add Users → Read and Reports privileges to your custom role).
  • HTTP 400 “Invalid Input: customer”, you’re a reseller or multi-customer tenant and my_customer doesn’t resolve. Replace the customer_id in Extra Config with the real customer ID.
  • “Client Secret is not valid JSON” on Test, you pasted something other than the full service-account key file. Paste the entire JSON including the outer braces.
  • rowsSkipped > 0 and rowsWritten = 0, your tenant hasn’t imported any KRIs for this integration yet. Open the integration in Settings → Integrations, tick the KRIs under KRIs to import, and save.
  • Still stuck? Open a support ticket with the run ID (from Run history) and we’ll dig in.