-
-
Notifications
You must be signed in to change notification settings - Fork 73
Improvements to documentation with regards to remote OAuth issue #97
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -237,6 +237,48 @@ The manager supports loading credentials from two sources, with a clear priority | |
| - This is the key to "Stateless Deployment" for platforms like Railway, Render, Heroku | ||
| - Credentials are referenced internally using `env://` URIs (e.g., `env://gemini_cli/1`) | ||
|
|
||
| #### 2.6.4. Remote Host Authentication (SSH Port Forwarding) | ||
|
|
||
| When the proxy is deployed on a remote host (VPS, cloud server, etc.), OAuth authentication requires special handling because OAuth callbacks are sent to `localhost`, which on the remote server refers to the server itself, not your local machine. | ||
|
|
||
| **The Problem:** | ||
|
|
||
| - Proxy runs on remote VPS at `your-vps-ip` | ||
| - You attempt to add OAuth credentials using the credential tool on the VPS | ||
| - OAuth provider redirects to `http://localhost:PORT/callback` | ||
| - On the VPS, `localhost` points to the VPS's localhost, not your local browser | ||
| - The callback fails because your browser cannot connect to the VPS's localhost | ||
|
|
||
| **The Solution: SSH Port Forwarding** | ||
|
|
||
| Create an SSH tunnel to forward OAuth callback ports from the VPS to your local machine: | ||
|
|
||
| ```bash | ||
| # Single provider examples | ||
| ssh -L 8085:localhost:8085 user@your-vps-ip # Gemini CLI | ||
| ssh -L 51121:localhost:51121 user@your-vps-ip # Antigravity | ||
| ssh -L 11451:localhost:11451 user@your-vps-ip # iFlow | ||
|
|
||
| # Multiple providers simultaneously | ||
| ssh -L 8085:localhost:8085 -L 51121:localhost:51121 -L 11451:localhost:11451 user@your-vps-ip | ||
| ``` | ||
|
|
||
| **Workflow:** | ||
|
|
||
| 1. **Establish SSH tunnel** (keep this connection open) | ||
| 2. **Run credential tool on VPS** (in separate SSH session) | ||
| 3. **Complete browser-based OAuth** - callbacks are forwarded via tunnel | ||
| 4. **Close SSH tunnel** after authentication completes | ||
|
|
||
| **Alternative Approach: Local Authentication + Export** | ||
|
|
||
| If SSH port forwarding is not feasible: | ||
| 1. Complete OAuth flows locally on your machine | ||
| 2. Export credentials to environment variables using credential tool's export feature | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It might be helpful to include the actual command for exporting credentials here, e.g., |
||
| 3. Deploy `.env` file to remote server | ||
|
|
||
| This approach uses the credential tool's export functionality to generate environment variable representations of OAuth credentials, which can then be deployed to stateless environments without requiring SSH tunnels. | ||
|
|
||
| **Gemini CLI Environment Variables:** | ||
|
|
||
| Single credential (legacy format): | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -523,13 +523,13 @@ SSH tunnels forward ports from your local machine to the remote VPS, allowing yo | |||||
| From your **local machine**, open a terminal and run: | ||||||
|
|
||||||
| ```bash | ||||||
| # Forward all OAuth callback ports at once | ||||||
| ssh -L 51121:localhost:51121 -L 8085:localhost:8085 -L 11451:localhost:11451 user@your-vps-ip | ||||||
| # Forward all OAuth callback ports at once (recommended) | ||||||
| ssh -L 8085:localhost:8085 -L 51121:localhost:51121 -L 11451:localhost:11451 user@your-vps-ip | ||||||
|
|
||||||
| # Alternative: Forward ports individually as needed | ||||||
| ssh -L 51121:localhost:51121 user@your-vps-ip # For Antigravity | ||||||
| ssh -L 8085:localhost:8085 user@your-vps-ip # For Gemini CLI | ||||||
| ssh -L 11451:localhost:11451 user@your-vps-ip # For iFlow | ||||||
| ssh -L 51121:localhost:51121 user@your-vps-ip # For Antigravity | ||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is a slight formatting inconsistency with the indentation of the comment here (triple space vs single space on other lines).
Suggested change
|
||||||
| ssh -L 11451:localhost:11451 user@your-vps-ip # For iFlow | ||||||
| ``` | ||||||
|
|
||||||
| **Keep this SSH session open** during the entire authentication process. | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -774,6 +774,76 @@ For platforms without file persistence (Railway, Render, Vercel): | |||||||||
|
|
||||||||||
| </details> | ||||||||||
|
|
||||||||||
| <details> | ||||||||||
| <summary><b>Remote Host Deployment (SSH Port Forwarding)</b></summary> | ||||||||||
|
|
||||||||||
| When the proxy is running on a remote host (VPS, cloud server, etc.), OAuth token authentication requires SSH port forwarding. This is because the OAuth callback URL is sent to `localhost`, which on the remote server points to the server itself, not your local machine. | ||||||||||
|
|
||||||||||
| **The Problem:** | ||||||||||
|
|
||||||||||
| - You run the proxy on a remote VPS | ||||||||||
| - You try to add OAuth credentials using the credential tool | ||||||||||
| - The OAuth provider redirects to `http://localhost:PORT/callback` | ||||||||||
| - On the VPS, `localhost` refers to the VPS, not your local machine | ||||||||||
| - The callback fails because your browser can't reach the VPS's localhost | ||||||||||
|
|
||||||||||
| **The Solution: SSH Port Forwarding** | ||||||||||
|
|
||||||||||
| Use SSH to tunnel the OAuth callback ports from the VPS back to your local machine. You only need to do this when adding OAuth credentials. | ||||||||||
|
|
||||||||||
| **Single Provider Examples:** | ||||||||||
|
|
||||||||||
| ```bash | ||||||||||
| # Gemini CLI (port 8085) | ||||||||||
| ssh -L 8085:localhost:8085 user@your-vps-ip | ||||||||||
|
|
||||||||||
| # Antigravity (port 51121) | ||||||||||
| ssh -L 51121:localhost:51121 user@your-vps-ip | ||||||||||
|
|
||||||||||
| # iFlow (port 11451) | ||||||||||
| ssh -L 11451:localhost:11451 user@your-vps-ip | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| **Multiple Providers at Once:** | ||||||||||
|
|
||||||||||
| ```bash | ||||||||||
| # Forward all three OAuth ports simultaneously | ||||||||||
| ssh -L 8085:localhost:8085 -L 51121:localhost:51121 -L 11451:localhost:11451 user@your-vps-ip | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| **Complete Workflow:** | ||||||||||
|
|
||||||||||
| 1. **Establish SSH tunnel** (keep this connection open): | ||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The iFlow port (
Suggested change
|
||||||||||
| ```bash | ||||||||||
| ssh -L 8085:localhost:8085 -L 51121:localhost:51121 user@your-vps-ip | ||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The "Complete Workflow" step 1 SSH tunnel command is missing the iFlow port 11451. This is inconsistent with every other section in the PR (the "Multiple Providers at Once" block at line 811, the "Custom VPS / Systemd" section at line 1003, and DOCUMENTATION.md section 2.6.4). A user following this workflow who also needs iFlow credentials won't have that port forwarded, causing their OAuth callback to silently fail.
Suggested change
|
||||||||||
| ``` | ||||||||||
|
|
||||||||||
| 2. **Run the credential tool on the VPS** (in a separate terminal or SSH session): | ||||||||||
| ```bash | ||||||||||
| ssh user@your-vps-ip | ||||||||||
|
Comment on lines
+816
to
+823
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Add blank lines before fenced code blocks in list items. This section triggers MD031 ( 🧰 Tools🪛 markdownlint-cli2 (0.21.0)[warning] 817-817: Fenced code blocks should be surrounded by blank lines (MD031, blanks-around-fences) [warning] 822-822: Fenced code blocks should be surrounded by blank lines (MD031, blanks-around-fences) 🤖 Prompt for AI Agents |
||||||||||
| cd /path/to/LLM-API-Key-Proxy | ||||||||||
| python -m rotator_library.credential_tool | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| 3. **Complete OAuth authentication**: | ||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. On many remote servers (especially headless VPS instances), the credential tool cannot automatically open a browser window. It usually prints a URL for the user to copy. Clarifying this (e.g., "The tool will provide a URL to open in your local browser") would be more accurate for VPS users. |
||||||||||
| - The credential tool will open a browser window | ||||||||||
| - Because of the SSH tunnel, the callback will be forwarded to your local machine | ||||||||||
| - Complete the authentication flow as normal | ||||||||||
|
|
||||||||||
| 4. **Close SSH tunnel** after authentication is complete | ||||||||||
|
|
||||||||||
| **Alternative: Local Authentication + Deploy Credentials** | ||||||||||
|
|
||||||||||
| If you prefer not to use SSH port forwarding: | ||||||||||
|
|
||||||||||
| 1. Complete OAuth flows locally on your machine | ||||||||||
| 2. Export credentials to environment variables using the credential tool | ||||||||||
| 3. Deploy the `.env` file to your remote server | ||||||||||
|
|
||||||||||
| See the "Stateless Deployment" section above for details on exporting credentials. | ||||||||||
|
|
||||||||||
| </details> | ||||||||||
|
|
||||||||||
| <details> | ||||||||||
| <summary><b>OAuth Callback Port Configuration</b></summary> | ||||||||||
|
|
||||||||||
|
|
@@ -930,11 +1000,13 @@ For OAuth providers (Antigravity, Gemini CLI, etc.), you must authenticate local | |||||||||
|
|
||||||||||
| ```bash | ||||||||||
| # Forward callback ports through SSH | ||||||||||
| ssh -L 51121:localhost:51121 -L 8085:localhost:8085 user@your-vps | ||||||||||
| ssh -L 8085:localhost:8085 -L 51121:localhost:51121 -L 11451:localhost:11451 user@your-vps-ip | ||||||||||
|
|
||||||||||
| # Then run credential tool on the VPS | ||||||||||
| # Then run credential tool on the VPS in a separate terminal | ||||||||||
| ``` | ||||||||||
|
|
||||||||||
| This creates a tunnel that forwards OAuth callback ports from the VPS to your local machine, allowing the browser-based authentication to complete successfully. | ||||||||||
|
|
||||||||||
| **Systemd Service:** | ||||||||||
|
|
||||||||||
| ```ini | ||||||||||
|
|
@@ -953,6 +1025,7 @@ WantedBy=multi-user.target | |||||||||
| ``` | ||||||||||
|
|
||||||||||
| See [VPS Deployment](Deployment%20guide.md#appendix-deploying-to-a-custom-vps) for complete guide. | ||||||||||
| See the [Remote Host Deployment (SSH Port Forwarding)](#remote-host-deployment-ssh-port-forwarding) section above for detailed OAuth setup instructions. | ||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The fragment link target is invalid (MD051).
🔗 Suggested fix-See the [Remote Host Deployment (SSH Port Forwarding)](`#remote-host-deployment-ssh-port-forwarding`) section above for detailed OAuth setup instructions.
+See the **Remote Host Deployment (SSH Port Forwarding)** section above for detailed OAuth setup instructions.📝 Committable suggestion
Suggested change
🧰 Tools🪛 markdownlint-cli2 (0.21.0)[warning] 1028-1028: Link fragments should be valid (MD051, link-fragments) 🤖 Prompt for AI Agents |
||||||||||
|
|
||||||||||
| </details> | ||||||||||
|
|
||||||||||
|
|
@@ -967,6 +1040,7 @@ See [VPS Deployment](Deployment%20guide.md#appendix-deploying-to-a-custom-vps) f | |||||||||
| | All keys on cooldown | All keys failed recently; check `logs/detailed_logs/` for upstream errors | | ||||||||||
| | Model not found | Verify format is `provider/model_name` (e.g., `gemini/gemini-2.5-flash`) | | ||||||||||
| | OAuth callback failed | Ensure callback port (8085, 51121, 11451) isn't blocked by firewall | | ||||||||||
| | OAuth callback failed on remote VPS | Use SSH port forwarding: `ssh -L 8085:localhost:8085 -L 51121:localhost:51121 user@your-vps-ip` | | ||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The iFlow port (
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The troubleshooting table entry for "OAuth callback failed on remote VPS" is also missing iFlow port 11451. This is inconsistent with the "Multiple Providers at Once" command block immediately above (line 811), which correctly lists all three ports.
Suggested change
|
||||||||||
| | Streaming hangs | Increase `TIMEOUT_READ_STREAMING`; check provider status | | ||||||||||
|
|
||||||||||
| **Detailed Logs:** | ||||||||||
|
|
||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -703,6 +703,9 @@ async def verify_anthropic_api_key( | |||||||||||||||||||||||||||||||||||
| Dependency to verify API key for Anthropic endpoints. | ||||||||||||||||||||||||||||||||||||
| Accepts either x-api-key header (Anthropic style) or Authorization Bearer (OpenAI style). | ||||||||||||||||||||||||||||||||||||
| """ | ||||||||||||||||||||||||||||||||||||
| # If PROXY_API_KEY is not set or empty, skip verification (open access) | ||||||||||||||||||||||||||||||||||||
| if not PROXY_API_KEY: | ||||||||||||||||||||||||||||||||||||
| return x_api_key or auth | ||||||||||||||||||||||||||||||||||||
|
Comment on lines
+706
to
+708
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fail-open auth here should be explicit opt-in, not implicit. Line 706 silently disables endpoint authentication when 🔐 Suggested fix (explicit unauthenticated mode) async def verify_anthropic_api_key(
x_api_key: str = Depends(anthropic_api_key_header),
auth: str = Depends(api_key_header),
):
@@
- # If PROXY_API_KEY is not set or empty, skip verification (open access)
- if not PROXY_API_KEY:
- return x_api_key or auth
+ allow_unauthenticated = (
+ os.getenv("ALLOW_UNAUTHENTICATED", "false").lower() == "true"
+ )
+ if not PROXY_API_KEY:
+ if allow_unauthenticated:
+ return x_api_key or auth
+ raise HTTPException(
+ status_code=500,
+ detail="Server misconfigured: PROXY_API_KEY is not set",
+ )📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||
| # Check x-api-key first (Anthropic style) | ||||||||||||||||||||||||||||||||||||
| if x_api_key and x_api_key == PROXY_API_KEY: | ||||||||||||||||||||||||||||||||||||
| return x_api_key | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Section numbering is out of order.
2.6.4appears before2.6.3, which breaks doc structure and cross-reference clarity. Please renumber/reorder this subsection sequence.🤖 Prompt for AI Agents