Skip to content

fix: prevent SDK "Not logged in" error before reaching gateway#127

Merged
nicknisi merged 3 commits intomainfrom
devin/1776965753-fix-sdk-not-logged-in
Apr 24, 2026
Merged

fix: prevent SDK "Not logged in" error before reaching gateway#127
nicknisi merged 3 commits intomainfrom
devin/1776965753-fix-sdk-not-logged-in

Conversation

@devin-ai-integration
Copy link
Copy Markdown
Contributor

@devin-ai-integration devin-ai-integration Bot commented Apr 23, 2026

Summary

Fixes #124.

The Claude Agent SDK's bundled CLI runs a local auth-source check at startup. If none of ANTHROPIC_API_KEY, ANTHROPIC_AUTH_TOKEN, CLAUDE_CODE_OAUTH_TOKEN, apiKeyHelper, or a /login-managed keychain entry is present in its environment, it immediately emits a result message with is_error: true and result: "Not logged in · Please run /login"never contacting the gateway at all (duration_api_ms: 0).

All four proxy / gateway paths in agent-interface.ts explicitly delete sdkEnv.ANTHROPIC_AUTH_TOKEN on the assumption that the credential / claim-token proxy handles Authorization upstream. For any user who doesn't happen to have Claude Code configured locally, that assumption leaves the SDK with apiKeySource: "none" and the installer fails with Not logged in · Please run /login before a single byte hits the WorkOS gateway.

This PR seeds a placeholder bearer token (workos-cli-proxy-placeholder) on the proxy / gateway paths so the SDK's local check passes. The credential proxy still rewrites the Authorization header with the real WorkOS token before forwarding upstream, so the placeholder never reaches the gateway. The user's personal ANTHROPIC_API_KEY is also stripped from sdkEnv on these paths so it can't leak into WorkOS-gateway requests. --direct mode is unchanged.

Reproduced directly against the bundled SDK CLI with no auth env:

$ env -i ANTHROPIC_BASE_URL=http://127.0.0.1:1 \
    node node_modules/@anthropic-ai/claude-agent-sdk/cli.js \
    --print --output-format stream-json --verbose "hi"
{"type":"system","subtype":"init",...,"apiKeySource":"none",...}
{"type":"assistant","message":{...,"content":[{"type":"text","text":"Not logged in · Please run /login"}]},...}
{"type":"result","subtype":"success","is_error":true,"duration_ms":94,"duration_api_ms":0,"result":"Not logged in · Please run /login",...}

With ANTHROPIC_AUTH_TOKEN set (to anything), the SDK proceeds past the local check and actually talks to the configured base URL — which in production is the credential proxy.

Review & Testing Checklist for Human

  • Install against a fresh machine that has no ANTHROPIC_API_KEY, ANTHROPIC_AUTH_TOKEN, or ~/.claude config, using a normal logged-in WorkOS session — confirm the agent actually starts and the install proceeds (previously failed immediately with "Not logged in · Please run /login").
  • Install with a valid ANTHROPIC_API_KEY already present in the shell env — confirm it's NOT forwarded to the WorkOS gateway (the credential proxy should see only Authorization: Bearer <workos-token>, no x-api-key).
  • workos install --direct still works and the user's ANTHROPIC_API_KEY is preserved on that path.
  • Unclaimed-environment / claim-token proxy path still works when running without an existing login.

Notes

  • Only agent-interface.ts changes; the proxy itself is unchanged (it already overwrites Authorization on the credential-proxy path).
  • I did not modify the delete sdkEnv.ANTHROPIC_AUTH_TOKEN in --direct mode — there we talk to api.anthropic.com directly and the user's real ANTHROPIC_API_KEY becomes the valid auth source, so no local-check failure.
  • The second symptom in Claude Code returned an error result: Not logged in · Please run /login #124 ("continue on a feature branch → Installer cancelled by user") was not independently reproducible from the code I read; it's most plausibly the downstream effect of the agent failing with "Not logged in" and the adapter rendering a generic cancellation message. Worth re-testing once this lands.

Link to Devin session: https://app.devin.ai/sessions/e17e4acdc96e43c19c7dbde249b826ba

Summary by CodeRabbit

Release Notes

  • Bug Fixes
    • Fixed a security issue where API credentials could be inadvertently forwarded to upstream services in certain configurations.
    • Improved authentication reliability across different credential management and proxy modes.
    • Enhanced SDK authentication handling to ensure proper credential isolation and routing in various deployment scenarios.

