Skip to content

feat(claude-agent-sdk): add deterministic auth modes and readiness - #522

Open
David Gómez (ldavidgomez) wants to merge 4 commits into
microsoft:mainfrom
ldavidgomez:feat/claude-auth-readiness-preflight
Open

feat(claude-agent-sdk): add deterministic auth modes and readiness#522
David Gómez (ldavidgomez) wants to merge 4 commits into
microsoft:mainfrom
ldavidgomez:feat/claude-auth-readiness-preflight

Conversation

@ldavidgomez

Copy link
Copy Markdown
Contributor

Summary

  • Adds deterministic auth_mode support for claude-agent-sdk:
    • subscription selects the child-process subscription path by clearing API-key/token variables only through ClaudeAgentOptions.env.
    • api_key requires an inherited API key and clears the competing auth token.
    • auto preserves the CLI's inherited credential resolution.
  • Adds bounded, sanitized auth-readiness checks and structured conductor doctor --check diagnostics.
  • Hardens subprocess cleanup, including cancellation during the spawn window.
  • Makes ordinary tests hermetic: no local Claude CLI, login, or credentials required.
  • Documents the supported contract and limitations.

Validation

  • Independent review accepted the implementation.
  • ruff check . passes after rebase.
  • Focused provider, diagnostics, doctor, plugin, and factory tests: 436 passed; two Windows symlink-privilege failures are pre-existing and unrelated.
  • A hermetic full-suite comparison against the rebase base found no ticket-attributable regression; upstream CI remains the final gate.

Notes

  • Builds on the ProviderRegistry concurrency fix already released in v0.1.37.
  • This change does not claim billing attribution or rely on a real model invocation as evidence.

🤖 Generated with Claude Code

@ldavidgomez

Copy link
Copy Markdown
Contributor Author

Example configurations

Use subscription when the workflow should explicitly use the Claude subscription login available to the child process:

provider:
  type: claude-agent-sdk
  auth_mode: subscription

Use api_key when the runner supplies ANTHROPIC_API_KEY and API-key authentication is required:

provider:
  type: claude-agent-sdk
  auth_mode: api_key

Use auto only when preserving the Claude CLI's inherited credential resolution is intentional:

provider:
  type: claude-agent-sdk
  auth_mode: auto

subscription and api_key make the intended authentication path explicit for the provider subprocess. auto preserves existing CLI precedence and is therefore intentionally less deterministic.

…light

- Add ProviderSettings.auth_mode (auto/subscription/api_key) to make the
  credential path explicit rather than relying on ambient env inference
- _check_auth_readiness() resolves mode before CLI probe (F7); skips the
  subprocess entirely for api_key mode and for auto+ANTHROPIC_API_KEY
- Env-conflict check (ANTHROPIC_API_KEY/ANTHROPIC_AUTH_TOKEN) is gated on
  subscription mode only — auto mode with ANTHROPIC_AUTH_TOKEN alone now
  resolves correctly to subscription (F1)
- _run_auth_status_subprocess() returns (stdout, stderr, returncode) 3-tuple;
  removes _AUTH_STATUS_STDERR ContextVar hidden side-channel (F6)
- OSError from create_subprocess_exec is caught and returned as a sanitized
  ClaudeAuthStatus rather than escaping as FileNotFoundError (F3)
- interrupt_waiter task is initialised to None before the try block and
  cancelled+awaited in the CancelledError handler so no asyncio task is
  orphaned on outer cancellation (F4)
- Update two existing tests to mock _check_auth_readiness — validate_connection
  now also asserts auth readiness, and an interrupt pre-set fires before
  fake_query is called (F2)
- Remove AgentOps harness scaffolding erroneously appended to AGENTS.md (F5)
- Correct AGENTS.md / CHANGELOG docs: env-conflict is subscription-only;
  validate_connection() returns False (not raises) on failure; cancellation
  leaves no orphaned task

Closes TICKET-20260816-0002

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
…ery tests

`TestClaudeAgentSdkDelivery` drives a real `ClaudeAgentSdkProvider`
through `execute()` while stubbing only the SDK seam (`query`,
`ClaudeAgentOptions`). The authentication readiness preflight runs
before any of that, so all three tests failed on a missing credential
instead of on the component wiring they assert.

These were red from the moment the preflight landed, but invisible
locally: `pytest.importorskip("claude_agent_sdk")` skips the whole
module unless the optional extra is installed. CI does install it
(`ci.yml`), so they would have failed there.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@ldavidgomez
David Gómez (ldavidgomez) force-pushed the feat/claude-auth-readiness-preflight branch from 2c74b3c to 6d97da7 Compare September 11, 2026 18:09
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