Skip to content

fix(sdk-bridge/claude): route through cube identity via CLAUDE_CONFIG_DIR#209

Merged
jacsamell merged 1 commit into
mainfrom
fix-claude-sdk-cube-identity
May 23, 2026
Merged

fix(sdk-bridge/claude): route through cube identity via CLAUDE_CONFIG_DIR#209
jacsamell merged 1 commit into
mainfrom
fix-claude-sdk-cube-identity

Conversation

@jacsamell
Copy link
Copy Markdown
Contributor

@jacsamell jacsamell commented May 23, 2026

Summary

Closes the auth-routing gap surfaced in Phase 3 dogfood: claude-sdk runs were billing the operator's terminal Claude Code session, not cube's separate identity. Now resolves `CLAUDE_CONFIG_DIR` from the same convention (`~/.cube/claude-config/` or `$CUBE_CLAUDE_CONFIG_DIR` override) the legacy `claude.py` adapter uses.

Why

The bundled `claude` binary that `claude-agent-sdk` spawns reads `CLAUDE_CONFIG_DIR` for auth. Without it, the binary loads the operator's `~/.claude/` and bills their account.

Test plan

  • 3 new tests covering claude provider sets the var, env override honoured, codex+cursor untouched
  • 16/16 sdk-bridge tests pass; 245/245 full suite passes

🤖 Generated with Claude Code

Summary

This PR fixes an authentication routing gap where Claude SDK runs were incorrectly billing the operator's terminal session instead of the cube's identity.

Key Changes:

  • Added _resolve_cube_claude_config_dir() function that checks $CUBE_CLAUDE_CONFIG_DIR (if set and exists) or falls back to ~/.cube/claude-config/, mirroring the legacy claude.py adapter's convention
  • Modified SDKBridgeAdapter.run() to explicitly set CLAUDE_CONFIG_DIR in the subprocess environment for the claude provider only when a cube identity directory is resolved
  • Codex and Cursor providers remain unaffected—they inherit the parent environment without modification

Tests: Added three test cases verifying that the claude provider injects the correct CLAUDE_CONFIG_DIR, the $CUBE_CLAUDE_CONFIG_DIR override is honoured, and codex/cursor providers do not touch the variable. Full test suite passes (245/245).

Review Change Stack

…_DIR

Phase 3 dogfood operator question: "the claude sdk is using the agent
cube creds yea not my one here?" — answer was NO. claude-sdk runs
were billing the operator's interactive terminal session, not cube's.

The legacy claude.py adapter sets CLAUDE_CONFIG_DIR to point at
~/.cube/claude-config/ so the spawned `claude` binary picks up cube's
OAuth tokens. SDKBridgeAdapter just inherited parent env without that
resolution, so the bundled claude binary (claude-agent-sdk wraps the
same binary under the hood) loaded the operator's `~/.claude/` instead.

This PR ports the resolver:
1. _resolve_cube_claude_config_dir() — same logic as claude.py:
   - $CUBE_CLAUDE_CONFIG_DIR override if set + dir exists
   - ~/.cube/claude-config/ default if it exists
   - else None (use whatever auth is in parent env)
2. SDKBridgeAdapter.run() sets env['CLAUDE_CONFIG_DIR'] when provider
   is 'claude' AND a cube identity is resolved. Codex and Cursor are
   untouched — they have their own auth (OPENAI_*, CURSOR_API_KEY).

Tests: 3 new tests covering claude sets the var, $CUBE_CLAUDE_CONFIG_DIR
override is honoured, codex/cursor do NOT touch CLAUDE_CONFIG_DIR.

16/16 sdk-bridge tests pass; 245/245 in tests/ pass.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@jacsamell jacsamell merged commit 0719965 into main May 23, 2026
@jacsamell jacsamell deleted the fix-claude-sdk-cube-identity branch May 23, 2026 10:51
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 23, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 97a3314e-63ce-43c9-94d9-334c06568bd5

📥 Commits

Reviewing files that changed from the base of the PR and between f508759 and 9e8f4cd.

📒 Files selected for processing (2)
  • python/cube/core/adapters/sdk_bridge.py
  • tests/cli/test_sdk_bridge_adapter.py

Walkthrough

The PR adds environment variable routing to set CLAUDE_CONFIG_DIR in subprocess contexts for the Claude SDK bridge adapter. A module constant and resolver function determine the config directory from environment overrides or cube's default path, then SDKBridgeAdapter.run() explicitly injects this into subprocess environments for the Claude provider only.

Changes

Claude Config Directory Environment Routing

Layer / File(s) Summary
Config directory resolver and constant
python/cube/core/adapters/sdk_bridge.py
Module constant _DEFAULT_CUBE_CLAUDE_CONFIG_DIR and helper _resolve_cube_claude_config_dir() resolve the config directory by checking for CUBE_CLAUDE_CONFIG_DIR override, falling back to the default cube config path when it exists, returning None otherwise.
Subprocess environment setup for Claude provider
python/cube/core/adapters/sdk_bridge.py
SDKBridgeAdapter.run() now explicitly constructs subprocess environment via os.environ.copy() and conditionally sets CLAUDE_CONFIG_DIR for the claude provider using the resolved directory.
Test coverage for config directory environment routing
tests/cli/test_sdk_bridge_adapter.py
Three async tests verify environment variable routing: default cube config injection when no override is set, respecting explicit CUBE_CLAUDE_CONFIG_DIR values, and preserving pre-existing values for non-Claude providers (Codex, Cursor).

Estimated Code Review Effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Possibly Related PRs

  • aetheronhq/agent-cube#153: Modifies Claude subprocess credential and config routing in claude.py with related environment variable and login flow changes.

Poem

🐇 A config path that bravely hops, from cube's default through env stops,
The Claude subprocess now knows where to dwell, with tests to verify all works well!
🌟


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

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