The Claude Agent SDK's CLI subprocess runs a local auth-source check at
startup and immediately emits a result message with is_error: true and
result 'Not logged in · Please run /login' — never reaching the gateway
— when none of ANTHROPIC_API_KEY, ANTHROPIC_AUTH_TOKEN,
CLAUDE_CODE_OAUTH_TOKEN, apiKeyHelper, or a '/login'-managed keychain
entry is present in its environment.

All four proxy / gateway paths in agent-interface.ts were explicitly
deleting ANTHROPIC_AUTH_TOKEN on the assumption that the credential
proxy handling Authorization upstream was sufficient. For any user
without Claude Code set up locally, that assumption left the SDK with
source 'none' and the installer failed with 'Not logged in · Please run
/login' before a single byte hit the WorkOS gateway.

Seed ANTHROPIC_AUTH_TOKEN with a placeholder on the proxy paths so the
SDK's local check passes (the credential proxy rewrites Authorization
with the real WorkOS token before forwarding), and strip the user's
personal ANTHROPIC_API_KEY from sdkEnv so it cannot leak upstream when
the proxy is in use. Direct mode is unchanged.

Fixes #124
@devin-ai-integration
Copy link
Copy Markdown
Contributor Author

Original prompt from nick.nisi@workos.com

Take a crack at this issue. See if there's anything obvious that might be causing the issue #124

@devin-ai-integration
Copy link
Copy Markdown
Contributor Author

🤖 Devin AI Engineer

I'll be helping with this pull request! Here's what you should know:

✅ I will automatically:

  • Address comments on this PR. Add '(aside)' to your comment to have me ignore it.
  • Look at CI failures and help fix them

Note: I can only respond to comments from users who have write access to this repository.

⚙️ Control Options:

  • Disable automatic comment and CI monitoring

@nicknisi
Copy link
Copy Markdown
Member

@greptileai

@nicknisi
Copy link
Copy Markdown
Member

/coderabbit review

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Apr 23, 2026

Greptile Summary

This PR fixes the Claude Agent SDK emitting "Not logged in" before reaching the WorkOS gateway by seeding a workos-cli-proxy-placeholder bearer token on all non-direct paths so the SDK's local auth-source check is satisfied, while simultaneously stripping any user ANTHROPIC_API_KEY from sdkEnv on those paths to prevent it leaking to the gateway. The previously flagged gap — the legacy fallback branch not stripping ANTHROPIC_API_KEY — is now closed (see delete sdkEnv.ANTHROPIC_API_KEY at line 461), and comprehensive tests cover all six auth paths.

Confidence Score: 5/5

Safe to merge — the prior P1 credential-leak gap on the legacy fallback path is fixed and all paths are now tested.

All previously identified P1 findings have been addressed. The only remaining finding is a P2 style suggestion about exporting the placeholder constant. No security regressions introduced.

No files require special attention.

Important Files Changed

Filename Overview
src/lib/agent-interface.ts Seeds placeholder bearer on all non-direct paths and strips user key everywhere including the previously-missed legacy fallback branch; logic is correct and well-commented.
src/lib/agent-interface.spec.ts Adds six focused initializeAgent tests covering credential-proxy, claim-token-proxy, skip-auth, local, legacy-fallback, and direct paths; credentials.js mock was already present so new imports wire up correctly.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[initializeAgent] --> B{direct?}
    B -- Yes --> C[User key preserved\nNo base URL override\nTalks to upstream directly]
    B -- No --> D{Unclaimed environment?}
    D -- Yes --> E[Claim-token proxy started\nSDK pointed at proxy\nUser key deleted\nPlaceholder bearer set]
    D -- No --> F{Normal gateway mode?}
    F -- No --> G{Skip-auth flag?}
    G -- Yes --> H[Pointed at gateway\nUser key deleted\nPlaceholder bearer set]
    G -- No --> I[Local dev mode\nPointed at gateway\nUser key deleted\nPlaceholder bearer set]
    F -- Yes --> J{Has credentials?}
    J -- No --> K[Throw: Not authenticated]
    J -- Yes --> L{Refresh token and proxy enabled?}
    L -- Yes --> M[Credential proxy started\nSDK pointed at proxy\nUser key deleted\nPlaceholder bearer set]
    L -- No --> N[Legacy fallback\nToken refreshed\nSDK pointed at gateway\nUser key deleted\nReal access token set]
Loading

Reviews (3): Last reviewed commit: "test(installer): use typed AgentConfig h..." | Re-trigger Greptile

