Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 103 additions & 0 deletions .planning/REQUIREMENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# Requirements - Google OAuth for Gemini Models

## Overview

Enable OpenCode users to authenticate with their Google account to access Gemini models through their Google AI Pro/Ultra subscriptions, while maintaining existing API key authentication.

## Functional Requirements

### FR-01: OAuth Authentication Flow
- System MUST support Google OAuth 2.0 Authorization Code flow
- System MUST support token refresh using refresh tokens
- System MUST handle token expiry gracefully
- System MUST support revocation of OAuth credentials

### FR-02: Dual Authentication Support
- System MUST support API key authentication (existing)
- System MUST support OAuth authentication (new)
- System MUST allow switching between authentication methods
- System MUST maintain backwards compatibility with existing API key users

### FR-03: Provider Integration
- System MUST pass OAuth bearer tokens to Gemini API
- System MUST use OAuth credentials for users with active Google subscriptions
- System MUST fall back to API keys if OAuth is not configured
- System MUST handle authentication errors appropriately

### FR-04: CLI Authentication
- CLI MUST provide `opencode auth login --google` command
- CLI MUST handle OAuth callback via local server
- CLI MUST store OAuth tokens securely
- CLI MUST show authentication status to user

### FR-05: Console Integration
- Console MUST provide "Connect Google Account" UI
- Console MUST display OAuth connection status
- Console MUST allow disconnecting Google account
- Console MUST handle OAuth errors with clear messages

### FR-06: Credential Storage
- System MUST store access tokens securely
- System MUST store refresh tokens securely
- System MUST track token expiry times
- System MUST associate credentials with workspaces

## Non-Functional Requirements

### NFR-01: Security
- Tokens MUST be encrypted at rest
- Tokens MUST never be logged or exposed in error messages
- OAuth state parameter MUST prevent CSRF attacks
- PKCE (Proof Key for Code Exchange) SHOULD be used for mobile/CLI

### NFR-02: Performance
- Token refresh MUST not block API calls
- Token status check SHOULD be cached for short duration
- OAuth flow MUST complete within 30 seconds

### NFR-03: Availability
- System MUST remain functional if Google OAuth is down (fallback to API keys)
- System MUST handle Google API rate limits appropriately
- Token refresh failures MUST have retry logic

### NFR-04: Usability
- OAuth setup MUST take less than 2 minutes
- Error messages MUST be actionable
- Users MUST be able to see which auth method is active
- Re-authentication flow MUST be simple

## Technical Constraints

### TC-01: Existing Infrastructure
- MUST use existing Drizzle ORM and MySQL database
- MUST work with existing provider abstraction layer
- MUST integrate with existing OpenAuthJS setup where possible
- MUST not break existing API key authentication

### TC-02: Google API Constraints
- MUST comply with Google AI API terms of service
- MUST handle Google's rate limits for subscription tiers
- MUST use correct OAuth scopes for Gemini access
- MUST handle Google's token lifecycle requirements

### TC-03: Deployment
- MUST deploy to Cloudflare Workers (backend)
- MUST support serverless environment
- MUST handle environment variable configuration
- MUST support zero-downtime deployments

## Out of Scope

- Google Cloud Platform OAuth (different from Google AI OAuth)
- Enterprise SSO integration
- OAuth for other model providers (Anthropic, OpenAI already have their own flows)
- Token sharing between workspaces
- Multi-factor authentication enforcement

## Success Metrics

- OAuth setup completion rate > 90%
- Token refresh success rate > 99%
- API regression rate = 0 (no existing API key users broken)
- Average time to authenticate < 60 seconds
- Support tickets related to auth < 5% of total
208 changes: 208 additions & 0 deletions .planning/ROADMAP.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@
# OpenCode Google OAuth for Gemini Models - Roadmap

**Project:** Add Google OAuth support alongside existing API key authentication to enable users to access Gemini models through their Google AI Pro/Ultra subscriptions.

**Current State:**
- API key-based authentication for model providers
- Google OAuth exists for console app login (`@openauthjs/openauth/provider/google`)
- Gemini models configured as providers requiring API keys
- Users with Google AI Pro/Ultra subscriptions cannot use their subscription credentials

**Target State:**
- Users can authenticate via Google OAuth to use their Google AI subscription
- Existing API key authentication remains functional
- Seamless switching between API key and OAuth credentials
- Support for both Google AI Studio OAuth and Google Cloud OAuth flows

---

## Phase 01: Requirements & Discovery

**Goal:** Define technical requirements and research Google AI OAuth implementation patterns.

**Deliverables:**
- Document Google AI OAuth scopes and endpoints
- Identify token refresh requirements
- Define user experience flows
- Document data storage requirements

**Success Criteria:**
- Clear understanding of Google AI OAuth vs Google Cloud OAuth differences
- Documented API endpoints for token exchange
- User flow diagrams approved

---

## Phase 02: Database Schema Extensions

**Goal:** Extend database schema to store OAuth tokens and credentials.

**Deliverables:**
- New `google_oauth` table for storing OAuth credentials
- Migration scripts for existing databases
- Updated Drizzle schema definitions
- Token refresh logic design

