Google Services Secure
by @nelmaz
Secure Google Workspace integration (Gmail, Drive, Calendar, Sheets, Docs, Contacts, etc.) with enterprise-grade security. Features credential isolation, inp...
clawhub install google-services-secureπ About This Skill
name: google-services-secure description: Secure Google Workspace integration (Gmail, Drive, Calendar, Sheets, Docs, Contacts, etc.) with enterprise-grade security. Features credential isolation, input validation, audit logging, rate limiting, and granular permissions. Use when working with Google APIs, sending emails, managing files, scheduling calendar events, or automating Google Workspace workflows. version: "1.0.0" metadata: author: nelson-mazonzika homepage: https://clawhub.ai/nelson-mazonzika/google-services-secure license: MIT openclaw: emoji: π requires: bins: [] env: - GOOGLE_API_KEY - GOOGLE_CLIENT_ID - GOOGLE_CLIENT_SECRET node: ">=18.0.0" security: level: enterprise features: - credential-isolation - input-validation - audit-logging - rate-limiting - granular-permissions - sandbox-support - oauth-2.0-flow - https-only - confirmation-required tested: true audit-trail: true
Google Services Secure
π Security First
This skill implements enterprise-grade security protections for Google Workspace APIs:
β οΈ Before Using
CRITICAL SECURITY REQUIREMENTS:
1. Environment Variables MUST be Set:
# NEVER store these in openclaw.json or any config file
export GOOGLE_API_KEY="your-api-key"
export GOOGLE_CLIENT_ID="your-client-id"
export GOOGLE_CLIENT_SECRET="your-client-secret"
export GOOGLE_REDIRECT_URI="http://localhost:8080/callback"
2. First-Time Setup Required:
cd /data/.openclaw/workspace/skills/google-services-secure
./scripts/validate-setup.sh
3. OAuth 2.0 Flow:
# Generate OAuth URL and authenticate
./scripts/auth-google.sh
Quick Start
1. Configure Environment Variables
# Add to ~/.bashrc or /etc/environment
export GOOGLE_API_KEY="your-api-key"
export GOOGLE_CLIENT_ID="your-client-id.apps.googleusercontent.com"
export GOOGLE_CLIENT_SECRET="your-client-secret"
export GOOGLE_REDIRECT_URI="http://localhost:8080/callback"Reload shell
source ~/.bashrc
2. Validate Setup
cd /data/.openclaw/workspace/skills/google-services-secure
./scripts/validate-setup.sh
This will:
3. Authenticate via OAuth 2.0
cd /data/.openclaw/workspace/skills/google-services-secure
./scripts/auth-google.sh
This will:
4. List Gmail Messages (Read-Only)
curl -s "https://gmail.googleapis.com/gmail/v1/users/me/messages?maxResults=10" \
-H "Authorization: Bearer $ACCESS_TOKEN"
-H "Content-Type: application/json"
Security Architecture
Credential Management
β NEVER do this:
{
"env": {
"GOOGLE_API_KEY": "AIza...", // β INSECURE
"GOOGLE_CLIENT_ID": "...apps.googleusercontent.com", // β INSECURE
"GOOGLE_CLIENT_SECRET": "..." // β CRITICAL SECURITY ISSUE
}
}
β CORRECT approach:
# Set at system level, never in files
export GOOGLE_API_KEY="your-api-key"
export GOOGLE_CLIENT_ID="your-client-id.apps.googleusercontent.com"
export GOOGLE_CLIENT_SECRET="your-client-secret"
OAuth 2.0 Authorization Flow
Step 1: Generate Authorization URL
https://accounts.google.com/o/oauth2/v2/auth?client_id=$GOOGLE_CLIENT_ID \
&redirect_uri=$GOOGLE_REDIRECT_URI \
&response_type=code \
&scope=https://www.googleapis.com/auth/gmail.readonly,https://www.googleapis.com/auth/drive.readonly
Step 2: Exchange Code for Token
curl -X POST https://oauth2.googleapis.com/token \
-H "Content-Type: application/x-www-form-urlencoded" \
-d "client_id=$GOOGLE_CLIENT_ID" \
-d "client_secret=$GOOGLE_CLIENT_SECRET" \
-d "code=$AUTHORIZATION_CODE" \
-d "redirect_uri=$GOOGLE_REDIRECT_URI" \
-d "grant_type=authorization_code"
Permissions System
The skill operates in three permission modes:
| Mode | Read | Write | Delete | Share | Risk Level |
|-------|------|-------|---------|-------|-------------|
| readonly | β
| β | β | β | π’ LOW |
| restricted | β
| β
* | β | β | π‘ MEDIUM |
| full | β
| β
| β
* | β
* | π΄ HIGH |
* Requires explicit confirmation for each operation
Default mode: readonly
To change mode:
export GOOGLE_PERMISSION_MODE="readonly" # Recommended for production
Audit Logging
All actions are logged to:
/data/.openclaw/logs/google-services-audit.log
Log format:
{
"timestamp": "2024-04-04T00:30:45.123Z",
"user": "nelson",
"service": "gmail",
"action": "LIST_MESSAGES",
"status": "success",
"messageCount": 10,
"durationMs": 234,
"permissionMode": "readonly"
}
Rate Limiting
Default limits (configurable):
| Service | Limit | Window | |---------|-------|---------| | Gmail API | 100 | per minute | | Drive API | 500 | per minute | | Calendar API | 100 | per minute | | Sheets API | 100 | per minute | | Contacts API | 50 | per minute |
Customize limits:
export GOOGLE_RATE_LIMIT_GMAIL="100/minute"
export GOOGLE_RATE_LIMIT_DRIVE="500/minute"
Available Services
π§ Gmail (gmail.googleapis.com)
#### 1. List Messages
curl -s "https://gmail.googleapis.com/gmail/v1/users/me/messages?maxResults=10" \
-H "Authorization: Bearer $ACCESS_TOKEN"
#### 2. Get Message
curl -s "https://gmail.googleapis.com/gmail/v1/users/me/messages/$MESSAGE_ID" \
-H "Authorization: Bearer $ACCESS_TOKEN"
#### 3. Send Email (Requires Permission) β οΈ Confirmation required before sending
curl -X POST "https://gmail.googleapis.com/gmail/v1/users/me/messages/send" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"raw": "From: me@example.com\r\nTo: recipient@example.com\r\nSubject: Test\r\n\r\nTest message body"
}'
πΎ Google Drive (drive.googleapis.com)
#### 1. List Files
curl -s "https://www.googleapis.com/drive/v3/files?pageSize=10" \
-H "Authorization: Bearer $ACCESS_TOKEN"
#### 2. Upload File (Requires Permission) β οΈ Confirmation required before uploading
curl -X POST "https://www.googleapis.com/upload/drive/v3/files?uploadType=multipart" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-F "metadata={\"name\":\"test.txt\"};type=application/json; charset=UTF-8" \
-F "file=@test.txt"
#### 3. Download File
curl -s "https://www.googleapis.com/drive/v3/files/$FILE_ID?alt=media" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-O downloaded_file.txt
π Google Calendar (calendar.googleapis.com)
#### 1. List Events
curl -s "https://www.googleapis.com/calendar/v3/calendars/primary/events?maxResults=10" \
-H "Authorization: Bearer $ACCESS_TOKEN"
#### 2. Create Event (Requires Permission) β οΈ Confirmation required before creating
curl -X POST "https://www.googleapis.com/calendar/v3/calendars/primary/events" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"summary": "Meeting",
"start": {"dateTime": "2024-04-04T10:00:00Z"},
"end": {"dateTime": "2024-04-04T11:00:00Z"}
}'
π Google Sheets (sheets.googleapis.com)
#### 1. List Spreadsheets
curl -s "https://sheets.googleapis.com/v4/spreadsheets" \
-H "Authorization: Bearer $ACCESS_TOKEN"
#### 2. Read Sheet Values
curl -s "https://sheets.googleapis.com/v4/spreadsheets/$SPREADSHEET_ID/values/Sheet1!A1:B10" \
-H "Authorization: Bearer $ACCESS_TOKEN"
#### 3. Update Sheet (Requires Permission) β οΈ Confirmation required before updating
curl -X PUT "https://sheets.googleapis.com/v4/spreadsheets/$SPREADSHEET_ID/values/Sheet1!A1:B10" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"values": [["New Value"]]
}'
π Google Docs (docs.googleapis.com)
#### 1. List Documents
curl -s "https://www.googleapis.com/drive/v3/files?q=mimeType%3D'application/vnd.google-apps.document'" \
-H "Authorization: Bearer $ACCESS_TOKEN"
#### 2. Get Document Content
curl -s "https://www.googleapis.com/drive/v3/files/$DOC_ID/export?mimeType=text/plain" \
-H "Authorization: Bearer $ACCESS_TOKEN"
π₯ Google Contacts (people.googleapis.com)
#### 1. List Connections
curl -s "https://people.googleapis.com/v1/people/me/connections?personFields=names,emailAddresses" \
-H "Authorization: Bearer $ACCESS_TOKEN"
#### 2. Create Contact (Requires Permission) β οΈ Confirmation required before creating
curl -X POST "https://people.googleapis.com/v1/people:createContact" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"emailAddresses": [{"value": "new@example.com"}],
"names": [{"givenName": "John", "familyName": "Doe"}]
}'
Input Validation
Email Validation
function validateEmail(email) {
// Must be valid email format
if (!email.match(/^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/)) {
throw new Error('Invalid email format');
} // No dangerous characters
if (email.match(/