Skip to content

fix(proxy): swap placeholder secrets in auth headers unconditionally#153

Closed
vinit-patel-athena wants to merge 1 commit into
lobu-ai:mainfrom
vinit-patel-athena:fix/proxy-placeholder-swap-system-keys
Closed

fix(proxy): swap placeholder secrets in auth headers unconditionally#153
vinit-patel-athena wants to merge 1 commit into
lobu-ai:mainfrom
vinit-patel-athena:fix/proxy-placeholder-swap-system-keys

Conversation

@vinit-patel-athena
Copy link
Copy Markdown

Summary

  • Fix proxy credential resolution for API key authentication (both system keys from .env and keys entered through the settings UI)
  • The URL-based credential path (added in 1dbcb8c) only looked up per-user auth profiles and set Authorization: Bearer. When the credential was an API key (not OAuth), the x-api-key header still contained the lobu_secret_* placeholder, which was sent to the upstream provider and rejected as invalid.
  • Split credential resolution into two unconditional steps: (1) auth profile lookup, then (2) placeholder swap for any remaining lobu_secret_* values in auth headers

Problem

The else branch guarding the placeholder swap meant it only ran when the URL-based path was not taken. Since all modern deployments include /a/{agentId} in the proxy URL, the URL-based path was always entered and the placeholder swap was always skipped.

This affected:

  • System API keys set via ANTHROPIC_API_KEY / ANTHROPIC_AUTH_TOKEN in .env
  • API keys entered through the settings UI (authType: "api-key")

OAuth users were unaffected because OAuth credentials flow through CLAUDE_CODE_OAUTH_TOKEN which uses the "lobu-proxy" marker and Authorization: Bearer header (resolved in step 1).

Test plan

  • Deploy with ANTHROPIC_API_KEY in .env (no OAuth), send a message via REST API, verify the agent responds
  • Deploy with API key entered through settings UI, send a message, verify the agent responds
  • Deploy with OAuth authentication, send a message, verify no regression

Made with Cursor

The URL-based credential resolution path (introduced in 1dbcb8c) only
looked up per-user auth profiles and set Authorization: Bearer. When no
auth profile existed (system API key from .env), the x-api-key header
still contained the lobu_secret_* placeholder, which was sent to the
upstream provider and rejected as invalid.

This happened because the placeholder swap logic was guarded by an
`else` branch that only ran when the URL-based path was not taken.
System keys (e.g. ANTHROPIC_API_KEY) are stored as UUID placeholder
mappings in Redis, not as auth profiles, so the URL-based path found
no profile and the legacy swap path was skipped entirely.

Split credential resolution into two unconditional steps:
1. Auth profile lookup (when agentId is in the URL)
2. Placeholder swap for any auth headers still containing lobu_secret_*

Step 2 now runs regardless of whether step 1 found a profile, so
system keys in x-api-key and Authorization headers are always resolved.
OAuth users are unaffected since their credentials use the "lobu-proxy"
marker (not a UUID placeholder) and are resolved in step 1.

Made-with: Cursor
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