- Don’t require browser-based login
- Don’t expire (until the key is rotated)
- Can use Domain-Wide Delegation to act on behalf of users
- Are ideal for production automation and CI/CD
When to Use Service Accounts
Use service accounts when:- Running automated workflows that access Google Workspace data
- Building applications that need to access resources across multiple user accounts
- Deploying to production environments (servers, Kubernetes, Cloud Run)
- You have a Google Workspace domain with admin access (required for Domain-Wide Delegation)
- Developing locally on your personal machine
- Accessing only your own Google account
- You don’t have Google Workspace admin permissions
Setup Overview
Enable Domain-Wide Delegation (optional)
If you need to access other users’ data, enable Domain-Wide Delegation in Google Workspace Admin.
Creating a Service Account
Open Google Cloud Console
Navigate to IAM & Admin > Service Accounts:
Create service account
- Click Create Service Account
- Service account name:
gws-automation(or your preferred name) - Service account ID:
gws-automation(auto-filled) - Description: “Service account for gws CLI automation”
- Click Create and Continue
- Skip granting roles (click Continue, then Done)
For Workspace APIs, service accounts don’t need IAM roles in the GCP project. Permissions are granted through OAuth scopes and Domain-Wide Delegation.
Create and download key
- Click on the newly created service account
- Go to the Keys tab
- Click Add Key → Create new key
- Select JSON format
- Click Create
Enable required APIs
Using the Service Account
Basic Usage (No Domain-Wide Delegation)
For APIs that don’t require user impersonation (e.g., accessing the service account’s own Drive):gws automatically detects service account credentials by the "type": "service_account" field.With Domain-Wide Delegation (Impersonation)
To access another user’s data (e.g., read their Gmail, Drive files), you must:- Enable Domain-Wide Delegation for the service account
- Grant OAuth scopes in Google Workspace Admin Console
- Set the
GOOGLE_WORKSPACE_CLI_IMPERSONATED_USERenvironment variable
Enabling Domain-Wide Delegation
Enable Domain-Wide Delegation in GCP
- Go to Service Accounts
- Click on your service account
- Click Show advanced settings
- Under Domain-wide delegation, click Enable Google Workspace Domain-wide Delegation
- Product name for consent screen:
gws CLI - Click Save
Grant API scopes in Workspace Admin
- Open Google Workspace Admin Console
- Navigate to Security → Access and data control → API controls
- Click Manage Domain Wide Delegation
- Click Add new
- Client ID: Paste the service account’s Client ID from step 1
- OAuth scopes: Enter the scopes your automation needs (comma-separated):
- Click Authorize
Common OAuth Scopes for Domain-Wide Delegation
| Service | Scope |
|---|---|
| Google Drive (read/write) | https://www.googleapis.com/auth/drive |
| Google Drive (read-only) | https://www.googleapis.com/auth/drive.readonly |
| Gmail (read/write) | https://www.googleapis.com/auth/gmail.modify |
| Gmail (read-only) | https://www.googleapis.com/auth/gmail.readonly |
| Google Calendar | https://www.googleapis.com/auth/calendar |
| Google Sheets | https://www.googleapis.com/auth/spreadsheets |
| Google Docs | https://www.googleapis.com/auth/documents |
| Google Slides | https://www.googleapis.com/auth/presentations |
You must list all scopes your automation will use in the Workspace Admin Console. Service accounts cannot request additional scopes at runtime.
CI/CD Integration
GitHub Actions
- Go to repo Settings → Secrets → Actions
- Add
GWS_SERVICE_ACCOUNT - Paste the entire contents of the service account JSON file
Docker
Kubernetes Secret
Environment Variables Reference
| Variable | Description | Example |
|---|---|---|
GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE | Path to service account JSON | /app/service-account.json |
GOOGLE_WORKSPACE_CLI_IMPERSONATED_USER | User email to impersonate (requires DWD) | admin@example.com |
Security Best Practices
Restrict service account permissions
Restrict service account permissions
- Grant the minimum OAuth scopes required in Workspace Admin
- Use separate service accounts for different automation workflows
- Regularly audit service account usage in the Admin Console
Secure the private key
Secure the private key
- Never commit service account keys to version control
- Store keys in encrypted secrets managers (GitHub Secrets, Vault, Cloud Secret Manager)
- Rotate keys every 90 days
- Delete unused service account keys immediately
Use impersonation narrowly
Use impersonation narrowly
- Only impersonate the specific users required
- Avoid impersonating super admin accounts
- Log all impersonated actions for audit trails
Monitor usage
Monitor usage
- Enable audit logging in Google Workspace Admin
- Set up alerts for unexpected API usage
- Review service account activity monthly
Troubleshooting
”Subject (user to impersonate) is required” Error
You’re trying to access user data without settingGOOGLE_WORKSPACE_CLI_IMPERSONATED_USER:
“Not authorized to access this resource” Error
Possible causes:- Domain-Wide Delegation not enabled: Follow steps in “Enabling Domain-Wide Delegation”
- Scopes not granted in Workspace Admin: Verify scopes in Admin Console → Security → API Controls → Domain Wide Delegation
- Wrong Client ID: Ensure you used the service account’s Client ID (not the numeric User ID)
- API not enabled: Enable required APIs in GCP Console
”Invalid JWT Signature” Error
The service account key file is corrupted or invalid:- Re-download the JSON key from GCP Console
- Verify the file contains
-----BEGIN PRIVATE KEY-----and-----END PRIVATE KEY----- - Check that the file wasn’t modified (no extra whitespace, encoding issues)
Credential Precedence
When both user OAuth and service account credentials are available:GOOGLE_WORKSPACE_CLI_TOKEN(pre-obtained access token, highest priority)GOOGLE_WORKSPACE_CLI_CREDENTIALS_FILE(can be user OAuth or service account)- Encrypted user credentials (
~/.config/gws/credentials.enc) - Plaintext user credentials (
~/.config/gws/credentials.json)
gws detects service account vs user OAuth by inspecting the "type" field in the JSON file.
Comparison: Service Accounts vs User OAuth
| Feature | Service Account | User OAuth |
|---|---|---|
| Setup complexity | High (requires Workspace admin) | Low (just gws auth login) |
| Requires browser | No | Yes (for initial setup) |
| Credential lifetime | Until key is rotated | Until refresh token revoked |
| Access multiple users | Yes (with DWD) | No (only authenticated user) |
| Works in CI/CD | Yes | Yes (after export) |
| Audit trail | Service account name | User email |
| Best for | Production automation | Local development |
Next Steps
Headless/CI Auth
Learn about user OAuth credentials in CI/CD
Interactive Auth
Set up OAuth for local development