Overview
Loaf supports three authentication providers with different authentication mechanisms. All credentials are stored securely using the system keychain when available.Supported Providers
- OpenAI - OAuth 2.0 with device code flow or browser-based login
- OpenRouter - API key authentication
- Antigravity - Google OAuth 2.0 with browser flow
OpenAI Authentication
OAuth Flow
OpenAI uses OAuth 2.0 with PKCE for secure authentication:Authentication Modes
auto(default) - Detects headless environments and chooses appropriate flowbrowser- Opens browser and uses localhost callbackdevice_code- Uses device code flow for headless environments
Headless Detection
Loaf automatically detects headless environments (src/openai-oauth.ts:274):Browser Flow
The browser flow uses PKCE with local callback server:- Generate PKCE challenge (src/openai-oauth.ts:226):
- Start local server on port 1455 (or random if taken)
- Build authorization URL:
-
Exchange code for tokens at
/oauth/token - Extract ChatGPT account ID from ID token JWT
Device Code Flow
For headless environments (src/openai-oauth.ts:380):- Requests a user code from
/api/accounts/deviceauth/usercode - Displays verification URL and code to user
- Polls
/api/accounts/deviceauth/tokenevery 5 seconds - Returns authorization code when user approves
- Exchanges code for tokens
Token Exchange
OpenAI supports exchanging ID tokens for API keys (src/openai-oauth.ts:729):Credential Storage
OpenAI credentials are stored in two locations:- Secure store (system keychain):
- Auth metadata file (
~/.loaf/auth.json):
Loading Credentials
- Read from secure store (preferred)
- Migrate from legacy
auth.jsonif found - Return null if no credentials
Configuration
OpenRouter Authentication
OpenRouter uses simple API key authentication:Antigravity Authentication
Google OAuth Flow
Antigravity uses Google OAuth 2.0 with offline access:OAuth Configuration
Token Storage
Antigravity tokens are stored in the secure store:Token Refresh
Tokens are automatically refreshed when nearing expiry (src/antigravity-oauth.ts:123):Profile Data
Antigravity fetches user profile from Google APIs (src/antigravity-oauth.ts:162):Loading Credentials
Secure Storage
Loaf uses the system keychain for credential storage:Best Practices
Security
- Use secure storage - Never store tokens in plain text files
- Rotate regularly - Refresh tokens periodically
- Limit scope - Request only necessary OAuth scopes
- Handle expiry - Check token expiration before use
- Clean up - Remove credentials when switching accounts
Error Handling
- Network failures - Retry with exponential backoff
- Token expiry - Automatically refresh when possible
- Invalid credentials - Prompt for re-authentication
- Timeout - Set reasonable timeouts for auth flows
Multi-Provider Support
- Check availability - Verify provider is configured before use
- Fallback providers - Support multiple providers for resilience
- Provider switching - Allow easy switching between providers
CLI Usage
Source Code Reference
src/openai-oauth.ts- OpenAI OAuth implementation (src/openai-oauth.ts:1)src/antigravity-oauth.ts- Antigravity OAuth implementation (src/antigravity-oauth.ts:1)src/secure-store.ts- Secure credential storagesrc/secret-accounts.ts- Secret key definitionssrc/config.ts- Provider type definitions (src/config.ts:2)
Related
- Model Selection - Choose models after authentication
- Slash Commands - Managing auth with commands
- RPC Auth Methods - Programmatic auth API