**Success Criteria:**
- Schema supports access token, refresh token, expiry
- Workspace-level OAuth credential association
- Secure credential storage (encryption at rest)
- Migration tested and reversible

---

## Phase 03: Google OAuth Client Implementation

**Goal:** Implement OAuth client for Google AI authentication flow.

**Deliverables:**
- OAuth client using Google's Authorization Code flow
- Token exchange and refresh handling
- Error handling for expired/revoked tokens
- Scope configuration for Google AI access

**Success Criteria:**
- OAuth flow completes successfully
- Access tokens are obtained and stored
- Refresh tokens work correctly
- Proper error messages for failures

---

## Phase 04: Provider Integration - Gemini OAuth

**Goal:** Create new provider type that uses OAuth credentials instead of API keys.

**Deliverables:**
- `GeminiOAuthProvider` class implementation
- Credential resolution (OAuth token vs API key)
- Request signing with OAuth bearer tokens
- Fallback to API key if OAuth fails

**Success Criteria:**
- Gemini API calls work with OAuth tokens
- Existing API key providers unaffected
- Graceful fallback on token expiry
- Consistent interface across providers

---

## Phase 05: CLI Authentication Integration

**Goal:** Add Google OAuth authentication option to CLI.

**Deliverables:**
- `opencode auth login --google` command
- OAuth callback handling (local server)
- Token storage in local config
- Session management

**Success Criteria:**
- Users can authenticate via Google from CLI
- OAuth flow completes with redirect
- Tokens persist across sessions
- Clear status indicators

---

## Phase 06: Console UI Integration

**Goal:** Add Google OAuth UI to console application.

**Deliverables:**
- "Connect Google Account" button in console
- OAuth flow initiation and callback
- Credential display and management
- Disconnect/reconnect functionality

**Success Criteria:**
- UI clearly shows OAuth status
- Users can link/unlink Google account
- Existing API key UI still works
- No breaking changes to current console

---

## Phase 07: Token Lifecycle Management

**Goal:** Implement automatic token refresh and revocation handling.

**Deliverables:**
- Background token refresh worker
- Token expiry detection before API calls
- Re-authorization flow for expired sessions
- Token cleanup on workspace deletion

**Success Criteria:**
- Tokens refresh automatically before expiry
- Users prompted to re-authenticate when needed
- Stale tokens cleaned up
- No API calls with expired tokens

---

## Phase 08: Testing & Validation

**Goal:** Comprehensive testing of OAuth implementation.

**Deliverables:**
- Unit tests for OAuth client
- Integration tests for provider
- E2E tests for CLI and console flows
- Manual testing with real Google AI subscriptions

**Success Criteria:**
- All tests passing
- Real Pro/Ultra subscriptions work
- API key path still functional
- Edge cases handled (expired tokens, revoked access)

---

## Phase 09: Documentation & Release

**Goal:** Document changes and release to users.

**Deliverables:**
- User documentation for Google OAuth setup
- Migration guide for existing users
- Admin guide for OAuth configuration
- Changelog and release notes

**Success Criteria:**
- Clear setup instructions
- Troubleshooting guide for common issues
- Backwards compatibility documented
- Smooth rollout to users

---

## Dependencies

| Phase | Blocked By |
|-------|------------|
| 02 | 01 |
| 03 | 01 |
| 04 | 02, 03 |
| 05 | 03, 04 |
| 06 | 03, 04 |
| 07 | 04, 05, 06 |
| 08 | 04, 05, 06, 07 |
| 09 | 08 |

## Open Questions

1. **OAuth Provider Choice:** Use Google Cloud OAuth or Google AI Studio OAuth? (May need both)
2. **Scopes Required:** Exact OAuth scopes needed for Gemini API access via subscription
3. **Token Storage:** Encrypt tokens at rest? Key management approach?
4. **Workspace Association:** Are OAuth credentials per-user or per-workspace?
5. **Rate Limiting:** How do subscription rate limits interact with OpenCode's rate limiting?

---

## Definitions

- **Google AI Pro/Ultra:** Google's subscription tiers for Gemini model access
- **OAuth Bearer Token:** Authorization token used in API request headers
- **Refresh Token:** Long-lived token used to obtain new access tokens
- **Provider:** OpenCode's abstraction for model API integrations
13 changes: 8 additions & 5 deletions packages/opencode/src/cli/cmd/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -277,6 +277,13 @@ export const AuthLoginCommand = cmd({
openrouter: 5,
vercel: 6,
}

const hints: Record<string, string> = {
opencode: "recommended",
anthropic: "Claude Max or API key",
openai: "ChatGPT Plus/Pro or API key",
google: "Google AI Pro/Ultra or API key",
}
let provider = await prompts.autocomplete({
message: "Select provider",
maxItems: 8,
Expand All @@ -291,11 +298,7 @@ export const AuthLoginCommand = cmd({
map((x) => ({
label: x.name,
value: x.id,
hint: {
opencode: "recommended",
anthropic: "Claude Max or API key",
openai: "ChatGPT Plus/Pro or API key",
}[x.id],
hint: hints[x.id],
})),
),
{
Expand Down
Loading
Loading