Skip to main content

Runbook: Gsuite Disabled-Mode Behavior

P3 / informational. What the platform does when Google Workspace is not configured โ€” no GSUITE_SERVICE_ACCOUNT_KEY_JSON / GSUITE_ADMIN_USER_EMAIL, or creds present but broken. This is the expected state in dev/test and in any env before Workspace Admin DWD is provisioned. See OWNERS.md for on-call.

The contract (ADR-0002 Phase 2, #1179): never crash, never silently write a half-provisioned OSA row, always surface a clear "disabled" indicator.

Full verification recap (all scenarios + evidence): gsuite-disabled-mode-verification.md.


How to tell which mode you're inโ€‹

At boot, GoogleAdminClient logs exactly one line:

Boot logdisabledReasonMeaning
WARN Gsuite disabled โ€” no service account configured โ€ฆno-credentialsExpected dev/test state. Provisioning is skipped.
ERROR Gsuite config incomplete โ€” exactly one of โ€ฆconfig-incompleteOnly one of the key/admin-email pair is set. Misconfig โ€” set both.
ERROR Gsuite credentials invalid โ€” โ€ฆinvalid-credentialsKey present but unparseable. Misconfig โ€” fix the SA JSON.
LOG Google Admin SDK initialized (impersonating โ€ฆ)nullEnabled.

Boot never aborts on any of these โ€” a malformed secret degrades to disabled rather than crash-looping the API under active-active.

What each surface does when disabledโ€‹

  • Provisioning jobs (workspace-provisioning queue) โ€” behavior depends on the disabledReason:
    • no-credentials (intentional disable): every job (create / suspend / archive / restore / set-sendas) completes as a no-op with Job โ€ฆ skipped: gsuite disabled (no-credentials) โ€” OSA โ€ฆ left unprovisioned. No Sentry event, no AM notification, no DB write of gsuite_user_id / gsuite_provisioned_at. email_alias may already be set (a pure string compute) โ€” that's fine.
    • invalid-credentials / config-incomplete (misconfiguration): the job throws (gsuite is misconfigured (<reason>) โ€” refusing to silently no-op โ€ฆ) โ†’ BullMQ retries โ†’ onFailed fires the Sentry + AM alert. This is deliberate: a misconfig must not silently drop a lifecycle op. It matters most for suspend/archive under credential rot โ€” otherwise a Specialist would silently keep Workspace access they should have lost. Fix the creds and the retried job (or a re-trigger) completes.
  • Per-org enqueue gate: in dev/staging the producer (isGsuiteProvisioningEnabledForOrg) does not even enqueue. The processor guard above is defense-in-depth for the explicit AM Provision action, which overrides the env default.
  • OAuth token reads (OAuthTokenService.getAccessToken): an OSA with no refresh token throws the typed OAuthTokenUnavailableError (carries osaId), not a generic error. Catch it and no-op.
  • OSA detail UI (/ops/clients/[id]/specialists/[assignmentId]): shows the email_alias, renders gsuite_user_id as "Not provisioned" and timestamps as "โ€”", status badge Pending. No undefined, no console error.

To enable Gsuite in an environmentโ€‹

  1. Set both GSUITE_SERVICE_ACCOUNT_KEY_JSON (full SA JSON) and GSUITE_ADMIN_USER_EMAIL (admin to impersonate via DWD).
  2. Restart the API; confirm the boot log reads Google Admin SDK initialized (impersonating โ€ฆ).
  3. Per-org: flip the GSuite provisioning toggle on the client detail page, or rely on the production env default. See workspace-provisioning-failure.md for the enabled-path failure runbook.

When this is a real problem (not expected)โ€‹

  • config-incomplete or invalid-credentials in staging/production โ†’ a misconfigured secret. The boot logs an error, and lifecycle jobs fail loudly (Sentry + AM "provisioning failed" alert) rather than skipping โ€” so this also shows up as failed workspace-provisioning jobs. Fix the env var and restart; cross-check against workspace-provisioning-failure.md.
  • OSAs stuck at gsuite_user_id = NULL in an env you expected to be enabled โ†’ check the boot log's disabledReason first; it's the fastest triage signal.