An OpenClaw plugin that gives AI agents access to Google Workspace (Gmail, Calendar, etc.) using Civic for OAuth. No Google Cloud project, no local credentials, no token management.
Without this plugin, giving an agent access to Google APIs via gog requires:
- Creating a Google Cloud project, enabling APIs, and configuring the OAuth consent screen
- Generating OAuth client credentials (
credentials.json) - Running
gog auth credentials set credentials.jsonthengog auth add you@gmail.com— which opens a browser and stores a refresh token in your local keyring - Dealing with token expiry, revocation, and refresh failures yourself
- Accepting that
gogrequests broad scopes by default — e.g.,gmail.modify+gmail.settings.basic+gmail.settings.sharingeven if your agent only reads email
Every user who runs the agent has to do this themselves.
With this plugin, the setup is:
openclaw plugins install @civic/openclaw-googleCivic provides the OAuth client, stores tokens encrypted server-side, refreshes them automatically, and the plugin requests only the scope each command actually needs.
Agent calls "gog gmail search ..."
│
▼
Plugin intercepts (before_tool_call hook)
│
▼
Matches "gog gmail" → needs google-gmail-read (gmail.readonly)
│
▼
Fetches token from Civic ──→ Token ready? → Inject GOG_ACCESS_TOKEN → gog runs
└→ Not authorized? → Block with auth URL for user
└→ Token expired? → Civic already refreshed it → inject and run
The agent and gog never see OAuth client credentials or refresh tokens. They get a short-lived access token injected via environment variable.
On first use for a given scope, the agent surfaces an authorization URL. The user clicks it, consents once, and all future calls for that scope work automatically.
gog's native auth requests broad scopes per service. This plugin maps each subcommand to the minimum scope needed:
| Agent action | Scope via this plugin | Scope via native gog auth |
|---|---|---|
| Read/search email | gmail.readonly |
gmail.modify + gmail.settings.basic + gmail.settings.sharing |
| Send email | gmail.send |
(same broad set) |
| Create/edit drafts | gmail.compose |
(same broad set) |
| Trash/archive email | gmail.modify |
(same broad set) |
| Read calendar | calendar.readonly |
calendar (full read/write) |
| Create/update/delete events | calendar.events |
calendar (full read/write) |
Each scope requires separate user consent. An agent that only reads email cannot send or delete it.
openclaw plugins install @civic/openclaw-googlebrew install gogAdd to the OpenClaw gateway environment:
NEXUS_TOKEN=<your-civic-api-token>Get your token from nexus.civic.com → Settings → API Keys.
Ask your agent to read email, check your calendar, draft a reply. On first use per scope, you'll see an authorization link to click.
| Command | Credential ID | Scope |
|---|---|---|
gog gmail send |
google-gmail-send |
gmail.send |
gog gmail drafts / draft |
google-gmail-draft |
gmail.compose |
gog gmail trash / archive / read / unread / batch |
google-gmail-modify |
gmail.modify |
gog gmail (everything else) |
google-gmail-read |
gmail.readonly |
gog calendar create / update / delete / respond / subscribe |
google-calendar-write |
calendar.events |
gog calendar (everything else) |
google-calendar-read |
calendar.readonly |
Mappings are evaluated most-specific first — gog gmail send matches before the gog gmail catch-all.
The plugin works out of the box after install. To customize, edit ~/.openclaw/openclaw.json:
{
"plugins": {
"entries": {
"civic-google": {
"enabled": true
}
}
}
}To add mappings for additional Google services (e.g., Drive):
{
"plugins": {
"entries": {
"civic-google": {
"enabled": true,
"config": {
"credentialMappings": [
{
"credentialId": "google-drive-read",
"envVar": "GOG_ACCESS_TOKEN",
"toolMatch": "exec:gog drive"
}
]
}
}
}
}
}Default: https://nexus.civic.com/ext/openclaw. For local development:
OPENCLAW_PROXY_URL=http://localhost:3013/openclaw- Tokens are stored in Civic's encrypted store (AES-256), not on the agent's machine
- Access tokens are short-lived (~1 hour) and refreshed automatically server-side
- Each subcommand gets only the scope it needs, with separate user consent per scope
- Revoking access in Civic invalidates all tokens immediately
- The agent never sees OAuth client secrets or refresh tokens
MIT