Skip to content

feat: OAuth authentication for AI providers#9

Merged
dortort merged 6 commits intomainfrom
feat/oauth-authentication
Feb 6, 2026
Merged

feat: OAuth authentication for AI providers#9
dortort merged 6 commits intomainfrom
feat/oauth-authentication

Conversation

@dortort
Copy link
Owner

@dortort dortort commented Feb 6, 2026

Summary

Replace API key inputs as the primary auth method with OAuth sign-in buttons. Users authenticate with their existing AI provider subscriptions instead of paying per-token API pricing.

Provider Support

Provider OAuth Notes
OpenAI Supported PKCE flow via auth.openai.com. Uses ChatGPT Plus/Pro subscription.
Anthropic Blocked API key only. Third-party OAuth violates TOS.
Google Experimental PKCE flow via Google OAuth. Access may be revoked.

Changes

New Files

  • src/main/services/OAuthService.ts - PKCE flow, loopback server, token exchange, refresh
  • src/main/ipc/oauth.router.ts - tRPC routes: startFlow, disconnect, getStatus, getCapabilities
  • src/renderer/features/settings/ProviderCard.tsx - Per-provider card with OAuth button

Key Features

  • PKCE flow with loopback HTTP server on random port (RFC 8252)
  • OpenAI token exchange converts ID token to API key via official grant type
  • Automatic token refresh scheduled 5 minutes before expiry
  • Backward compatible with existing API key authentication
  • Redesigned Settings UI with OAuth as primary, API keys in collapsible "Advanced" section

Technical Details

  • OpenAI OAuth aligns with official docs: offline_access scope, id_token_add_organizations, codex_cli_simplified_flow params
  • XSS-safe callback HTML with proper escaping
  • Token expiry checked on startup with immediate refresh if needed
  • Encrypted token storage via Electron safeStorage

Test Plan

  • Click "Sign in with OpenAI" → browser opens auth page → complete login → callback received → UI shows "Connected"
  • Send a chat message via OAuth-authenticated OpenAI → AI responds
  • "Disconnect" clears tokens and UI state
  • Anthropic API key flow unchanged
  • Restart app → OAuth state restored, token refresh timer re-scheduled
  • "Advanced" section → API key inputs still work for all providers

🤖 Generated with Claude Code

dortort and others added 6 commits February 5, 2026 20:09
Add foundational types for OAuth authentication:
- OAuthTokens, OAuthFlowStatus, AuthMethod types
- Discriminated ProviderConfig union (ProviderConfigApiKey | ProviderConfigOAuth)
- OAUTH_CAPABILITIES map with endpoints, scopes, PKCE params for OpenAI/Google
- OAuthError and OAuthTokenExpiredError classes

OpenAI OAuth aligns with official docs: offline_access scope,
id_token_add_organizations, codex_cli_simplified_flow params,
and token exchange grant support.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New OAuthService handles complete OAuth authentication:
- PKCE flow with loopback HTTP server on random port
- S256 code challenge method per RFC 7636
- OpenAI token exchange (ID token → API key via token-exchange grant)
- Automatic token refresh scheduling (5 min before expiry)
- XSS-safe callback HTML with proper escaping

SettingsService extended with OAuth token CRUD:
- getOAuthTokens, setOAuthTokens, deleteOAuthTokens
- getAuthMethod, setAuthMethod
- Encrypted storage via safeStorage
- Backward-compatible with existing settings files

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Adapters support dual authentication:
- OpenAIAdapter: API key OR OAuth token with chatgpt-account-id header
- GoogleAdapter: API key (x-goog-api-key) OR OAuth Bearer token
- ProviderManager: handles discriminated config union, updateOAuthToken()

New oauth.router with tRPC procedures:
- startFlow, disconnect, getStatus, getCapabilities

IPC layer updates:
- Context instantiates OAuthService, restores OAuth on startup
- Expired tokens refreshed immediately before provider configuration
- Token refresh callback wired for automatic updates
- Preload bridge exposes onOAuthStatus/removeOAuthListeners

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
New ProviderCard component:
- OAuth sign-in button for supported providers (OpenAI, Google)
- "Experimental" badge for unstable providers
- Connected state shows email with disconnect button
- API key notice for Anthropic (OAuth not supported)

Redesigned SettingsDialog:
- Provider cards with OAuth as primary auth method
- Collapsible "Advanced: Use API Keys" section
- OAuth status listener for real-time flow updates

settingsStore extended with OAuth state:
- oauthStatus per provider (connected, email, authMethod)
- oauthFlowStatus (idle, pending, success, error)
- startOAuthFlow, disconnectOAuth, updateOAuthFlowStatus actions

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
OpenAI OAuth requires specific redirect configuration:
- Fixed port 1455 (not random)
- Callback path /auth/callback (not /callback)
- localhost hostname (not 127.0.0.1)

Added redirectPort and callbackPath to OAUTH_CAPABILITIES.
Updated OAuthService to use provider-specific settings.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@dortort dortort merged commit fe99961 into main Feb 6, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant