Skip to main content
Use this approach to run gws commands in environments without a browser, such as:
  • GitHub Actions, GitLab CI, CircleCI
  • Docker containers
  • SSH sessions on remote servers
  • Automated scripts and cron jobs

Overview

The headless authentication flow:
  1. Authenticate interactively on a machine with a browser
  2. Export the encrypted credentials to a file
  3. Transfer the file to your CI/headless environment
  4. Set GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE to point to the file
  5. Run gws commands — they’ll “just work” with no login prompt

Export Credentials from Interactive Machine

1

Authenticate interactively

On your local development machine:
gws auth setup
# or
gws auth login
2

Export credentials

Export the decrypted credentials to a file:
gws auth export --unmasked > credentials.json
The exported file contains your OAuth client secret and refresh token in plaintext. Handle it carefully:
  • Do not commit to version control
  • Use encrypted CI secrets storage
  • Delete after uploading to CI
3

Verify the export

Check the exported file format:
cat credentials.json | jq
Expected format:
{
  "type": "authorized_user",
  "client_id": "123456789.apps.googleusercontent.com",
  "client_secret": "GOCSPX-...",
  "refresh_token": "1//..."
}

Configure CI Environment

Using Environment Variable

Set the path to your credentials file:
export GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE=/path/to/credentials.json
gws drive files list

Using CI Secrets

Most CI platforms support encrypted secrets. Store the credentials file content as a secret:

GitHub Actions

name: Workspace Automation

on: [push]

jobs:
  sync:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      
      - name: Install gws
        run: npm install -g @googleworkspace/cli
      
      - name: Set up credentials
        run: |
          mkdir -p ~/.config/gws
          echo '${{ secrets.GWS_CREDENTIALS }}' > ~/.config/gws/credentials.json
        
      - name: List Drive files
        env:
          GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE: /home/runner/.config/gws/credentials.json
        run: |
          gws drive files list --params '{"pageSize": 10}'
To set the secret:
  1. Go to your repo → Settings → Secrets and variables → Actions
  2. Click New repository secret
  3. Name: GWS_CREDENTIALS
  4. Value: Paste the contents of credentials.json

GitLab CI

workspace-sync:
  image: node:20
  before_script:
    - npm install -g @googleworkspace/cli
    - mkdir -p ~/.config/gws
    - echo "$GWS_CREDENTIALS" > ~/.config/gws/credentials.json
  script:
    - export GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE=~/.config/gws/credentials.json
    - gws drive files list --params '{"pageSize": 10}'
To set the variable:
  1. Go to Settings → CI/CD → Variables
  2. Add variable GWS_CREDENTIALS (masked)
  3. Paste the contents of credentials.json

CircleCI

version: 2.1

jobs:
  workspace-sync:
    docker:
      - image: cimg/node:20.0
    steps:
      - checkout
      - run:
          name: Install gws
          command: npm install -g @googleworkspace/cli
      - run:
          name: Set up credentials
          command: |
            mkdir -p ~/.config/gws
            echo "$GWS_CREDENTIALS" > ~/.config/gws/credentials.json
      - run:
          name: List Drive files
          command: |
            export GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE=~/.config/gws/credentials.json
            gws drive files list --params '{"pageSize": 10}'

workflows:
  main:
    jobs:
      - workspace-sync
To set the environment variable:
  1. Go to Project Settings → Environment Variables
  2. Add GWS_CREDENTIALS
  3. Paste the contents of credentials.json

Docker

FROM node:20-alpine

RUN npm install -g @googleworkspace/cli

# Copy credentials at build time (not recommended for production)
# COPY credentials.json /app/credentials.json

# Better: mount as volume or pass as secret at runtime
ENV GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE=/app/credentials.json

CMD ["gws", "drive", "files", "list"]
Run with mounted credentials:
docker run -v $(pwd)/credentials.json:/app/credentials.json my-gws-image

Using .env Files

gws automatically loads environment variables from a .env file in the current directory:
# .env
GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE=/path/to/credentials.json
Never commit .env files containing credentials to version control. Add .env to your .gitignore.

Credential Precedence

When running gws commands, credentials are resolved in this order:
PrioritySourceSet via
1Pre-obtained access tokenGOOGLE_WORKSPACE_CLI_TOKEN
2Credentials file (env var)GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE
3Encrypted credentials~/.config/gws/credentials.enc (from gws auth login)
4Plaintext credentials~/.config/gws/credentials.json
Environment variables can also be loaded from a .env file in the working directory.

Using Pre-Obtained Access Tokens

If another tool (e.g., gcloud, Application Default Credentials) already provides access tokens, you can bypass credential files entirely:
export GOOGLE_WORKSPACE_CLI_TOKEN=$(gcloud auth print-access-token)
gws drive files list
Access tokens expire quickly (typically 1 hour). This approach only works for short-lived scripts. For long-running CI jobs, use the refresh token method above.

Security Best Practices

  • Store credentials in GitHub Secrets, GitLab Variables, or CircleCI Environment Variables
  • Never hardcode credentials in workflow files
  • Use masked/protected variables when available
  • Create credentials with read-only scopes when possible:
    gws auth login --readonly
    gws auth export --unmasked > ci-credentials.json
    
  • Use different credentials for different CI jobs
  • Re-run gws auth login and export new credentials monthly
  • Update CI secrets after rotation
  • Run gws auth logout on the source machine after export
  • Monitor OAuth token usage in Google Cloud Console
  • Set up alerts for unusual API activity
  • Use service accounts for production workloads (see next section)

Debugging

Check which credentials are being used

gws auth status
Look for the credential_source field:
{
  "credential_source": "GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE",
  "plain_credentials": "/path/to/credentials.json",
  "plain_credentials_exists": true
}

Test authentication

# Minimal test
gws drive about get

# Test with verbose output
GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE=/path/to/credentials.json \
  gws drive files list --params '{"pageSize": 1}'

Limitations

  • Exported credentials are tied to the OAuth client used during gws auth login
  • If the original OAuth client is deleted in GCP Console, the credentials will stop working
  • Refresh tokens can be revoked by the user at https://myaccount.google.com/permissions

When to Use Service Accounts Instead

Consider using service accounts if:
  • You need credentials that never expire
  • You’re running automated workflows in a Google Workspace domain with Domain-Wide Delegation
  • You want credentials that aren’t tied to a specific user account
  • You need to access resources across multiple user accounts

Next Steps

Service Accounts

Use service accounts for server-to-server authentication

Interactive Auth

Return to local development setup