| name | gws-setup |
| description | Set up Google Workspace CLI (gws) authentication and credentials so the agent can use gws commands. Use this skill whenever the user mentions Google Workspace, gws CLI, Gmail, Google Drive, Google Calendar, Google Sheets, Google Docs, Google Chat, or wants to connect Google services. Also use when the user asks about Google OAuth, Google Cloud credentials, service accounts for Workspace, or needs to configure gws authentication in any environment (desktop, headless, CI, Docker). |
Google Workspace CLI Setup
Guide the user through installing and authenticating the gws CLI so this agent can interact with Google Workspace APIs (Gmail, Drive, Calendar, Sheets, Docs, Chat, and more).
The gws CLI dynamically generates its command surface from Google's Discovery Service, outputs structured JSON, and includes 40+ built-in helper commands prefixed with +.
Scripts
This skill includes executable scripts in scripts/:
| Script | Purpose |
|---|
scripts/gws-setup.sh | Interactive setup wizard — walks through all auth methods, copies creds to the secrets directory |
scripts/gws-export.sh | Export existing host credentials to the secrets directory for Docker/CI use |
scripts/gws-verify.sh | Verify gws installation and authentication status |
Run scripts from the skill directory. They accept --op-home to override the OpenPalm home path and --help for usage.
For host-side setup, tell the user to run gws-setup.sh interactively (it needs browser access for OAuth). For headless/CI, use gws-export.sh after authenticating on another machine. For diagnostics, use gws-verify.sh.
Credential Files Explained
There are three distinct credential files involved in GWS authentication. Understanding which is which matters because the user provides some and gws generates others.
Files the user provides
| File | What it is | Where to get it | Where it goes in secrets |
|---|
client_secret.json | OAuth app identity — contains client ID and client secret. Tells Google which app is requesting access. Does NOT contain user tokens. | Google Cloud Console > APIs & Services > Credentials > Create OAuth client ID (Desktop app) > Download JSON | knowledge/secrets/.gws/client_secret.json |
Service account key (.json) | Machine-to-machine identity — contains a private key for server-to-server auth. No browser/user interaction needed. | Google Cloud Console > IAM & Admin > Service Accounts > Keys > Create new key (JSON) | knowledge/secrets/gcloud-credentials.json |
Files generated by gws (do not create manually)
| File | What it is | How it gets created |
|---|
credentials.json | Authenticated tokens — contains the OAuth refresh token and access token generated after the user completes the browser consent flow. This is what actually authorizes API calls. | gws auth login (stored encrypted in config dir) or gws auth export --unmasked (plaintext) |
.encryption_key | AES-256-GCM key used to encrypt the stored credentials at rest. Falls back to OS keyring if available. | Created automatically by gws auth login |
The flow
- User provides
client_secret.json (or uses gws auth setup to create one automatically)
- User runs
gws auth login which uses the client secret to open a browser consent flow
- After user approves, gws stores encrypted
credentials.json + .encryption_key in the config dir
- The entire
.gws/ directory (client secret + encrypted credentials + encryption key) gets copied to knowledge/secrets/.gws/
For service accounts, the flow is simpler: user provides the key JSON and that's it — no browser, no login, no generated files.
Before You Start
Check if gws is already installed and authenticated:
which gws && gws auth status 2>&1 || echo "gws not found"
If gws is installed and authenticated, skip to "Verify It Works." If not, continue below.
Step 1: Install gws
Ask the user which installation method they prefer:
| Method | Command |
|---|
| npm (recommended) | npm install -g @googleworkspace/cli |
| Cargo | cargo install --git https://github.com/googleworkspace/cli --locked |
| Homebrew | brew install googleworkspace-cli |
| Nix | nix run github:googleworkspace/cli |
| Pre-built binary | Download from GitHub Releases |
After install, verify: gws --version
The OpenPalm assistant Docker image already includes gws and gcloud. No installation needed inside the container.
Step 2: Choose an Authentication Method
There are 6 authentication methods. The right one depends on the environment and use case. Walk the user through this decision:
Decision Guide
| Scenario | Method | User provides | Generated by gws |
|---|
| Desktop with browser, first time ever | Interactive Setup | Nothing (gws creates everything) | client_secret.json + credentials.json |
| Desktop with browser, have own OAuth app | Manual OAuth | client_secret.json from Cloud Console | credentials.json |
| Agent with browser automation | Browser-Assisted Auth | client_secret.json (or use existing) | credentials.json |
| CI/CD pipeline or headless server | Headless/Export Flow | Nothing (export from another machine) | credentials.json (exported) |
| Server-to-server, no user context | Service Account | Service account key JSON | Nothing |
| Quick test, already have a token | Pre-obtained Token | Access token string | Nothing |
Ask the user: "What environment will gws run in? Do you have browser access?" Then proceed to the matching section.
Read references/auth-methods.md for the detailed step-by-step walkthrough of each method.
Step 3: Configure for the OpenPalm Stack
After authentication, credentials need to be accessible to the assistant container.
The compose file sets these environment variables on the assistant service:
GOOGLE_APPLICATION_CREDENTIALS: /stash/secrets/gcloud-credentials.json
CLOUDSDK_CONFIG: /stash/secrets/.gcloud
GOOGLE_WORKSPACE_CLI_CONFIG_DIR: /stash/secrets/.gws
GOOGLE_WORKSPACE_PROJECT_ID: ${GOOGLE_WORKSPACE_PROJECT_ID:-}
Important: Do NOT set GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE in compose. If it points to a missing plaintext JSON file, gws fails even when valid encrypted credentials exist in the config dir. Let gws discover credentials via CONFIG_DIR instead — this works for all auth methods (encrypted creds, plaintext export, and service accounts).
The assistant mounts knowledge/secrets/ at /stash/secrets/. Place files there:
Vault directory layout
knowledge/secrets/
.gws/ # GWS CLI config directory
client_secret.json # User-provided: OAuth app identity (Manual OAuth method)
credentials.json # Generated: authenticated tokens (from gws auth login/export)
.encryption_key # Generated: credential encryption key
.gcloud/ # gcloud CLI config directory
gcloud-credentials.json # User-provided: service account key (Service Account method)
Not all files are needed — it depends on the auth method:
| Auth method | Files in knowledge/secrets/.gws/ | Files in knowledge/secrets/ |
|---|
| Interactive Setup | client_secret.json, credentials.json, .encryption_key (all copied from ~/.config/gws/) | — |
| Manual OAuth | client_secret.json, credentials.json, .encryption_key | — |
| Headless/Export | credentials.json (plaintext export) | — |
| Service Account | — | gcloud-credentials.json |
| Pre-obtained Token | — | — (token set in user.env) |
The quickest path: run scripts/gws-setup.sh on the host. It authenticates and copies the right files to knowledge/secrets/.gws/ automatically.
After placing files, recreate the assistant container:
docker compose ... up -d --force-recreate --no-deps assistant
Do NOT use docker restart — it does not re-read env_file changes.
Host Machine (No Docker)
Credentials live in ~/.config/gws/ by default. Override with:
export GOOGLE_WORKSPACE_CLI_CONFIG_DIR=/custom/path
Step 4: Verify It Works
Run the verification script:
scripts/gws-verify.sh
Or test manually:
gws drive files list --params '{"pageSize": 3}'
If this returns JSON with file entries, authentication is working.
If it fails, check:
gws auth status — are credentials present?
- Are the right scopes enabled? Filter with:
gws auth login -s drive,gmail,sheets
- For unverified apps: did you add yourself as a test user in Google Cloud Console?
Authentication Precedence
gws checks credentials in this order (first match wins):
GOOGLE_WORKSPACE_CLI_TOKEN env var (raw access token)
GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE env var (path to credentials JSON)
- Encrypted credentials in
GOOGLE_WORKSPACE_CLI_CONFIG_DIR (from gws auth login)
- Plaintext
credentials.json in config dir
Quirk: If GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE is set but the file doesn't exist, gws fails immediately — it does NOT fall through to check the config dir. This is why the compose file only sets CONFIG_DIR and omits CREDENTIALS_FILE. All auth methods work through the config dir.
Scope Management
Unverified OAuth apps are limited to ~25 scopes. Filter to only what you need:
gws auth login -s drive,gmail,sheets,calendar,chat,docs
Available service filters: drive, gmail, sheets, calendar, chat, docs, admin, script, tasks, people, groups.
Environment Variables Reference
| Variable | Purpose |
|---|
GOOGLE_WORKSPACE_CLI_TOKEN | Pre-obtained OAuth2 access token (expires ~1hr, no refresh) |
GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE | Path to credentials.json (exported tokens or service account key) |
GOOGLE_WORKSPACE_CLI_CLIENT_ID | OAuth client ID (alternative to client_secret.json) |
GOOGLE_WORKSPACE_CLI_CLIENT_SECRET | OAuth client secret (alternative to client_secret.json) |
GOOGLE_WORKSPACE_CLI_CONFIG_DIR | Config dir override (default: ~/.config/gws) |
GOOGLE_WORKSPACE_CLI_LOG | Log level (e.g., gws=debug) |
GOOGLE_WORKSPACE_CLI_LOG_FILE | Log directory with daily rotation |
GOOGLE_WORKSPACE_PROJECT_ID | GCP project ID override |
GOOGLE_WORKSPACE_CLI_SANITIZE_TEMPLATE | Model Armor template path |
GOOGLE_WORKSPACE_CLI_SANITIZE_MODE | warn (default) or block |
Variables can also be set in a .env file (gws loads via dotenvy).
Quick Command Reference
After setup, verify access to key services:
gws drive files list --params '{"pageSize": 5}'
gws drive +upload ./report.pdf --name "Q1 Report"
gws gmail +triage
gws gmail +send --to user@example.com --subject "Hello" --body "Hi"
gws calendar +agenda --today
gws calendar +insert
gws sheets +read --spreadsheet ID --range "Sheet1!A1:C10"
gws sheets +append --spreadsheet ID --values "Alice,95"
gws chat +send
gws schema drive.files.list
Troubleshooting
| Problem | Fix |
|---|
| "Access blocked" on login | Add yourself as test user in Cloud Console > OAuth consent screen > Test users |
| Scope errors | Use -s service1,service2 to request only needed scopes |
| Token expired | Run gws auth login again, or gws auth export --unmasked to refresh credentials.json |
| Container can't find creds | Check knowledge/secrets/.gws/ exists and has credentials.json or encrypted creds |
| "gws not found" in container | Already included in assistant image — check PATH |
| Drive API not enabled | Run gws auth setup or enable Drive API in Cloud Console |
| Wrong client_secret.json | Must be "Desktop app" type, not "Web application" |
| Credentials work on host but not in container | Did you copy the .encryption_key too? Or use gws auth export --unmasked for plaintext |