Skip to content

feat(OAuth):Add Claude subscription OAuth provider#59

Open
S-Foxx wants to merge 1 commit intoagent0ai:mainfrom
S-Foxx:feature/claude-subscription-oauth
Open

feat(OAuth):Add Claude subscription OAuth provider#59
S-Foxx wants to merge 1 commit intoagent0ai:mainfrom
S-Foxx:feature/claude-subscription-oauth

Conversation

@S-Foxx
Copy link
Copy Markdown

@S-Foxx S-Foxx commented May 6, 2026

Summary

Adds a third optional LLM provider for the admin and onscreen agents that signs users in with their Claude subscription instead of an API key. Several users (and the author) have asked for this; the goal is to let people use Space Agent against the model their Claude subscription already pays for, without pasting raw API keys.

The default API-key flow and the local Hugging Face flow are completely untouched. Subscription mode is opt-in per surface, gated by ANTHROPIC_OAUTH_ALLOWED (default true).

What it does

  • New segmented control: API key · Claude subscription · Local in both agent settings dialogs
  • Subscription tab embeds a reusable connect block: click Connect with Claude, approve in a popup on claude.ai, copy the code Anthropic shows on its hosted page, paste, click Finish connecting
  • Curated dropdown of Claude subscription models (Opus 4.7 / Sonnet 4.6 / Haiku 4.5). Aliases resolve to the latest dated release on Anthropic's side, so newer model drops do not require a Space Agent update
  • Status row reads "Connected to Claude · ACTIVE" with the account email and a one-line note explaining that Space Agent silently refreshes the access token, plus a Disconnect button
  • API-key and local provider paths and validation are unchanged

How it works

  • Browser-side _core/anthropic_oauth/ owns the connect block, the request-hook extension that redirects subscription-mode requests to a dedicated server endpoint, and a small client.js around the four OAuth endpoints
  • Server-side _core/auth/anthropic_oauth.js owns PKCE, AES-256-GCM token sealing, encrypted persistence at L2/<user>/meta/anthropic_oauth.json, lazy refresh, and the read-only status helper
  • Five new endpoints under server/api/:
    • oauth_anthropic_authorize (POST)
    • oauth_anthropic_callback (GET for redirect mode, POST for paste mode)
    • oauth_anthropic_status (GET)
    • oauth_anthropic_disconnect (POST)
    • anthropic_subscription_completions (POST) — translates OpenAI chat-completions to Anthropic Messages API and back, so the existing fetch readers in the agents stay unchanged
  • Default flow mode is the manual code-paste flow because the public Claude Code OAuth client does not allowlist arbitrary localhost redirect URIs. ANTHROPIC_OAUTH_FLOW_MODE=redirect is available as opt-in for deployments that register their own Anthropic OAuth client (override ANTHROPIC_OAUTH_CLIENT_ID to use it)
  • Tokens never reach the browser; the server injects the bearer plus the anthropic-beta: oauth-2025-04-20 and anthropic-version headers when streaming to api.anthropic.com/v1/messages
  • Refresh tokens are auto-rotated 60s before access-token expiry, and on a single 401 from the upstream

Runtime params (all with sensible public defaults)

Param Default Purpose
ANTHROPIC_OAUTH_ALLOWED true Hide the subscription option entirely when false
ANTHROPIC_OAUTH_CLIENT_ID published Claude Code public client Override with your own registered Anthropic OAuth client to enable redirect-mode
ANTHROPIC_OAUTH_AUTHORIZE_URL https://claude.ai/oauth/authorize
ANTHROPIC_OAUTH_TOKEN_URL https://console.anthropic.com/v1/oauth/token
ANTHROPIC_OAUTH_REDIRECT_URI Anthropic-hosted code page Used in paste mode
ANTHROPIC_OAUTH_FLOW_MODE auto (resolves to paste) Set to redirect if you have a registered client
ANTHROPIC_API_BASE_URL https://api.anthropic.com Override for proxied deployments

Documentation

Updated in the same commit:

  • /AGENTS.md runtime params + module index
  • /app/AGENTS.md module index + module description
  • /server/api/AGENTS.md new endpoint family
  • /server/lib/auth/AGENTS.md new owned file + storage contract
  • /app/L0/_all/mod/_core/admin/views/agent/AGENTS.md
  • /app/L0/_all/mod/_core/onscreen_agent/AGENTS.md
  • /app/L0/_all/mod/_core/visual/AGENTS.md (.field select shared contract)
  • New /app/L0/_all/mod/_core/anthropic_oauth/AGENTS.md

