|
| 1 | +# OAuth Setup Guide |
| 2 | + |
| 3 | +This guide explains how to configure LocalGPT to use OAuth credentials from Claude Pro/Max and Google Gemini subscription plans instead of pay-per-request API keys. |
| 4 | + |
| 5 | +## Claude Pro/Max OAuth |
| 6 | + |
| 7 | +### Benefits |
| 8 | +- Use your Claude Pro ($20/month) or Max ($100/month) subscription quota |
| 9 | +- Avoid per-token API charges |
| 10 | +- Fixed monthly cost with generous usage limits |
| 11 | + |
| 12 | +### Obtaining OAuth Tokens |
| 13 | + |
| 14 | +Claude OAuth uses PKCE (Proof Key for Code Exchange) flow. You'll need to: |
| 15 | + |
| 16 | +1. **Generate PKCE pair:** |
| 17 | + - Create a code_verifier (random string) |
| 18 | + - Generate code_challenge using S256 (SHA-256 hash of verifier) |
| 19 | + |
| 20 | +2. **Authorization URL:** |
| 21 | + ``` |
| 22 | + https://claude.ai/oauth/authorize?client_id=9d1c250a-e61b-44d9-88ed-5944d1962f5e&response_type=code&redirect_uri=https://console.anthropic.com/oauth/code/callback&code_challenge=<YOUR_CHALLENGE>&code_challenge_method=S256&scope=org:create_api_key user:profile user:inference&state=<RANDOM_STATE> |
| 23 | + ``` |
| 24 | + |
| 25 | +3. **Token Exchange:** |
| 26 | + After user authorizes, exchange the code for tokens: |
| 27 | + ```bash |
| 28 | + curl -X POST https://console.anthropic.com/v1/oauth/token \ |
| 29 | + -H "Content-Type: application/json" \ |
| 30 | + -d '{ |
| 31 | + "client_id": "9d1c250a-e61b-44d9-88ed-5944d1962f5e", |
| 32 | + "grant_type": "authorization_code", |
| 33 | + "redirect_uri": "https://console.anthropic.com/oauth/code/callback", |
| 34 | + "code": "<AUTHORIZATION_CODE>", |
| 35 | + "code_verifier": "<YOUR_VERIFIER>" |
| 36 | + }' |
| 37 | + ``` |
| 38 | + |
| 39 | +4. **Response:** |
| 40 | + ```json |
| 41 | + { |
| 42 | + "access_token": "...", |
| 43 | + "refresh_token": "...", |
| 44 | + "expires_in": 3600 |
| 45 | + } |
| 46 | + ``` |
| 47 | + |
| 48 | +### Configuration |
| 49 | + |
| 50 | +Add to `~/.localgpt/config.toml`: |
| 51 | + |
| 52 | +```toml |
| 53 | +[providers.anthropic_oauth] |
| 54 | +access_token = "${ANTHROPIC_OAUTH_TOKEN}" |
| 55 | +refresh_token = "${ANTHROPIC_OAUTH_REFRESH_TOKEN}" # Optional, for future token refresh |
| 56 | +base_url = "https://api.anthropic.com" |
| 57 | +``` |
| 58 | + |
| 59 | +Then set environment variables: |
| 60 | +```bash |
| 61 | +export ANTHROPIC_OAUTH_TOKEN="your-access-token" |
| 62 | +export ANTHROPIC_OAUTH_REFRESH_TOKEN="your-refresh-token" |
| 63 | +``` |
| 64 | + |
| 65 | +### Usage |
| 66 | + |
| 67 | +Use any Claude model as normal. The OAuth provider is automatically preferred when configured: |
| 68 | + |
| 69 | +```bash |
| 70 | +localgpt ask "Hello" --model anthropic/claude-opus-4-5 |
| 71 | +# or |
| 72 | +localgpt ask "Hello" --model opus # alias |
| 73 | +``` |
| 74 | + |
| 75 | +### References |
| 76 | +- [anthropic-auth library (Rust)](https://github.com/querymt/anthropic-auth) - Complete OAuth implementation |
| 77 | +- [DeepWiki: Claude OAuth Guide](https://deepwiki.com/sst/opencode-anthropic-auth/4.1-claude-promax-oauth) |
| 78 | + |
| 79 | +--- |
| 80 | + |
| 81 | +## Google Gemini OAuth |
| 82 | + |
| 83 | +### Benefits |
| 84 | +- Use your Gemini subscription quota |
| 85 | +- Enterprise/project-scoped access |
| 86 | +- Fixed monthly cost for subscriptions |
| 87 | + |
| 88 | +### Obtaining OAuth Tokens |
| 89 | + |
| 90 | +1. **Enable Gemini API:** |
| 91 | + - Go to [Google Cloud Console](https://console.cloud.google.com/) |
| 92 | + - Enable "Google Generative Language API" |
| 93 | + |
| 94 | +2. **Configure OAuth Consent Screen:** |
| 95 | + - Navigate to "APIs & Services > Consent Screen" |
| 96 | + - Set user type (External for public, Internal for organization) |
| 97 | + - Fill in app details and add test users |
| 98 | + |
| 99 | +3. **Create OAuth Credentials:** |
| 100 | + - Go to "APIs & Services > Credentials" |
| 101 | + - Click "Create Credentials" → "OAuth client ID" |
| 102 | + - Select application type (Desktop app for CLI, Web app for web apps) |
| 103 | + - Download the `client_id.json` file |
| 104 | + |
| 105 | +4. **Authorization Flow:** |
| 106 | + ```bash |
| 107 | + # Manual OAuth flow (pseudocode) |
| 108 | + # 1. Redirect user to Google OAuth consent screen |
| 109 | + # 2. User authorizes |
| 110 | + # 3. Exchange authorization code for tokens |
| 111 | + |
| 112 | + # Or use gemini-cli: |
| 113 | + gemini auth login --oauth |
| 114 | + ``` |
| 115 | + |
| 116 | +5. **Token Response:** |
| 117 | + ```json |
| 118 | + { |
| 119 | + "access_token": "...", |
| 120 | + "refresh_token": "...", |
| 121 | + "expires_in": 3600 |
| 122 | + } |
| 123 | + ``` |
| 124 | + |
| 125 | +### Configuration |
| 126 | + |
| 127 | +Add to `~/.localgpt/config.toml`: |
| 128 | + |
| 129 | +```toml |
| 130 | +[providers.gemini_oauth] |
| 131 | +access_token = "${GEMINI_OAUTH_TOKEN}" |
| 132 | +refresh_token = "${GEMINI_OAUTH_REFRESH_TOKEN}" # Optional, for future token refresh |
| 133 | +base_url = "https://generativelanguage.googleapis.com" |
| 134 | +project_id = "${GOOGLE_CLOUD_PROJECT}" # Optional, for enterprise plans |
| 135 | +``` |
| 136 | + |
| 137 | +Set environment variables: |
| 138 | +```bash |
| 139 | +export GEMINI_OAUTH_TOKEN="your-access-token" |
| 140 | +export GEMINI_OAUTH_REFRESH_TOKEN="your-refresh-token" |
| 141 | +export GOOGLE_CLOUD_PROJECT="your-project-id" # If using project-scoped access |
| 142 | +``` |
| 143 | + |
| 144 | +### Usage |
| 145 | + |
| 146 | +Use Gemini models with the `gemini/` prefix: |
| 147 | + |
| 148 | +```bash |
| 149 | +localgpt ask "Hello" --model gemini/gemini-2.0-flash |
| 150 | +# or |
| 151 | +localgpt ask "Hello" --model gemini-2.0-flash # auto-routed |
| 152 | +``` |
| 153 | + |
| 154 | +### References |
| 155 | +- [Gemini OAuth Quickstart](https://ai.google.dev/gemini-api/docs/oauth) |
| 156 | +- [Gemini CLI Authentication](https://www.geminicli.cc/docs/authentication) |
| 157 | +- [Google Cloud Authentication](https://docs.cloud.google.com/gemini/enterprise/docs/authentication) |
| 158 | + |
| 159 | +--- |
| 160 | + |
| 161 | +## Token Refresh (Future Enhancement) |
| 162 | + |
| 163 | +**Note:** Automatic token refresh is not yet implemented. You must manually refresh expired tokens. |
| 164 | + |
| 165 | +To refresh tokens: |
| 166 | + |
| 167 | +**Claude:** |
| 168 | +```bash |
| 169 | +curl -X POST https://console.anthropic.com/v1/oauth/token \ |
| 170 | + -H "Content-Type: application/json" \ |
| 171 | + -d '{ |
| 172 | + "client_id": "9d1c250a-e61b-44d9-88ed-5944d1962f5e", |
| 173 | + "grant_type": "refresh_token", |
| 174 | + "refresh_token": "<YOUR_REFRESH_TOKEN>" |
| 175 | + }' |
| 176 | +``` |
| 177 | + |
| 178 | +**Gemini:** |
| 179 | +```bash |
| 180 | +curl -X POST https://oauth2.googleapis.com/token \ |
| 181 | + -H "Content-Type: application/x-www-form-urlencoded" \ |
| 182 | + -d "client_id=<YOUR_CLIENT_ID>&client_secret=<YOUR_CLIENT_SECRET>&refresh_token=<YOUR_REFRESH_TOKEN>&grant_type=refresh_token" |
| 183 | +``` |
| 184 | + |
| 185 | +--- |
| 186 | + |
| 187 | +## Security Notes |
| 188 | + |
| 189 | +1. **Store tokens securely** - Use environment variables, not hardcoded values |
| 190 | +2. **Never commit tokens** to version control |
| 191 | +3. **Rotate tokens regularly** - Especially if compromised |
| 192 | +4. **Use refresh tokens** - Access tokens expire, keep refresh tokens secure |
| 193 | +5. **Limit scopes** - Only request necessary OAuth scopes |
| 194 | + |
| 195 | +--- |
| 196 | + |
| 197 | +## Troubleshooting |
| 198 | + |
| 199 | +### "401 Unauthorized" Error |
| 200 | +- Your access token has expired. Use the refresh token to obtain a new one. |
| 201 | +- Check that the token is correctly set in environment variables. |
| 202 | + |
| 203 | +### "OAuth provider not configured" Error |
| 204 | +- Ensure `[providers.anthropic_oauth]` or `[providers.gemini_oauth]` is in your config. |
| 205 | +- Verify environment variables are exported in your shell. |
| 206 | + |
| 207 | +### Token Refresh Issues |
| 208 | +- Refresh tokens can expire after long periods of inactivity. |
| 209 | +- You may need to re-authorize through the OAuth flow. |
| 210 | + |
| 211 | +--- |
| 212 | + |
| 213 | +## Alternative: API Keys |
| 214 | + |
| 215 | +If OAuth setup is too complex, you can still use traditional API keys: |
| 216 | + |
| 217 | +```toml |
| 218 | +# Claude API (pay-per-request) |
| 219 | +[providers.anthropic] |
| 220 | +api_key = "${ANTHROPIC_API_KEY}" |
| 221 | + |
| 222 | +# Gemini API (pay-per-request, not available yet in LocalGPT) |
| 223 | +# Currently only OAuth is supported for Gemini |
| 224 | +``` |
0 commit comments