Skip to content

Google Workspace Connector — Setup Guide

Step-by-step walkthrough for connecting a Google Workspace domain to Floh. For the full command reference, see google-workspace-connector.md.

1. Create a Service Account

  1. Go to GCP Console > IAM & Admin > Service Accounts
  2. Select your project (or create one)
  3. Click Create Service Account
  4. Name: floh-workspace-connector
  5. Description: Floh connector for Google Workspace management
  6. Click Done (skip the optional grant steps)
  7. Click the new service account → Keys tab → Add KeyCreate new keyJSON
  8. Save the downloaded JSON file securely — you'll need client_email, private_key, and client_id from it

2. Enable the Required APIs

In the same GCP project, go to API Library and enable:

  • Admin SDK API (admin.googleapis.com)
  • Google Drive API (drive.googleapis.com)

3. Grant Domain-Wide Delegation

  1. Open the downloaded JSON key file and copy the numeric client_id value
  2. Go to Google Admin Console for your domain
  3. Navigate to Security → Access and data control → API controls → Manage Domain Wide Delegation
  4. Click Add new
  5. Enter:
  6. Client ID: the numeric client_id from the JSON key file
  7. OAuth scopes (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.readonly,https://www.googleapis.com/auth/drive

The admin.directory.orgunit.readonly scope is required for the workflow designer to populate and validate the orgUnitPath field on createUser. Without it, designer lookups against the Org Units API fail with 403 insufficientPermissions even though the rest of the connector works.

  1. Click Authorize

Note: Domain-wide delegation is configured entirely in the Google Admin Console. The GCP Console no longer has a separate toggle for this.

4. Register the Connector Instance in Floh

The google-workspace connector type is seeded automatically on server startup. Create a configured instance by calling:

PUT /api/connectors/<connector-id>

with the connection config from your JSON key file:

{
  "config": {
    "serviceAccountEmail": "<client_email from JSON>",
    "privateKey": "<private_key from JSON — full PEM string>",
    "adminEmail": "<workspace super admin email>",
    "customerId": "my_customer"
  }
}
Field Source Notes
serviceAccountEmail client_email in JSON key file e.g. sa@project.iam.gserviceaccount.com
privateKey private_key in JSON key file Full PEM string including -----BEGIN/END----- and \n sequences
adminEmail Your Workspace super admin login The service account impersonates this user
customerId Optional Defaults to my_customer; find yours in Admin Console → Account → Account settings

The privateKey is marked as a secret field and is encrypted at rest with AES-256-GCM.

CSRF Note

When calling write endpoints via curl in local development, include CSRF headers:

-H "x-csrf-token: dev" -b "floh_csrf=dev"

In non-dev environments, use the actual CSRF token and cookie issued by the app.

5. Test the Connection

curl -sk -X POST \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -H "x-csrf-token: dev" -b "floh_csrf=dev" \
  "https://localhost:7070/api/connectors/<connector-id>/execute" \
  -d '{"command": "test"}'

Expected response:

{
  "success": true,
  "payload": {
    "message": "Connection successful",
    "tokenObtained": true,
    "adminEmail": "admin@example.com",
    "customerId": "my_customer"
  }
}

Then verify each domain:

{"command": "listUsers", "maxResults": 5}
{"command": "listGroups"}
{"command": "listSharedDrives"}

Troubleshooting

Error Cause Fix
"pkcs8" must be PKCS#8 formatted string privateKey is missing or malformed Use the full private_key value from the JSON file (not the private_key_id)
Not a valid email or user ID serviceAccountEmail typo, or adminEmail doesn't exist in the domain, or delegation not configured Verify all three: service account email matches client_email, admin email is a real super admin, and the Client ID + scopes are saved in Admin Console
Invalid or missing CSRF token Write request missing CSRF headers Add -H "x-csrf-token: dev" -b "floh_csrf=dev" to curl
Forbidden / 403 from Google Scopes not authorized in domain-wide delegation Re-check the delegation entry in Admin Console — ensure all four scopes are listed (user, group, orgunit.readonly, drive)
403 insufficientPermissions on orgUnitPath lookup in the workflow designer DWD entry pre-dates the admin.directory.orgunit.readonly scope Edit the existing DWD entry and add https://www.googleapis.com/auth/admin.directory.orgunit.readonly, then save