Tests

tests/anthropic_oauth_test.mjs — 10 focused tests:

  • Endpoint defaults (Claude Code public client) and runtime-param overrides
  • PKCE verifier + authorize URL composition for both flow modes
  • auto resolves to paste on local and non-local hosts
  • Explicit redirect opt-in produces a local callback URL
  • Status helper reports disconnected + reads sealed records back into UI metadata round-trip
  • Disconnect helper is a no-op when no record exists

$ node --test tests/anthropic_oauth_test.mjs
Total tests: 10
Tests passed: 10
Test failed: 10

Test plan

  • Connect end-to-end against a real Claude subscription on localhost
  • Disconnect, reconnect, send messages with each of Opus 4.7 / Sonnet 4.6 / Haiku 4.5
  • Verify the API-key flow and the local Hugging Face flow still work
  • Verify the subscription endpoint silently refreshes the access token
  • Verify subscription tokens never reach the browser (network panel: /api/anthropic_subscription_completions carries no Authorization)

Backwards compatibility

  • Existing settings YAML round-trips unchanged
  • New llm_provider: subscription value is forward-only; older Space Agent versions that read this YAML will fall through to the API normalizer (paste-safe)
  • Encrypted token file uses a fresh AES-GCM seal derived from password_seal_key so it inherits the existing rotation policy

Add an optional third LLM provider for the admin and onscreen agents
that authenticates with Anthropic via the user's Claude subscription
instead of an API key. The browser owns the connect flow and a
reusable settings-dialog block; the server owns the OAuth state cache,
the encrypted token store under L2/<user>/meta/anthropic_oauth.json,
silent refresh, and a dedicated streaming completions endpoint that
translates between OpenAI chat-completions shape and Anthropic
Messages API shape so the existing browser fetch readers stay
unchanged.

- New `_core/anthropic_oauth/` browser module with a connect block,
  request hook, and per-surface extensions for the admin and onscreen
  prepareXxxApiRequest seams. Subscription mode redirects API-mode
  requests to /api/anthropic_subscription_completions and strips the
  Authorization header so the bearer token never reaches the browser.
- Five new server endpoints: oauth_anthropic_authorize, _callback (GET
  for redirect mode + POST for paste mode), _status, _disconnect, and
  anthropic_subscription_completions. Tokens are sealed with
  AES-256-GCM using a sub-key derived from the existing password seal
  key; refresh tokens are auto-rotated 60s before access-token expiry
  and on upstream 401.
- Provider enums extended with `subscription` for both admin and
  onscreen agents; existing api/local paths and validation are
  untouched. The settings dialog gains a third segmented tab with a
  curated Claude model dropdown (Opus 4.7, Sonnet 4.6, Haiku 4.5),
  hides the params field for subscription mode (Anthropic's
  subscription tier rejects user-supplied temperature on newer
  models), and embeds the connect block.
- Default flow mode is the manual code-paste flow because the public
  Claude Code OAuth client does not allowlist arbitrary localhost
  callbacks. Redirect mode is opt-in via ANTHROPIC_OAUTH_FLOW_MODE for
  deployments that ship their own registered Anthropic OAuth client.
- Six new runtime params (ANTHROPIC_OAUTH_ALLOWED, _CLIENT_ID,
  _AUTHORIZE_URL, _TOKEN_URL, _REDIRECT_URI, _FLOW_MODE,
  ANTHROPIC_API_BASE_URL) with safe public defaults so the feature
  works out of the box; existing user secret model is reused.
- meta/anthropic_oauth.json added to the L2 git-history ignore list so
  refresh-token rotation does not churn local-history commits.
- Shared visual primitive .field now styles `select` consistently with
  `input` and `textarea` so future dialog selects match without
  per-feature CSS.
- Documentation updated across AGENTS.md (root, app, server/api,
  server/lib/auth, admin/views/agent, onscreen_agent, visual) plus a
  new anthropic_oauth/AGENTS.md for the module contract. Ten focused
  unit tests cover endpoint defaults, runtime-param overrides, PKCE
  authorize URL composition, both flow modes, and the sealed-record
  status round trip.
@S-Foxx S-Foxx changed the title Add Claude subscription OAuth provider feat(OAuth):Add Claude subscription OAuth provider May 6, 2026
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