Skip to content

Google Workspace CLI (gws) — Setup and Configuration

Created 2026-04-06
Tags referenceinfrastructuregoogle-workspacecli
  • CLI: gws (installed via Homebrew at /opt/homebrew/bin/gws)
  • Auth method: OAuth2 (browser-based login, credentials stored in macOS Keychain)
  • GCP Project: gws-cli-claude-baseworks (Project ID: 1009018244876)
  • RAPT policy: Set to “never expire” in Google Admin Console — tokens stay valid indefinitely
  • Users: pat@baseworks.com and asia@baseworks.com

We initially set up a service account (gws-cli-agent) with a downloaded JSON key, but reverted because:

  • Google recommends against downloadable service account keys (security risk if file is compromised)
  • Workload Identity Federation (Google’s recommended alternative) is for cloud-to-cloud auth, not local CLI
  • OAuth with relaxed RAPT is simpler and more secure for personal laptop usage — credentials live in the encrypted macOS Keychain, not as a file on disk

The service account still exists in GCP but has no active keys. It can be deleted or reactivated if needed.

ScopeWhat it covers
gmail.modifyRead, send, draft, label emails
driveFull Drive access (files, folders, shared drives)
calendarManage calendars and events
documentsRead and write Google Docs
spreadsheetsRead and write Sheets
presentationsRead and write Slides
tasksManage task lists
Terminal window
# Install
brew install gws
# Authenticate (one-time, opens browser)
gws auth login
# Test
gws gmail users messages list --params '{"userId": "me", "maxResults": 1}'
Terminal window
# List recent emails
gws gmail users messages list --params '{"userId": "me", "maxResults": 10}'
# Read an email
gws gmail users messages get --params '{"userId": "me", "id": "MESSAGE_ID", "format": "full"}'
# Create a draft
gws gmail users drafts create --params '{"userId": "me"}' --json '{"message": {"raw": "BASE64_ENCODED_EMAIL"}}'
# List Drive files
gws drive files list --params '{"pageSize": 10}'
# List calendar events
gws calendar events list --params '{"calendarId": "primary", "maxResults": 5}'
  • invalid_grant error: Run gws auth login to re-authenticate. With the relaxed RAPT policy, this should rarely happen.
  • 401 authError: Same fix — gws auth login.
  • Check auth status: gws auth status shows current auth method, scopes, and token validity.
  • RAPT policy: admin.google.com > Security > Access and data control > Google Cloud session control
  • Domain-wide delegation: admin.google.com > Security > API controls > Domain-wide Delegation
  • GCP project: console.cloud.google.com > project gws-cli-claude-baseworks