Skip to content

Conversation

@jovermier
Copy link

@jovermier jovermier commented Dec 12, 2025

Summary

  • Add PASSTHROUGH_API_KEY environment variable to enable per-user quota tracking
  • When enabled, extracts API key from incoming request headers (x-api-key or Authorization Bearer)
  • Routes through the extracted key to upstream gateway instead of using static OPENAI_API_KEY
  • Useful for multi-tenant environments where each user needs their own virtual key tracking

Implementation Details

  • Added PASSTHROUGH_API_KEY configuration option
  • Modified request handling to extract and use incoming API key when passthrough mode is enabled
  • Maintains backward compatibility - existing functionality unchanged when disabled
  • Added proper logging for debugging and monitoring

Copilot AI review requested due to automatic review settings December 12, 2025 20:42
@jovermier jovermier changed the title Add PASSTHROUGH_API_KEY option for per-user quota tracking Add PASSTHROUGH_API_KEY option to forward incoming API keys Dec 12, 2025
Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a PASSTHROUGH_API_KEY configuration option to enable per-user quota tracking in multi-tenant environments. When enabled, the proxy extracts API keys from incoming request headers (x-api-key or Authorization Bearer) and forwards them to the upstream LiteLLM gateway instead of using the static OPENAI_API_KEY environment variable.

  • Adds PASSTHROUGH_API_KEY environment variable with header extraction logic
  • Updates OpenAI model routing to use passthrough API keys when enabled
  • Includes unrelated Dockerfile improvement (python:latest → python:3.12-slim)

Reviewed changes

Copilot reviewed 2 out of 3 changed files in this pull request and generated 6 comments.

File Description
server.py Adds PASSTHROUGH_API_KEY configuration and implements API key extraction from request headers for OpenAI models
Dockerfile Updates base image from python:latest to python:3.12-slim (unrelated to PR purpose)
Comments suppressed due to low confidence (1)

server.py:1165

  • The PASSTHROUGH_API_KEY feature is only implemented for OpenAI models, but not for Anthropic or Gemini models. For consistency and to fully support the multi-tenant quota tracking use case described in the PR, this feature should be extended to all model providers. Consider applying the same passthrough logic to the Anthropic (line 1164) and Gemini (line 1161) model branches.
        # Determine which API key to use based on the model
        if request.model.startswith("openai/"):
            # Use passthrough key if enabled, otherwise fall back to env var
            litellm_request["api_key"] = incoming_api_key if PASSTHROUGH_API_KEY and incoming_api_key else OPENAI_API_KEY
            # Use custom OpenAI base URL if configured
            if OPENAI_BASE_URL:
                litellm_request["api_base"] = OPENAI_BASE_URL
                logger.debug(f"Using {'passthrough' if PASSTHROUGH_API_KEY and incoming_api_key else 'OpenAI'} API key and custom base URL {OPENAI_BASE_URL} for model: {request.model}")
            else:
                logger.debug(f"Using {'passthrough' if PASSTHROUGH_API_KEY and incoming_api_key else 'OpenAI'} API key for model: {request.model}")
        elif request.model.startswith("gemini/"):
            if USE_VERTEX_AUTH:
                litellm_request["vertex_project"] = VERTEX_PROJECT
                litellm_request["vertex_location"] = VERTEX_LOCATION
                litellm_request["custom_llm_provider"] = "vertex_ai"
                logger.debug(f"Using Gemini ADC with project={VERTEX_PROJECT}, location={VERTEX_LOCATION} and model: {request.model}")
            else:
                litellm_request["api_key"] = GEMINI_API_KEY
                logger.debug(f"Using Gemini API key for model: {request.model}")
        else:
            litellm_request["api_key"] = ANTHROPIC_API_KEY
            logger.debug(f"Using Anthropic API key for model: {request.model}")

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 1 out of 1 changed files in this pull request and generated 6 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 4 changed files in this pull request and generated 5 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

jovermier and others added 2 commits December 13, 2025 23:42
- Add specific rule in AuthorizationPolicy for vmagent service account
- Allow cluster.local/ns/monitoring/sa/vmagent-victoria-metrics principal
- This should resolve vmagent scrape errors shown in AlertManager

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Update PASSTHROUGH_API_KEY documentation to clarify fallback behavior
- Add REQUIRE_PASSTHROUGH_KEY configuration option for strict validation
- Reject requests when REQUIRE_PASSTHROUGH_KEY=true but no valid API key is found
- Add configuration validation and example usage in documentation

Resolves feedback about silent fallback potentially bypassing quota tracking
in multi-tenant environments.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@jovermier
Copy link
Author

Security Improvements Added

