Skip to content

fix(ai): use pass-through endpoint for Claude Max OAuth forwarding#965

Merged
jlengelbrecht merged 1 commit intomainfrom
story-063-passthrough-fix
Jan 29, 2026
Merged

fix(ai): use pass-through endpoint for Claude Max OAuth forwarding#965
jlengelbrecht merged 1 commit intomainfrom
story-063-passthrough-fix

Conversation

@jlengelbrecht
Copy link
Copy Markdown
Owner

@jlengelbrecht jlengelbrecht commented Jan 29, 2026

Summary

Workaround for LiteLLM bug #19618 where clean_headers() strips the Authorization header before forwarding to Anthropic, breaking Claude Max OAuth authentication.

Relates to: STORY-063

The Problem

LiteLLM's header processing strips the Authorization header containing the OAuth token before it can be forwarded to Anthropic. This prevents Claude Max subscription authentication from working through LiteLLM.

Fix PRs exist (#19802, #19912) but are not yet merged.

Solution

Use LiteLLM's pass-through endpoint feature with forward_headers: true, which bypasses the header stripping logic and forwards all client headers (including Authorization) directly to Anthropic.

Changes

LiteLLM ConfigMap:

  • Add /anthropic pass-through endpoint targeting https://api.anthropic.com
  • Enable forward_headers: true to preserve OAuth token
  • Configure guardrails (lakera-guard, openai-mod) on pass-through

Moltbot HelmRelease:

  • Update ANTHROPIC_BASE_URL to use pass-through path (/anthropic)
  • Remove ANTHROPIC_MODEL (model specified in request body with pass-through)

Security

  • Guardrails still enforced on pass-through endpoint
  • LiteLLM authentication still required (auth: true)
  • OAuth token forwarded only to Anthropic (not other providers)
  • security-guardian review passed

Testing

  • LiteLLM pod restarts successfully
  • Moltbot pod restarts successfully
  • Send message via Moltbot
  • Verify request appears in LiteLLM logs
  • Verify Claude responds (OAuth auth works)
  • Verify guardrails triggered (check logs)

References

Pull Request Summary

Services and Namespaces Affected

  • LiteLLM (ai namespace): ConfigMap updated with Anthropic pass-through endpoint configuration
  • Moltbot (ai namespace): HelmRelease updated to route Claude requests through pass-through endpoint

Breaking Changes

  • ANTHROPIC_MODEL environment variable removed from Moltbot - any dependent services or monitoring referencing this variable will require updates
  • ANTHROPIC_BASE_URL endpoint path modified from http://litellm.ai.svc.cluster.local:4000 to http://litellm.ai.svc.cluster.local:4000/anthropic - requires coordinated deployment of both LiteLLM and Moltbot to maintain service continuity

Security Implications

  • OAuth token forwarding enabled: The pass-through endpoint configuration with forward_headers: true preserves the Authorization header for Claude Max OAuth authentication, forwarding the token only to Anthropic API (https://api.anthropic.com)
  • Guardrails maintained on pass-through: lakera-guard (prompt injection detection) and openai-mod (content policy compliance) remain enforced on the /anthropic endpoint via request_fields: ["messages[*].content"]
  • LiteLLM authentication enforced: auth: true setting on the pass-through endpoint ensures all requests still require LiteLLM master key authentication before forwarding to Anthropic
  • Workaround for LiteLLM bug #19618: This PR implements a temporary solution while upstream LiteLLM fixes are pending - the bug caused clean_headers() to strip Authorization headers before forwarding requests

Flux Dependency Impacts

  • Coordinated deployment required: Both LiteLLM ConfigMap and Moltbot HelmRelease must be synchronized during deployment - mismatched versions could cause service degradation (pass-through endpoint misconfigured while Moltbot expects it)
  • Pod restart required: Both LiteLLM and Moltbot pods must restart for changes to take effect
  • No Talos, SOPS, or ExternalSecrets changes identified

Resource Changes

  • LiteLLM ConfigMap: +18 lines (new /anthropic pass-through endpoint with guardrail configuration in pass_through_endpoints)
  • Moltbot HelmRelease: +3/-4 lines (ANTHROPIC_BASE_URL value modified, ANTHROPIC_MODEL field removed, documentation comments updated)
  • Total impact: Minimal configuration changes with significant functional impact on Claude Max OAuth flow

Deployment Checklist

  • Verify both LiteLLM and Moltbot pods restart successfully
  • Confirm OAuth token forwarding in LiteLLM logs
  • Test Claude Code Gateway via Moltbot to ensure OAuth authentication succeeds
  • Validate guardrail logs show lakera-guard and openai-mod enforcement on /anthropic requests

STORY-063: Workaround for LiteLLM bug #19618 where clean_headers()
strips Authorization header before forwarding to Anthropic.

Pass-through endpoint with forward_headers: true preserves all
client headers including OAuth token for Claude Max subscription.

Changes:
- Add /anthropic pass-through endpoint in LiteLLM ConfigMap
- Configure guardrails (lakera-guard, openai-mod) on pass-through
- Update Moltbot ANTHROPIC_BASE_URL to use pass-through path
- Remove ANTHROPIC_MODEL (not needed with pass-through)

Reference: https://docs.litellm.ai/docs/pass_through/anthropic_completion
Copilot AI review requested due to automatic review settings January 29, 2026 05:29
@homebot-0 homebot-0 bot added the area/kubernetes Changes to Kubernetes manifests and apps label Jan 29, 2026
@homebot-0
Copy link
Copy Markdown
Contributor

homebot-0 bot commented Jan 29, 2026

ℹ️ SOPS Encryption Check

No SOPS files detected in this pull request.

Check Status
SOPS files in PR ✅ None detected

No encryption validation required for this PR.

@homebot-0
Copy link
Copy Markdown
Contributor

homebot-0 bot commented Jan 29, 2026

✅ Gitleaks Secret Scan Passed

No secrets detected in this pull request.

Check Status
Secret patterns ✅ Clean
Sensitive files ✅ None detected

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Jan 29, 2026

Walkthrough

The changes configure Anthropic API pass-through forwarding in LiteLLM with per-message content guardrails, while updating MoltBot's Anthropic client configuration to route through the new LiteLLM /anthropic endpoint and removing the model specification variable.

Changes

Cohort / File(s) Summary
LiteLLM Anthropic Pass-Through
kubernetes/apps/ai/litellm/app/configmap.yaml
Added pass_through_endpoints configuration targeting https://api.anthropic.com with token forwarding and per-model guardrails (lakera-guard, openai-mod). Configuration appears duplicated in file under general_settings.
MoltBot Anthropic Integration
kubernetes/apps/ai/moltbot/app/helmrelease.yaml
Updated ANTHROPIC_BASE_URL to point to LiteLLM pass-through path (/anthropic suffix). Removed ANTHROPIC_MODEL environment variable. Added comments referencing forward_headers approach and LiteLLM bug workaround.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Key attention areas:

  • Breaking change: ANTHROPIC_MODEL removal may impact dependent services
  • Configuration duplication: LiteLLM ConfigMap contains duplicated pass-through block
  • Security relevance: Verify guardrail policies (lakera-guard, openai-mod) are appropriate for message inspection
  • Routing correctness: Confirm MoltBot's new /anthropic path aligns with LiteLLM's pass_through_endpoints configuration

Suggested labels

area/kubernetes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: implementing a pass-through endpoint for Claude Max OAuth forwarding in LiteLLM configuration, which directly corresponds to the ConfigMap and HelmRelease modifications.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch story-063-passthrough-fix

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@homebot-0
Copy link
Copy Markdown
Contributor

homebot-0 bot commented Jan 29, 2026

--- kubernetes/apps/ai/moltbot/app Kustomization: ai/moltbot HelmRelease: ai/moltbot

+++ kubernetes/apps/ai/moltbot/app Kustomization: ai/moltbot HelmRelease: ai/moltbot

@@ -51,20 +51,18 @@

                 fs.writeFileSync(f, JSON.stringify(c, null, 2));
               "
               exec node dist/entry.js gateway \
                 --port 18789 --bind lan --verbose
             env:
               ANTHROPIC_BASE_URL:
-                value: http://litellm.ai.svc.cluster.local:4000
+                value: http://litellm.ai.svc.cluster.local:4000/anthropic
               ANTHROPIC_CUSTOM_HEADERS:
                 valueFrom:
                   secretKeyRef:
                     key: ANTHROPIC_CUSTOM_HEADERS
                     name: moltbot-secrets
-              ANTHROPIC_MODEL:
-                value: claude-default
               ANTHROPIC_OAUTH_TOKEN:
                 valueFrom:
                   secretKeyRef:
                     key: ANTHROPIC_OAUTH_TOKEN
                     name: moltbot-secrets
               CLAWDBOT_GATEWAY_TOKEN:
--- kubernetes/apps/ai/litellm/app Kustomization: ai/litellm ConfigMap: ai/litellm-config

+++ kubernetes/apps/ai/litellm/app Kustomization: ai/litellm ConfigMap: ai/litellm-config

@@ -219,12 +219,30 @@

       # STORY-150: Request timeout must accommodate longest cold start (wan-video: 420s)
       # Per-model timeouts take precedence, but this is the fallback default
       request_timeout: 420
       # STORY-059: Allow setting api_base for search tools via admin API
       # Required to configure self-hosted SearXNG endpoint
       allow_client_side_credentials: true
+
+      # =====================================================
+      # STORY-063: Anthropic Pass-Through for Claude Max OAuth
+      # Workaround for LiteLLM bug (Issue #19618) where Authorization
+      # header is stripped before forwarding to Anthropic.
+      # Pass-through with forward_headers: true preserves OAuth token.
+      # Reference: https://docs.litellm.ai/docs/pass_through/anthropic_completion
+      # =====================================================
+      pass_through_endpoints:
+        - path: "/anthropic"
+          target: "https://api.anthropic.com"
+          forward_headers: true
+          auth: true
+          guardrails:
+            lakera-guard:
+              request_fields: ["messages[*].content"]
+            openai-mod:
+              request_fields: ["messages[*].content"]
 
     litellm_settings:
       # Drop unsupported params instead of erroring
       drop_params: true
       # Enable logging for audit
       set_verbose: false

@homebot-0
Copy link
Copy Markdown
Contributor

homebot-0 bot commented Jan 29, 2026

--- HelmRelease: ai/moltbot Deployment: ai/moltbot

+++ HelmRelease: ai/moltbot Deployment: ai/moltbot

@@ -103,20 +103,18 @@

             fs.writeFileSync(f, JSON.stringify(c, null, 2));
           "
           exec node dist/entry.js gateway \
             --port 18789 --bind lan --verbose
         env:
         - name: ANTHROPIC_BASE_URL
-          value: http://litellm.ai.svc.cluster.local:4000
+          value: http://litellm.ai.svc.cluster.local:4000/anthropic
         - name: ANTHROPIC_CUSTOM_HEADERS
           valueFrom:
             secretKeyRef:
               key: ANTHROPIC_CUSTOM_HEADERS
               name: moltbot-secrets
-        - name: ANTHROPIC_MODEL
-          value: claude-default
         - name: ANTHROPIC_OAUTH_TOKEN
           valueFrom:
             secretKeyRef:
               key: ANTHROPIC_OAUTH_TOKEN
               name: moltbot-secrets
         - name: CLAWDBOT_GATEWAY_TOKEN

@jlengelbrecht jlengelbrecht merged commit 3a45854 into main Jan 29, 2026
18 of 19 checks passed
@jlengelbrecht jlengelbrecht deleted the story-063-passthrough-fix branch January 29, 2026 05:32
Copy link
Copy Markdown

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

Routes Anthropic (Claude Max OAuth) traffic through LiteLLM using a pass-through endpoint to work around a LiteLLM bug that strips the Authorization header during normal forwarding.

Changes:

  • Adds a LiteLLM /anthropic pass-through endpoint targeting https://api.anthropic.com with header forwarding enabled.
  • Updates Moltbot to use the new /anthropic base URL path (and removes the explicit ANTHROPIC_MODEL env var).

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.

File Description
kubernetes/apps/ai/moltbot/app/helmrelease.yaml Points Moltbot’s Anthropic base URL at LiteLLM’s new /anthropic pass-through endpoint.
kubernetes/apps/ai/litellm/app/configmap.yaml Adds the pass-through endpoint configuration intended to preserve Anthropic OAuth headers and keep guardrails enabled.

Comment on lines +234 to +240
# Pass-through with forward_headers: true preserves OAuth token.
# Reference: https://docs.litellm.ai/docs/pass_through/anthropic_completion
# =====================================================
pass_through_endpoints:
- path: "/anthropic"
target: "https://api.anthropic.com"
forward_headers: true
Copy link

Copilot AI Jan 29, 2026

Choose a reason for hiding this comment

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

forward_headers: true will forward all incoming headers to https://api.anthropic.com, which can leak LiteLLM authentication material (e.g., Authorization: Bearer <master/virtual key> for clients that use bearer auth, and/or x-litellm-api-key) to the upstream provider. Since litellm ingress allows traffic from any pod in the ai namespace (and the internal gateway), this is a real credential-exfil path. Prefer forwarding only the minimal required header(s) for Claude Max OAuth (typically Authorization) and explicitly ensure LiteLLM auth headers are not forwarded upstream (e.g., via an allowlist/denylist mechanism or a dedicated auth header for LiteLLM separate from Authorization).

Suggested change
# Pass-through with forward_headers: true preserves OAuth token.
# Reference: https://docs.litellm.ai/docs/pass_through/anthropic_completion
# =====================================================
pass_through_endpoints:
- path: "/anthropic"
target: "https://api.anthropic.com"
forward_headers: true
# Pass-through with a restricted forward_headers allowlist preserves
# the OAuth token without leaking LiteLLM-specific auth headers.
# Reference: https://docs.litellm.ai/docs/pass_through/anthropic_completion
# =====================================================
pass_through_endpoints:
- path: "/anthropic"
target: "https://api.anthropic.com"
forward_headers:
- "authorization"
- "anthropic-version"
- "anthropic-beta"

Copilot uses AI. Check for mistakes.
Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@kubernetes/apps/ai/litellm/app/configmap.yaml`:
- Around line 238-241: The pass-through route for path "/anthropic" currently
uses forward_headers: true which leaks all client headers; remove
forward_headers: true from the /anthropic route in configmap.yaml and either add
a explicit headers: list containing only required headers for Anthropic, or
implement an upstream proxy (NGINX/Envoy) to strip sensitive headers before
requests reach the /anthropic target, or replace the pass-through with a custom
adapter that constructs outgoing requests with only safe headers; update the
configuration for the "/anthropic" route (path "/anthropic", target
"https://api.anthropic.com") accordingly.

Comment on lines +238 to +241
- path: "/anthropic"
target: "https://api.anthropic.com"
forward_headers: true
auth: true
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🌐 Web query:

LiteLLM forward_headers allowlist header filtering pass-through proxy

💡 Result:

In LiteLLM pass-through endpoints, header forwarding is currently all-or-nothing:

  • forward_headers: true will forward all incoming request headers to the target endpoint. (docs.litellm.ai)
  • There is no documented “allowlist” / per-header filter option for pass-through routes (the pass-through config spec only exposes headers: (static headers) and forward_headers: (boolean)). (docs.litellm.ai)

Example (forwards everything):

general_settings:
  pass_through_endpoints:
    - path: "/v1/rerank"
      target: "https://api.cohere.com/v1/rerank"
      headers:
        Authorization: "bearer os.environ/COHERE_API_KEY"
        content-type: application/json
        accept: application/json
      forward_headers: true

(docs.litellm.ai)

If you need an allowlist (only some headers)

You’ll need to do it outside of pass-through, e.g.:

  • Put an upstream proxy (NGINX/Envoy/API Gateway) in front of LiteLLM to strip/allow only specific headers before they reach LiteLLM, or
  • Write a custom adapter/callback that explicitly constructs the outbound request/headers, instead of using a pure pass-through route. (docs.litellm.ai)

Related (non pass-through) header forwarding controls

For normal model calls (not pass-through), LiteLLM provides forward_client_headers_to_llm_api, which enables forwarding for specific model groups, but it still isn’t a per-header allowlist; it forwards certain categories (notably x-* headers, with some exclusions) when enabled. (docs.litellm.ai)

Also note there’s been historical confusion/bugs around pass-through header behavior (see GitHub issue). (github.com)

Citations:


🌐 Web query:

LiteLLM pass-through proxy configuration header forwarding documentation

💡 Result:

LiteLLM “pass-through proxy” header forwarding is documented under Pass Through Endpoints:

  • Config key: general_settings.pass_through_endpoints[].forward_headers: true
    This enables forwarding the original incoming request headers to the upstream “target” endpoint (in addition to any static headers: you define). Example in docs shows headers: plus forward_headers: true. [1]

  • Where it’s documented: “Create Pass Through Endpoints” → Config.yaml Setup / Configuration Reference (includes headers and forward_headers). [1]

Related (non-pass-through) header forwarding docs (for forwarding client headers to LLM provider APIs, not arbitrary pass-through targets):

  • general_settings.forward_client_headers_to_llm_api: true (global) or enable per model group via litellm_settings.model_group_settings.forward_client_headers_to_llm_api. [3]
  • Overview of supported/special request headers is listed under “Request Headers”. [2]

Sources:
[1] LiteLLM Docs — Create Pass Through Endpoints (pass-through + forward_headers) (docs.litellm.ai)
[2] LiteLLM Docs — Request Headers (docs.litellm.ai)
[3] LiteLLM Docs — Forward Client Headers to LLM API (docs.litellm.ai)

Citations:


🌐 Web query:

LiteLLM "forward_headers" allowed_headers whitelist configuration

💡 Result:

LiteLLM has two different “forward headers” features, and neither currently supports an allowed_headers (whitelist) config knob:

1) Proxy → LLM provider header forwarding (model-group controlled)

This is configured via forward_client_headers_to_llm_api (globally or per model group). When enabled, LiteLLM forwards only specific categories (effectively a built-in allowlist), e.g.:

  • Custom x-... headers (with exceptions like x-stainless-*)
  • Some provider-specific headers (e.g., Anthropic beta headers; OpenAI org header when separately enabled)
    There is no documented allowed_headers whitelist you can set—control is via enabling/disabling forwarding per model group. [1]

2) Pass-through endpoints header forwarding

For pass_through_endpoints, the per-route flag is:

general_settings:
  pass_through_endpoints:
    - path: "/v1/..."
      target: "https://..."
      forward_headers: true

forward_headers: true forwards all incoming request headers to the target endpoint; docs do not mention any allowed_headers filtering/whitelist option. [2]

If you need a whitelist today

  • For pass-through endpoints, you generally have to not use forward_headers: true and instead explicitly set/override the needed headers under headers: (but that won’t dynamically “pass through” arbitrary client headers). Lack of fine-grained “forward only these headers” control has been raised as a feature request/limitation. [3]

Sources: Forward client headers docs [1], pass-through endpoint docs [2], related GitHub issue discussing header pass-through control [3].


Remove forward_headers: true or implement header filtering to prevent credential leakage.

forward_headers: true forwards all incoming client headers to Anthropic, including internal LiteLLM auth credentials and cookies. LiteLLM's pass-through endpoint configuration does not support an allowlist—you must either:

  1. Remove forward_headers: true and explicitly define only required headers under headers:
  2. Deploy an upstream proxy (NGINX/Envoy) in front of LiteLLM to strip sensitive headers before reaching the pass-through endpoint
  3. Replace the pass-through route with a custom adapter that constructs requests with only safe headers

Without one of these mitigations, all client headers are forwarded to the external Anthropic API.

🤖 Prompt for AI Agents
In `@kubernetes/apps/ai/litellm/app/configmap.yaml` around lines 238 - 241, The
pass-through route for path "/anthropic" currently uses forward_headers: true
which leaks all client headers; remove forward_headers: true from the /anthropic
route in configmap.yaml and either add a explicit headers: list containing only
required headers for Anthropic, or implement an upstream proxy (NGINX/Envoy) to
strip sensitive headers before requests reach the /anthropic target, or replace
the pass-through with a custom adapter that constructs outgoing requests with
only safe headers; update the configuration for the "/anthropic" route (path
"/anthropic", target "https://api.anthropic.com") accordingly.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/kubernetes Changes to Kubernetes manifests and apps

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants