Skip to content

feat(providers): add anthropic-oauth provider for subscription plan auth#1923

Closed
cjfit wants to merge 1 commit into
NVIDIA:mainfrom
cjfit:feat/anthropic-subscription-oauth
Closed

feat(providers): add anthropic-oauth provider for subscription plan auth#1923
cjfit wants to merge 1 commit into
NVIDIA:mainfrom
cjfit:feat/anthropic-subscription-oauth

Conversation

@cjfit

@cjfit cjfit commented Jun 16, 2026

Copy link
Copy Markdown

Summary

Adds an anthropic-oauth provider type (alias claude-plan) so sandboxes can run Claude Code on an Anthropic Pro/Max subscription plan instead of a metered API key. The subscription OAuth token is harvested, stored, and refreshed entirely outside the sandbox and injected only at the egress proxy boundary — it is never written into the sandbox environment, filesystem, or logs. This reuses the existing gateway-side OAuth2 refresh machinery and the non-injectable/proxy-only credential path (the same pattern as the Vertex --from-gcloud-adc flow).

Related Issue

N/A — no tracking issue.

Changes

  • inference (openshell-core): new anthropic-oauth profile — Authorization: Bearer plus a mandatory anthropic-beta: oauth-2025-04-20 default header (subscription tokens require it where API keys do not). normalize_inference_provider_type aliases claude-plan.
  • router (openshell-router): merge the mandatory anthropic-beta flag with any client-sent anthropic-beta value into a single header, so a sandbox client cannot drop the OAuth flag (and we never emit a duplicate header).
  • server (openshell-server): mark ANTHROPIC_OAUTH_TOKEN non-injectable so it rides the inference route bundle but is never exported into the sandbox env.
  • cli (openshell-cli): provider create --from-claude-login reads the local Claude Code login (macOS Keychain Claude Code-credentials or ~/.claude/.credentials.json), stores the access token as the proxy-only credential, and configures the gateway's Oauth2RefreshToken background refresh (Anthropic public client_id, no client secret). Includes create-failure rollback.
  • provider profile: new providers/anthropic-oauth.yaml.
  • docs: new docs/providers/anthropic-subscription.mdx; updated architecture/gateway.md and the provider table in docs/sandboxes/manage-providers.mdx.

Testing

  • mise run pre-commit passes (lint, format, license headers, full unit suite — clippy -D warnings clean).
  • Unit tests added: profile/alias resolution and Bearer + default-header derivation; the non-injectable rule and a resolve_provider_environment assertion that the access token is never returned to the sandbox; the router anthropic-beta merge (mandatory flag survives, no duplicate, Bearer injected); CLI credential JSON parsing (field extraction, ms/seconds expiry normalization, missing-field errors).
  • Manual e2e on macOS (validated end-to-end): claude login on host → openshell provider create --name claude-plan --type anthropic-oauth --from-claude-loginopenshell inference set --provider claude-plan --model claude-sonnet-4-6 → sandbox bound to the provider → ANTHROPIC_BASE_URL=https://inference.local ANTHROPIC_API_KEY=unused claude -p "…" returns a 200 completion.
  • Token-never-in-sandbox verified: inside the sandbox the OAuth token does not appear in env/filesystem; the Authorization: Bearer header is applied at the egress boundary, not by the sandbox.
  • Linux not yet validated. The CLI reader is OS-agnostic for the file path: the Keychain reader is macOS-gated and falls through to ~/.claude/.credentials.json, which is where Claude Code writes its login on Linux. This should work unchanged but has not been validated on Linux (and a keyring-backed Linux login, if any, is not yet supported).

Note for maintainers (ghcr images)

The supervisor applies the Bearer + anthropic-beta headers at the sandbox boundary, so the supervisor image must be rebuilt for this feature to take effect — a stale supervisor silently drops the headers and Anthropic rejects the request. On merge to main, release-dev.yml rebuilds and republishes gateway:dev and supervisor:dev, so keep the two on the same build.

Checklist

  • Follows Conventional Commits
  • Commits are signed off (DCO)
  • Architecture docs updated (architecture/gateway.md) and user docs added (docs/providers/anthropic-subscription.mdx)

Add an `anthropic-oauth` provider type (alias `claude-plan`) so sandboxes can
run Claude Code on an Anthropic Pro/Max subscription. The OAuth token is
harvested, stored, and refreshed entirely outside the sandbox and injected only
at the egress boundary; it is never written into the sandbox environment,
filesystem, or logs.

- inference: new anthropic-oauth profile (Authorization: Bearer plus a mandatory
  anthropic-beta: oauth-2025-04-20 default header)
- router: merge the mandatory anthropic-beta flag with any client-sent value so
  the sandbox cannot drop it
- server: mark ANTHROPIC_OAUTH_TOKEN non-injectable (proxy-only)
- cli: add `provider create --from-claude-login` to read the local Claude Code
  login (macOS Keychain or ~/.claude/.credentials.json) and wire the gateway's
  OAuth2 background refresh
- docs: add the Anthropic Subscription provider page and update gateway
  architecture and provider tables

The macOS path (Keychain) is validated end-to-end. Linux reads the same
~/.claude/.credentials.json file and should work unchanged, but has not yet been
validated on Linux.

Signed-off-by: Cedric Fitzgerald <soulcedric2@gmail.com>
@cjfit cjfit requested review from a team, derekwaynecarr and mrunalp as code owners June 16, 2026 02:03
@copy-pr-bot

copy-pr-bot Bot commented Jun 16, 2026

Copy link
Copy Markdown

This pull request requires additional validation before any workflows can run on NVIDIA's runners.

Pull request vetters can view their responsibilities here.

Contributors can view more details about this message here.

@github-actions

Copy link
Copy Markdown

Thank you for your submission! We ask that you sign our Developer Certificate of Origin before we can accept your contribution. You can sign the DCO by adding a comment below using this text:


I have read the DCO document and I hereby sign the DCO.


You can retrigger this bot by commenting recheck in this Pull Request. Posted by the DCO Assistant Lite bot.

@github-actions

Copy link
Copy Markdown

Thank you for your interest in contributing to OpenShell, @cjfit.

This project uses a vouch system for first-time contributors. Before submitting a pull request, you need to be vouched by a maintainer.

To get vouched:

  1. Open a Vouch Request discussion.
  2. Describe what you want to change and why.
  3. Write in your own words — do not have an AI generate the request.
  4. A maintainer will comment /vouch if approved.
  5. Once vouched, open a new PR (preferred) or reopen this one after a few minutes.

See CONTRIBUTING.md for details.

@github-actions github-actions Bot closed this Jun 16, 2026
@cjfit cjfit deleted the feat/anthropic-subscription-oauth branch June 16, 2026 02:07
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