I've addressed the code review concerns about passthrough API key security by adding:

  1. Documentation Update: Now clearly explains that PASSTHROUGH_API_KEY falls back to static keys when no valid key is found

  2. New Feature: Added environment variable for strict validation that:

    • Requires
    • Rejects requests with HTTP 401 when no valid API key is found
    • Prevents silent fallback to static keys
    • Ensures strict per-user quota tracking in multi-tenant environments
  3. Example Usage:
    SHELL=/bin/bash
    COREPACK_ENABLE_AUTO_PIN=0
    APPLICATION_INSIGHTS_NO_DIAGNOSTIC_CHANNEL=true
    CLAUDE_CODE_ENABLE_SDK_FILE_CHECKPOINTING=true
    HOSTNAME=infra
    LANGUAGE=en_US.UTF-8
    GIT_SSH_COMMAND=/home/coder/.coder/coder gitssh --
    CODER=true
    CODER_URL=https://coder.hahomelabs.com
    CREDENTIALS_S3_BUCKET_NAME=mycritters-shared-credentials
    ELECTRON_RUN_AS_NODE=1
    HOMEBREW_PREFIX=/home/linuxbrew/.linuxbrew
    VSCODE_PROXY_URI=https://{{port}}--main--infra--jovermier.coder.hahomelabs.com/
    CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1
    CODER_WORKSPACE_AGENT_NAME=main
    BINARY_DIR=/home/coder/.coder
    PWD=/home/coder/claude-code-proxy
    LOGNAME=coder
    TS_DEBUG_TRIM_WIREGUARD=false
    VSCODE_ESM_ENTRYPOINT=vs/workbench/api/node/extensionHostProcess
    PNPM_HOME=/home/coder/.local/share/pnpm
    GIT_COMMITTER_NAME=Jason Overmier
    NoDefaultCurrentDirectoryInExePath=1
    CLAUDECODE=1
    HOME=/home/coder
    CLAUDE_AGENT_SDK_VERSION=0.1.72
    LANG=en_US.UTF-8
    LS_COLORS=
    CS_DISABLE_FILE_DOWNLOADS=true
    CREDENTIALS_S3_SECRET_KEY=ACjWDIRrVIo97hDzQBqkFee4rCkvN4vspbI2C1Pu
    GIT_ASKPASS=/home/coder/.coder/coder
    VSCODE_L10N_BUNDLE_LOCATION=
    ANTHROPIC_BASE_URL=https://api.z.ai/api/anthropic
    CODER_WORKSPACE_NAME=infra
    SSH_CONNECTION=0.0.0.0 0 0.0.0.0 0
    GIT_AUTHOR_EMAIL=jason.r.overmier@gmail.com
    CODER_SESSION_TOKEN=rOCroa9TvK-q7JkpTH3QhfTIBpql0VyDc
    CODER_AGENT_AUTH=token
    INFOPATH=/home/linuxbrew/.linuxbrew/share/info:/home/linuxbrew/.linuxbrew/share/info:
    CODER_AGENT_TOKEN=6587e29e-fa14-46c3-a88a-ffa77eef5c75
    CODER_AGENT_URL=https://coder.hahomelabs.com/
    LESSCLOSE=/usr/bin/lesspipe %s %s
    GIT_COMMITTER_EMAIL=jason.r.overmier@gmail.com
    VSCODE_HANDLES_SIGPIPE=true
    LESSOPEN=| /usr/bin/lesspipe %s
    USER=coder
    CODER_SCRIPT_DATA_DIR=/tmp/coder-script-data/31b53cbd-5dae-4ae9-acc5-c85b2d372101
    CODE_SERVER_SESSION_SOCKET=/home/coder/.local/share/code-server/code-server-ipc.sock
    HOMEBREW_CELLAR=/home/linuxbrew/.linuxbrew/Cellar
    CREDENTIALS_S3_ACCESS_KEY=JTWGVZNP90TWWH384VDZ
    SHLVL=1
    GIT_EDITOR=true
    HOMEBREW_REPOSITORY=/home/linuxbrew/.linuxbrew/Homebrew
    VSCODE_CWD=/home/coder
    OTEL_EXPORTER_OTLP_METRICS_TEMPORALITY_PREFERENCE=delta
    ANTHROPIC_AUTH_TOKEN=ebde49948d47440999f0454bb9db7861.mQZsFyzVAZQhgbcm
    SSH_CLIENT=0.0.0.0 0 0
    CLAUDE_CODE_ENTRYPOINT=claude-vscode
    API_TIMEOUT_MS=3000000
    CS_DISABLE_GETTING_STARTED_OVERRIDE=true
    LC_ALL=en_US.UTF-8
    CODER_AGENT_BLOCK_FILE_TRANSFER=true
    CODER_AGENT_SUBSYSTEM=envbox
    GIT_AUTHOR_NAME=Jason Overmier
    CODER_SCRIPT_BIN_DIR=/tmp/coder-script-data/bin
    BROWSER=/tmp/code-server/lib/code-server-4.106.3/lib/vscode/bin/helpers/browser.sh
    PATH=/tmp/code-server/lib/code-server-4.106.3/lib/vscode/bin/remote-cli:/home/coder/.local/bin:/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin:/tmp/coder-script-data/bin:/home/coder/.local/share/pnpm:/home/linuxbrew/.linuxbrew/bin:/home/linuxbrew/.linuxbrew/sbin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/home/coder/.coder
    NODE_EXEC_PATH=/tmp/code-server/lib/code-server-4.106.3/lib/node
    CODER_WORKSPACE_OWNER_NAME=jovermier
    VSCODE_NLS_CONFIG={"userLocale":"en","osLocale":"en","resolvedLanguage":"en","defaultMessagesFile":"/tmp/code-server/lib/code-server-4.106.3/lib/vscode/out/nls.messages.json","locale":"en","availableLanguages":{}}
    DEBIAN_FRONTEND=noninteractive
    VSCODE_HANDLES_UNCAUGHT_ERRORS=true
    OLDPWD=/
    VSCODE_IPC_HOOK_CLI=/tmp/vscode-ipc-c571c94f-0485-4f82-a0f1-68d09e9a2e9c.sock
    CODE_SERVER_PARENT_PID=2256
    _=/usr/bin/env

These changes are committed to the main branch and address both code review items about documentation clarity and security concerns.

The implementation is backward compatible - existing behavior unchanged when is not enabled.

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