Comment thread src/lib/agent-interface.ts
Addresses Greptile P1: the legacy fallback path (no refresh token or
INSTALLER_DISABLE_PROXY=1) still leaked the user's personal
ANTHROPIC_API_KEY to the WorkOS gateway as an x-api-key header
alongside the WorkOS access token. Every other non-direct path already
deletes it; this brings the legacy branch in line.

Also clarifies the skip-auth/local log messages to reflect that a
placeholder bearer is now forwarded to the gateway (the SDK's local
auth-source check would otherwise fail with 'Not logged in').

Co-Authored-By: nick.nisi@workos.com <nick.nisi@workos.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 23, 2026

📝 Walkthrough

Walkthrough

The changes update authentication handling in the agent interface to prevent user-provided Anthropic API keys from being forwarded to the WorkOS gateway, instead using a placeholder token. The implementation covers multiple auth modes including credential proxy, claim-token proxy, legacy token-forwarding, and local auth scenarios, with corresponding test coverage.

Changes

Cohort / File(s) Summary
Agent Interface Auth Configuration
src/lib/agent-interface.ts, src/lib/agent-interface.spec.ts
Adds placeholder bearer token constant and updates initializeAgent to prevent user-provided ANTHROPIC_API_KEY from being forwarded to WorkOS gateway. Sets ANTHROPIC_AUTH_TOKEN placeholder in credential proxy, claim-token proxy, skipAuth, and local modes. Legacy token-forwarding mode deletes ANTHROPIC_API_KEY while preserving real access token. Direct mode preserves ANTHROPIC_API_KEY without placeholder. Includes comprehensive test coverage for all auth scenarios.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed The PR directly addresses issue #124 by seeding a placeholder auth token to prevent the SDK's local auth check failure and enable gateway contact.
Out of Scope Changes check ✅ Passed All changes are scoped to fixing the premature 'Not logged in' error; modifications are limited to agent-interface.ts and its test file with no unrelated alterations.
Title check ✅ Passed The title clearly summarizes the main change: preventing the SDK's 'Not logged in' error from occurring before the request reaches the gateway.

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

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch devin/1776965753-fix-sdk-not-logged-in

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

@devin-ai-integration
Copy link
Copy Markdown
Contributor Author

Addressed the legacy-fallback P1 in 553ef3e: delete sdkEnv.ANTHROPIC_API_KEY before setting the WorkOS access token on the !refreshToken / INSTALLER_DISABLE_PROXY=1 branch, plus a new test case (strips ANTHROPIC_API_KEY on legacy fallback path).

For the skip-auth / local flag — left the placeholder in place but updated both log messages to stop claiming "no token sent to gateway" (they now read "placeholder bearer sent to gateway"). Reasoning in the inline reply: without a token the SDK's local auth-source check fails before any request is made, so these paths were effectively broken for the same users this PR fixes. Happy to revisit if the gateway team confirms the literal placeholder value is a problem on those paths.

Full test suite (1573) + typecheck + oxlint clean.

Spec files are excluded from pnpm typecheck, which masked a latent type
mismatch in makeAgentConfigForInit (returned installDir instead of the
required workOSApiKey / workOSApiHost fields). Ann otate the helper
return type and align fields with AgentConfig so it would catch
regressions under a stricter typecheck config.

Co-Authored-By: nick.nisi@workos.com <nick.nisi@workos.com>
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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/lib/agent-interface.spec.ts`:
- Around line 409-414: The helper makeAgentConfigForInit currently returns the
wrong shape; update it to return a real AgentConfig object matching
initializeAgent's expectations by including workOSApiKey and workOSApiHost (as
test strings) along with workingDirectory and installDir so the returned value
is type-compatible with initializeAgent; locate makeAgentConfigForInit in the
spec and replace the returned object with an AgentConfig-shaped object
containing workOSApiKey, workOSApiHost, workingDirectory, and installDir.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 7d4c3314-02d2-4ea4-80c1-d8dc2b2d9747

📥 Commits

Reviewing files that changed from the base of the PR and between 802a5db and 553ef3e.

📒 Files selected for processing (2)
  • src/lib/agent-interface.spec.ts
  • src/lib/agent-interface.ts

Comment thread src/lib/agent-interface.spec.ts Outdated
@nicknisi nicknisi changed the title Fix SDK emitting "Not logged in" before reaching gateway fix: prevent SDK "Not logged in" error before reaching gateway Apr 24, 2026
@nicknisi nicknisi merged commit 69c2d7d into main Apr 24, 2026
6 checks passed
@nicknisi nicknisi deleted the devin/1776965753-fix-sdk-not-logged-in branch April 24, 2026 02:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

Claude Code returned an error result: Not logged in · Please run /login

1 participant