* security: path traversal, query bounds, marker injection fixes LocalStorage: contained() method validates all paths stay within storage root. file-resolver: resolveFile validates filePath within brainRoot, marker prefix rejects ../, absolute paths, bare '..'. file_list: LIMIT 100 on slug-filtered branch + FILE_LIST_LIMIT constant for both branches. Co-Authored-By: Gus <garagon@users.noreply.github.com> * security: symlink hardening in all file walkers All 4 walkers in files.ts (collectFiles, findRedirects, findAndClean, scan) plus init.ts counter now use lstatSync + isSymbolicLink skip. Tests import production collectFiles instead of reimplementing it. node_modules skipped. CLI file list and verify queries bounded with LIMIT. Co-Authored-By: Gus <garagon@users.noreply.github.com> * feat: typed health check DSL + recipe migration 4 DSL types: http, env_exists, command, any_of. Replaces raw execSync on recipe YAML. All 7 first-party recipes migrated from shell strings to typed objects. String health_checks still accepted with deprecation warning + metachar validation for non-embedded recipes. isUnsafeHealthCheck blocks shell injection for user-created recipes. Co-Authored-By: Gus <garagon@users.noreply.github.com> * chore: bump version and changelog (v0.9.3) Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> * test: E2E test for file_list LIMIT enforcement against real Postgres Inserts 150 file rows for one slug, verifies file_list returns at most 100 (both slug-filtered and unfiltered branches). Proves the LIMIT works at the database level, not just in unit tests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com> --------- Co-authored-by: Gus <garagon@users.noreply.github.com> Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
7.1 KiB
id, name, version, description, category, requires, secrets, health_checks, setup_time, cost_estimate
| id | name | version | description | category | requires | secrets | health_checks | setup_time | cost_estimate | |||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| credential-gateway | Credential Gateway | 0.7.0 | Secure access to Gmail, Google Calendar, and other Google services. ClawVisor (recommended) or direct Google OAuth. | infra |
|
|
15 min | $0 (both options are free) |
Credential Gateway: Secure Access to Google Services
Gmail, Google Calendar, Google Contacts, and other services require OAuth credentials. This recipe sets up secure access that email-to-brain and calendar-to-brain depend on.
IMPORTANT: Instructions for the Agent
You are the installer. Other recipes depend on this one. If the user wants email-to-brain or calendar-to-brain, set up credential-gateway FIRST.
Two options, both free:
- Option A: ClawVisor — handles OAuth, token refresh, and encryption for you. No token management. If you use multiple Google services, set up ClawVisor once and all recipes use it.
- Option B: Google OAuth directly — no extra service, but you manage tokens yourself. Good if you don't want another dependency.
Do not skip steps. Verify after each step.
Setup Flow
Step 1: Choose Your Gateway
Ask the user: "How do you want to connect to Google services (Gmail, Calendar)?
Option A: ClawVisor (recommended) ClawVisor handles OAuth, token refresh, and encryption. Set it up once and email-to-brain, calendar-to-brain, and any future Google service recipes all use the same credentials. No token management on your end.
Option B: Google OAuth2 directly Connect to Google APIs directly. No extra service. But you manage OAuth tokens yourself (they expire, need refresh)."
Option A: ClawVisor Setup
Tell the user: "1. Go to https://clawvisor.com and create an account 2. Create an agent (or use existing one) 3. Activate the services you need:
- Gmail (for email-to-brain)
- Google Calendar (for calendar-to-brain)
- Google Contacts (for enrichment)
-
Create a standing task with a broad purpose. CRITICAL: be EXPANSIVE.
Good purpose: 'Full executive assistant access to Gmail, Calendar, and Contacts including inbox triage, event listing, contact lookup, and historical data access for all connected Google accounts.'
Bad purpose: 'email triage' — too narrow, blocks legitimate requests.
-
Copy the Gateway URL and Agent Token and paste them to me"
Validate:
curl -sf "$CLAWVISOR_URL/health" \
&& echo "PASS: ClawVisor reachable" \
|| echo "FAIL: ClawVisor not reachable — check the URL"
STOP until ClawVisor validates.
Option B: Google OAuth2 Setup
Tell the user: "I need Google OAuth2 credentials. Here's exactly how:
- Go to https://console.cloud.google.com/apis/credentials (create a Google Cloud project if you don't have one — it's free)
- Click '+ CREATE CREDENTIALS' at the top > 'OAuth client ID'
- If prompted to configure the consent screen:
- User type: External (or Internal for Google Workspace)
- App name: 'GBrain' (anything works)
- Scopes: add the ones you need:
- Gmail:
https://www.googleapis.com/auth/gmail.readonly - Calendar:
https://www.googleapis.com/auth/calendar.readonly - Contacts:
https://www.googleapis.com/auth/contacts.readonly
- Gmail:
- Test users: add your own email address
- Create the OAuth client ID:
- Application type: Desktop app
- Name: 'GBrain'
- Click 'Create' — copy the Client ID and Client Secret
- Enable the APIs you need:
- Gmail: https://console.cloud.google.com/apis/library/gmail.googleapis.com
- Calendar: https://console.cloud.google.com/apis/library/calendar-json.googleapis.com Click 'Enable' on each one.
Paste the Client ID and Client Secret to me."
Validate:
[ -n "$GOOGLE_CLIENT_ID" ] && [ -n "$GOOGLE_CLIENT_SECRET" ] \
&& echo "PASS: Google OAuth credentials set" \
|| echo "FAIL: Missing GOOGLE_CLIENT_ID or GOOGLE_CLIENT_SECRET"
Then run the OAuth flow:
// The first time a recipe uses these credentials, it will:
// 1. Open a browser to the Google consent URL
// 2. User grants access
// 3. Script receives auth code, exchanges for access + refresh token
// 4. Stores tokens in ~/.gbrain/google-tokens.json
// 5. Auto-refreshes when tokens expire (refresh token is long-lived)
STOP until OAuth credentials validate.
Step 2: Log Setup Completion
mkdir -p ~/.gbrain/integrations/credential-gateway
echo '{"ts":"'$(date -u +%Y-%m-%dT%H:%M:%SZ)'","event":"setup_complete","source_version":"0.7.0","status":"ok","details":{"type":"CLAWVISOR_OR_GOOGLE"}}' >> ~/.gbrain/integrations/credential-gateway/heartbeat.jsonl
Tell the user: "Credential gateway is set up. Email-to-brain and calendar-to-brain can now access your Google services."
Tricky Spots
-
ClawVisor task purpose must be EXPANSIVE. "Email triage" is too narrow and blocks legitimate requests. Use a broad purpose that covers everything you might want to do with email. The intent verification model checks each request against the purpose. Narrow = blocked.
-
Google OAuth tokens expire. Access tokens last ~1 hour. The refresh token is long-lived but can be revoked. Store both in
~/.gbrain/google-tokens.jsonwith 0600 permissions. The script should auto-refresh on 401. -
Google consent screen in "Testing" mode limits to 100 users and tokens expire weekly. For personal use this is fine. For production, publish the app.
-
Multiple Google accounts. If you have work + personal Gmail, you need to authorize each one separately in the OAuth flow. ClawVisor handles this automatically.
How to Verify
- ClawVisor:
curl $CLAWVISOR_URL/healthreturns OK. - Google OAuth: Tokens exist at
~/.gbrain/google-tokens.json. - Gmail access: Run the email collector — it should pull recent messages.
- Calendar access: Run the calendar sync — it should pull today's events.
Cost Estimate
| Component | Monthly Cost |
|---|---|
| ClawVisor | $0 (free tier) |
| Google OAuth | $0 (free, no billing needed for personal use) |
Part of the GBrain Skillpack. See also: Email-to-Brain, Calendar-to-Brain