-
Notifications
You must be signed in to change notification settings - Fork 1
Adds Google Drive API support and Service Account Auth #78
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
4eaff08
Adds Google Drive API support
Forbrig cef3c28
Update package lock
Forbrig ef6a161
Regenerate package-lock.json to fix CI npm ci sync issues
Forbrig c34bbc9
Add explicit zod dependency to fix peer dependency conflicts in CI
Forbrig 1b3131c
Add hono and picomatch dependencies to fix peer dependency issues in CI
Forbrig 32ebf31
Doc changes
Forbrig 07b86ed
Doc changes
Forbrig 4027173
Doc changes and google header validation
Forbrig File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,4 +8,5 @@ node_modules/ | |
| .DS_Store | ||
| /blob-report/ | ||
| /dist/ | ||
| /cache/ | ||
| /cache/ | ||
| google.json | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,227 @@ | ||
| # Google Service Account Setup | ||
|
|
||
| ## Overview | ||
|
|
||
| Google service accounts allow server-to-server authentication without user interaction. Service account credentials are JSON key files that contain a private key for signing requests to Google APIs. | ||
|
|
||
| **🚨 TEMPORARY PROOF OF CONCEPT** | ||
|
|
||
| The `X-Google-Json` header currently accepts **unencrypted** service account JSON keys. This will be replaced with an encrypted key mechanism soon. Until then, only use for internal testing and local development. | ||
|
|
||
| **⚠️ CRITICAL SECURITY WARNING** | ||
|
|
||
| Service account keys are **EXTREMELY DANGEROUS**: | ||
| - **Keys DO NOT expire** - They remain valid until manually revoked | ||
| - **Full access** - Anyone with the key has complete access to resources shared with the service account | ||
| - **No user context** - Keys work even if you're not logged in | ||
| - **Irreversible access** - Leaked keys can be used immediately by attackers | ||
|
|
||
| **DO NOT:** | ||
| - ❌ Commit service account keys to version control | ||
| - ❌ Send keys via email, Slack, or insecure channels | ||
| - ❌ Store keys in client-side applications or public-facing code | ||
| - ❌ Use the X-Google-Json API header outside of secure server-to-server environments | ||
| - ❌ Share keys with untrusted parties | ||
| - ❌ Use this in any production environment | ||
|
|
||
| **ONLY USE FOR:** | ||
| - ✅ Internal testing and local development | ||
| - ✅ Demonstration purposes in secure environments | ||
|
|
||
| ## Creating a Service Account | ||
|
|
||
| ### Step 1: Access Google Cloud Console | ||
|
|
||
| 1. Go to [Google Cloud Console](https://console.cloud.google.com/) | ||
| 2. Select your project (or create a new one) | ||
| 3. Note your project ID for reference | ||
|
|
||
| ### Step 2: Enable Google Drive API | ||
|
|
||
| 1. Navigate to **APIs & Services** → **Library** | ||
| 2. Search for "Google Drive API" | ||
| 3. Click **Enable** | ||
| 4. Wait for enablement (~30 seconds) | ||
|
|
||
| ### Step 3: Create Service Account | ||
|
|
||
| 1. Navigate to **IAM & Admin** → **Service Accounts** | ||
| 2. Click **Create Service Account** | ||
|
|
||
| 3. Fill in details: | ||
| - **Service account name**: `cascade-mcp-drive` (or your preferred name) | ||
| - **Service account ID**: Auto-generated (e.g., `[email protected]`) | ||
| - **Description**: "Service account for CascadeMCP Google Drive integration" | ||
|
|
||
| 4. Click **Create and Continue** | ||
|
|
||
| 5. **Grant permissions** (Optional): | ||
| - For most use cases, you can skip this step | ||
| - Service accounts access only files explicitly shared with them | ||
| - If needed, add roles like "Editor" or specific Drive roles | ||
|
|
||
| 6. Click **Continue** | ||
|
|
||
| 7. **Grant users access** (Optional): | ||
| - Skip this step for typical use cases | ||
|
|
||
| 8. Click **Done** | ||
|
|
||
| ### Step 4: Create and Download Key | ||
|
|
||
| 1. Find your newly created service account in the list | ||
| 2. Click on the service account email | ||
| 3. Go to **Keys** tab | ||
| 4. Click **Add Key** → **Create new key** | ||
| 5. Select **JSON** format | ||
| 6. Click **Create** | ||
| 7. **IMPORTANT**: The JSON file downloads automatically: | ||
| - Save it securely immediately | ||
| - Rename it to `google.json` (or your preferred name) | ||
| - **This is your only chance to download this key** | ||
| - If lost, you must create a new key | ||
|
|
||
| ### Step 5: Secure the Key File | ||
|
|
||
| Place the key in your project root and ensure it's ignored by git: | ||
|
|
||
| ```bash | ||
| # Move to project root | ||
| mv ~/Downloads/project-id-*.json ./google.json | ||
|
|
||
| # Verify .gitignore is working | ||
| git status # google.json should NOT appear in untracked files | ||
| ``` | ||
|
|
||
| **Add to `.gitignore`** (if not already present): | ||
|
|
||
| ```gitignore | ||
| # Google Service Account Keys | ||
| google.json | ||
| ``` | ||
|
|
||
| ## Service Account JSON Structure | ||
|
|
||
| The downloaded JSON file contains: | ||
|
|
||
| ```json | ||
| { | ||
| "type": "service_account", | ||
| "project_id": "your-project-id", | ||
| "private_key_id": "abc123...", | ||
| "private_key": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----\n", | ||
| "client_email": "[email protected]", | ||
| "client_id": "123456789...", | ||
| "auth_uri": "https://accounts.google.com/o/oauth2/auth", | ||
| "token_uri": "https://oauth2.googleapis.com/token", | ||
| "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs", | ||
| "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/...", | ||
| "universe_domain": "googleapis.com" | ||
| } | ||
| ``` | ||
|
|
||
| **Key fields:** | ||
| - `type`: Must be `"service_account"` | ||
| - `project_id`: Your Google Cloud project ID | ||
| - `private_key`: RSA private key for signing JWT tokens | ||
| - `client_email`: Service account email (used to share files) | ||
|
|
||
| ## Granting Access to Files | ||
|
|
||
| Service accounts can only access Google Drive files that are explicitly shared with them: | ||
|
|
||
| ### Share a File with Service Account | ||
|
|
||
| 1. Open Google Drive | ||
| 2. Right-click on a file or folder | ||
| 3. Click **Share** | ||
| 4. Enter the service account email: | ||
| ``` | ||
| [email protected] | ||
| ``` | ||
| 5. Set permission level: | ||
| - **Viewer**: Read-only access | ||
| - **Commenter**: View and comment | ||
| - **Editor**: Full edit access | ||
| 6. Uncheck "Notify people" (service accounts can't receive emails) | ||
| 7. Click **Share** | ||
|
|
||
| **Important Notes:** | ||
| - Service accounts appear as regular users in sharing dialogs | ||
| - They cannot access files in "My Drive" unless explicitly shared | ||
| - Sharing with a service account is the ONLY way it can access files | ||
| - Service accounts cannot interact with Google Drive UI | ||
|
|
||
| ## Testing the Service Account | ||
|
|
||
| ### Direct Client Test | ||
|
|
||
| Test the service account credentials directly: | ||
|
|
||
| ```bash | ||
| node --import ./loader.mjs scripts/api/drive-about-user.ts | ||
| ``` | ||
|
|
||
| This will display the service account's email and permission ID. | ||
|
|
||
| ### API Endpoint Test | ||
|
|
||
| **Test with curl:** | ||
| ```bash | ||
| # Make sure server is running: npm run dev | ||
|
|
||
| curl -X POST http://localhost:3000/api/drive-about-user \ | ||
| -H "Content-Type: application/json" \ | ||
| -H "X-Google-Json: $(cat google.json)" \ | ||
| -d '{}' | ||
| ``` | ||
|
|
||
| **Test with Node.js:** | ||
| ```javascript | ||
| const fs = require('fs'); | ||
|
|
||
| const serviceAccountJson = fs.readFileSync('./google.json', 'utf-8'); | ||
|
|
||
| const response = await fetch('http://localhost:3000/api/drive-about-user', { | ||
| method: 'POST', | ||
| headers: { | ||
| 'Content-Type': 'application/json', | ||
| 'X-Google-Json': serviceAccountJson, | ||
| }, | ||
| body: JSON.stringify({}), | ||
| }); | ||
|
|
||
| const data = await response.json(); | ||
| console.log(`User: ${data.user.displayName}`); | ||
| console.log(`Email: ${data.user.emailAddress}`); | ||
| ``` | ||
|
|
||
| ## Revoking Service Account Keys | ||
|
|
||
| If a key is compromised or no longer needed: | ||
|
|
||
| ### Option 1: Delete the Key | ||
|
|
||
| 1. Go to **IAM & Admin** → **Service Accounts** | ||
| 2. Click on the service account | ||
| 3. Go to **Keys** tab | ||
| 4. Find the key (by Key ID) | ||
| 5. Click ⋮ (three dots) → **Delete** | ||
| 6. Confirm deletion | ||
|
|
||
| **Effect:** Key becomes invalid immediately and cannot be restored | ||
|
|
||
| ### Option 2: Delete the Service Account | ||
|
|
||
| 1. Go to **IAM & Admin** → **Service Accounts** | ||
| 2. Check the box next to the service account | ||
| 3. Click **Delete** (trash icon) | ||
| 4. Confirm deletion | ||
|
|
||
| **Effect:** All keys for this service account become invalid, and access to all shared files is revoked | ||
|
|
||
| ## Related Documentation | ||
|
|
||
| - [REST API Documentation](./rest-api.md) - Using service accounts with REST APIs | ||
| - [Google Cloud IAM Best Practices](https://cloud.google.com/iam/docs/best-practices) | ||
| - [Google Drive API - Service Accounts](https://developers.google.com/identity/protocols/oauth2/service-account) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -49,6 +49,19 @@ X-Anthropic-Token: sk-ant-api03-... | |
| - File content - Read only | ||
| - File comments - Read only | ||
|
|
||
| **Google Service Account** (for drive-about-user endpoint): | ||
|
|
||
| See the [Google Service Account Setup Guide](./google-service-account.md) for detailed instructions with screenshots. | ||
|
|
||
| ⚠️ **CRITICAL SECURITY WARNING**: Service account keys do NOT expire and provide full access to shared resources. The X-Google-Json header should ONLY be used in secure, server-to-server environments. Never expose this endpoint to client-side applications. | ||
|
|
||
| Quick setup: | ||
| 1. Create service account in [Google Cloud Console](https://console.cloud.google.com/) | ||
| 2. Enable Google Drive API | ||
| 3. Create and download JSON key | ||
| 4. Share Google Drive files with the service account email | ||
| 5. Use the JSON content in the `X-Google-Json` header | ||
|
|
||
| **Anthropic API Key:** | ||
| 1. Go to https://console.anthropic.com/settings/keys | ||
| 2. Create an API key | ||
|
|
@@ -287,6 +300,93 @@ while (true) { | |
| console.log(`Total stories written: ${storiesWritten}`); | ||
| ``` | ||
|
|
||
| --- | ||
|
|
||
| ### Drive About User (Google Service Account) | ||
|
|
||
| Get authenticated user information from Google Drive using service account credentials. | ||
|
|
||
| 🚨 **TEMPORARY PROOF OF CONCEPT** - The `X-Google-Json` header currently accepts unencrypted service account credentials and will be replaced with an encrypted key mechanism soon. Only use for internal testing and local development. See [Google Service Account Setup Guide](./google-service-account.md) for details. | ||
|
|
||
| **Endpoint:** `POST /api/drive-about-user` | ||
|
|
||
| **Headers:** | ||
| - `Content-Type: application/json` | ||
| - `X-Google-Json` (required) - Service account JSON as string | ||
|
|
||
| **Request Body:** | ||
| ```json | ||
| {} | ||
| ``` | ||
|
|
||
| **Parameters:** | ||
| - None (empty request body) | ||
|
|
||
| **Success Response (200 OK):** | ||
| ```json | ||
| { | ||
| "user": { | ||
| "kind": "drive#user", | ||
| "displayName": "cascade-mcp-drive", | ||
| "emailAddress": "[email protected]", | ||
| "permissionId": "12345678901234567890", | ||
| "photoLink": "https://lh3.googleusercontent.com/...", | ||
| "me": true | ||
| } | ||
| } | ||
| ``` | ||
|
|
||
| **Error Response (401 Unauthorized):** | ||
| ```json | ||
| { | ||
| "error": "Missing credentials header", | ||
| "details": "Please provide credentials via X-Google-Json header (plaintext service account JSON)" | ||
| } | ||
| ``` | ||
|
|
||
| **Example using curl:** | ||
| ```bash | ||
| # Load service account JSON from file | ||
| # Note: The JSON must be passed as a single-line string in the header | ||
| curl -X POST http://localhost:3000/api/drive-about-user \ | ||
| -H "Content-Type: application/json" \ | ||
| -H "X-Google-Json: $(cat google.json | tr -d '\n')" \ | ||
| -d '{}' | ||
|
|
||
| # Alternative: Use a variable to avoid shell escaping issues | ||
| GOOGLE_JSON=$(cat google.json | tr -d '\n') | ||
| curl -X POST http://localhost:3000/api/drive-about-user \ | ||
| -H "Content-Type: application/json" \ | ||
| -H "X-Google-Json: $GOOGLE_JSON" \ | ||
| -d '{}' | ||
| ``` | ||
|
|
||
| **Example using Node.js:** | ||
| ```javascript | ||
| const fs = require('fs'); | ||
|
|
||
| // Load service account JSON | ||
| const serviceAccountJson = fs.readFileSync('./google.json', 'utf-8'); | ||
|
|
||
| const response = await fetch('http://localhost:3000/api/drive-about-user', { | ||
| method: 'POST', | ||
| headers: { | ||
| 'Content-Type': 'application/json', | ||
| 'X-Google-Json': serviceAccountJson, | ||
| }, | ||
| body: JSON.stringify({}), | ||
| }); | ||
|
|
||
| const data = await response.json(); | ||
| console.log(`User: ${data.user.displayName}`); | ||
| console.log(`Email: ${data.user.emailAddress}`); | ||
| console.log(`Permission ID: ${data.user.permissionId}`); | ||
| ``` | ||
|
|
||
| For more information, see the [Google Service Account Setup Guide](./google-service-account.md). | ||
|
|
||
| --- | ||
|
|
||
| ## Error Handling | ||
|
|
||
| All endpoints return JSON responses with appropriate HTTP status codes: | ||
|
|
||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.