Skip to content

Support headless relayed launch with CLAUDE_CODE_OAUTH_TOKEN + relayed e2e test - #479

Draft
masonc08 wants to merge 2 commits into
mainfrom
masonc08/relayed-oauth-token-guard
Draft

Support headless relayed launch with CLAUDE_CODE_OAUTH_TOKEN + relayed e2e test#479
masonc08 wants to merge 2 commits into
mainfrom
masonc08/relayed-oauth-token-guard

Conversation

@masonc08

@masonc08 masonc08 commented Sep 3, 2026

Copy link
Copy Markdown
Collaborator

What

Makes the relayed (subscription-relay) claude launch runnable headlessly, and adds an e2e test for it.

1. Login guard (agents/claude.py). _ensure_subscription_login shells out to claude auth login (a browser flow) when no persisted login is found — which hangs an unattended/CI run. When CLAUDE_CODE_OAUTH_TOKEN is set (the claude setup-token output that supplies the subscription OAuth credential headlessly), it is the Authorization credential Claude Code uses directly, so the interactive login doesn't apply. Return early when it's set, before the auth status probe. Relayed writes no apiKeyHelper and sets no ANTHROPIC_API_KEY, so this token is the top credential Claude Code resolves.

2. Relayed e2e test (tests/test_e2e.py). Exercises the relayed launch end to end: starts the real loopback refresh proxy (as _launch_relayed does), writes the relayed provider config, and runs a one-shot validate_cmd so a request flows through the credential-swap proxy → gateway → Anthropic subscription. It stays inert until the supporting infra exists — skips unless CLAUDE_CODE_OAUTH_TOKEN is set and a relayed MPS is discoverable on the workspace.

Why

Relayed had no live e2e coverage because it couldn't run headless (interactive subscription OAuth). claude setup-token + CLAUDE_CODE_OAUTH_TOKEN closes that gap; the guard prevents the browser fallback from hanging CI.

To activate the e2e test in CI

  1. Run claude setup-token once (interactive), store the output as a CLAUDE_CODE_OAUTH_TOKEN GitHub Actions secret and export it in the e2e job.
  2. Provision a relayed Anthropic MPS on the CI test workspace.

Until both land, the test skips — no CI change in behavior.

Testing

  • New hermetic unit tests TestEnsureSubscriptionLogin (3): token-set skips all CLI shell-out; existing login skips the browser; no-login + no-token runs claude auth login. Pass.
  • Full test_agent_claude.py 139/139; test_e2e.py collects (32) and the relayed test skips cleanly. ruff clean.

This pull request and its description were written by Isaac.

masonc08 and others added 2 commits September 3, 2026 18:03
Relayed launch calls `_ensure_subscription_login`, which shells out to
`claude auth login` (a browser flow) when no persisted login is found. In a
headless/CI run that hangs. A pre-provisioned OAuth token (`claude setup-token`
output, injected via CLAUDE_CODE_OAUTH_TOKEN) is the Authorization credential
Claude Code uses directly, so no interactive login applies — return early when
it is set, before the auth-status probe. Relayed writes no apiKeyHelper and sets
no ANTHROPIC_API_KEY, so this token is the top credential Claude Code resolves.

Co-authored-by: Isaac <no-reply@databricks.com>
Exercises the relayed (subscription-relay) claude launch end to end: starts the
real loopback refresh proxy as `_launch_relayed` does, writes the relayed
provider config, and runs a one-shot `validate_cmd` so a request flows through
the credential-swap proxy to the gateway and out to the Anthropic subscription.

Gated to stay inert until the infra exists: skips unless CLAUDE_CODE_OAUTH_TOKEN
is set (the `claude setup-token` output that supplies the subscription OAuth
credential headlessly, per the login guard) and a relayed MPS is discoverable on
the workspace. Feeds the proxy the e2e bearer for the swap token, matching the
other launch tests.

Co-authored-by: Isaac <no-reply@databricks.com>
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