Google Workspace
Installs gws (the Google Workspace CLI) and configures mailbox aliases and per-shell account selection.
What it does
- Auto-installs and updates gws to the latest GitHub release (checksum-verified release tarball on Linux, Homebrew on macOS)
- Keeps Google Workspace account selection per-shell (
GOOGLE_WORKSPACE_CLI_CONFIG_DIR) so terminals never collide, see Per-shell isolation - Shell aliases and functions for reading the mailbox: inbox triage, Gmail-query search, message reading
- Tab completion for the account functions (gws itself ships no completion generator)
gws talks to the Workspace APIs directly (Gmail, Drive, Calendar, Sheets, Docs, Chat and more), with the command surface generated from the Google Discovery Service. Note that it is a pre-1.0 tool from the googleworkspace GitHub org that labels itself "not an officially supported Google product", so expect breaking changes.
Variables
| Variable | Default | Description |
|---|---|---|
googleworkspace_gws_version | latest | Pin gws to an exact version, or track the newest release |
googleworkspace_min_glibc | 2.39 | Minimum glibc the upstream gws binaries run against; older hosts (Ubuntu 22.04, Debian 12) skip the install with a note instead of re-downloading an unrunnable binary every apply |
googleworkspace_aliases | See defaults | Shell aliases to generate |
googleworkspace_functions | See defaults | Shell functions to generate |
googleworkspace_completions | See defaults | Completion wiring for the functions |
googleworkspace_gws_version: "0.22.5" # latestAliases
| Alias | Command | Description |
|---|---|---|
googleworkspace | gws-account | Show / switch the Google Workspace account |
google | gws-account | Show / switch the Google Workspace account |
inbox | gws gmail +triage | Unread inbox summary (sender, subject, date) |
Functions
| Function | Description |
|---|---|
gws-authenticate | Select an account and run gws auth login in one step |
gws-account | Show the current account, or switch to a named one |
mail-search | Search the mailbox with Gmail query syntax |
mail-read | Read one message by id, headers included |
Authentication
The role installs the binary but leaves you signed out, so nothing writes credentials during an apply. gws brings its own OAuth flow (not gcloud's application-default credentials) and encrypts stored credentials with a key in the OS keyring.
The one-time setup wraps gcloud to create a Cloud project with an OAuth client, then signs in through the browser:
gws auth setup # one-time: Cloud project + OAuth client (needs gcloud)
gws-authenticate personal # select the account and run `gws auth login`gws-authenticate passes extra arguments through to gws auth login, so you can limit what the token can do:
gws-authenticate personal --readonly # read-only scopes only
gws-authenticate personal -s gmail # consent scoped to GmailFor reading your mailbox, --readonly is enough: it includes gmail.readonly, which covers listing, searching, and reading messages.
Two caveats from the gws side:
- A personal
@gmail.comaccount works, but your OAuth app runs in testing mode, so add your address under the app's test users or the login is blocked. - Unverified (testing-mode) OAuth apps are capped at roughly 25 scopes, so prefer
--readonlyor-s gmailover broad presets.
For non-interactive hosts (CI, headless), skip the browser flow with an environment variable and gws picks it up without a login step:
export GOOGLE_WORKSPACE_CLI_TOKEN=$(gcloud auth print-access-token) # short-lived token
export GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE=/path/to/service-account.json # service accountReading your mailbox
inbox is the day-to-day entry point, mail-search and mail-read drill down:
inbox # unread summary: sender, subject, date
inbox --max 5 --query 'from:boss' # narrow it down
mail-search 'newer_than:7d has:attachment'
mail-read 18f1a2b3c4d # full message with headersThe functions wrap gws's Gmail helpers (gws gmail +triage, gws gmail +read), which also take --format json for scripting:
gws gmail +triage --format json | jq -r '.[] | .id + " " + .subject'Beyond the helpers, the whole Gmail API is available as raw methods, with gws schema to inspect any method's parameters:
gws gmail users messages list --params '{"userId": "me", "q": "is:starred"}'
gws schema gmail.users.messages.listPer-shell isolation
gws keeps one credential set per config dir (~/.config/gws by default), so a single shared dir can hold only one signed-in account. gws-account <name> exports GOOGLE_WORKSPACE_CLI_CONFIG_DIR=~/.config/gws/accounts/<name> instead, scoping the selection to the current shell: picking an account in one terminal cannot change which mailbox another terminal reads, and a personal and a work account can stay signed in side by side. Run it with no argument to show the current account and list the ones you have. The starship prompt reads the same GOOGLE_WORKSPACE_CLI_CONFIG_DIR and shows the account ( <account>), so each shell visibly shows the mailbox it is on. This is the per-shell context isolation concept the github and googlecloud roles apply, brought to Google Workspace.
Troubleshooting
No keyring on headless hosts and WSL
gws stores its credential encryption key in the OS keyring, which is often absent on headless Linux and WSL (no Secret Service on D-Bus). Switch the backend to a file and gws keeps the key at .encryption_key inside the config dir:
export GOOGLE_WORKSPACE_CLI_KEYRING_BACKEND=fileSet it before gws auth login, and keep it exported (an aliases or functions override, or your own dotfiles) so later commands can decrypt.
Access blocked on a personal account
A @gmail.com login that ends in "Access blocked" means your OAuth app is in testing mode and your address is not on its test-user list. Add yourself under the Cloud project's OAuth consent screen, Test users, and log in again.