Skip to content

Add Anthropic OAuth (Claude Pro/Max) sign-in to Orbit alongside API-key auth #29

@nekrut

Description

@nekrut

Motivation

Orbit currently requires users to paste an Anthropic API key into the welcome screen / Preferences. For Claude Pro / Max subscribers, OAuth-based sign-in (the same flow Claude Code uses) would be a much better first-run experience — no console trip, no key management, no leaked-secret risk. It also opens the door to GitHub Copilot, Google Gemini CLI, and OpenAI Codex sign-ins via the same plumbing.

Most of the work is already in pi-ai

@mariozechner/pi-ai/utils/oauth/anthropic.ts exposes the full PKCE flow:

  • loginAnthropic({ onAuth, onPrompt, onProgress, onManualCodeInput }) — opens a Node HTTP callback server, generates the auth URL, waits for the redirect, exchanges the code for tokens, returns OAuthCredentials.
  • refreshAnthropicToken(refreshToken) — token rotation.
  • anthropicOAuthProviderOAuthProviderInterface registration helper.

Sibling providers exist for GitHub Copilot, Gemini CLI, Antigravity, and OpenAI Codex — the same surface.

pi-coding-agent already wires OAuth into its auth storage:

  • core/model-registry.ts calls registerOAuthProvider.
  • authStorage.getOAuthProviders() enumerates registered providers.
  • migrations.js migrates legacy oauth.jsonauth.json with {type: \"oauth\", ...creds} records.
  • auth.json already supports a mixed store of apiKey + oauth entries.

So the brain side is essentially free. 401 → refresh-and-retry should already be in pi-coding-agent's request pipeline.

What Orbit needs to add

  1. Main-process auth handler (~30 lines, new file app/src/main/auth-handler.ts):

    • Calls loginAnthropic({ onAuth: ({url}) => shell.openExternal(url), onPrompt: ..., onProgress: ... }).
    • The onAuth(url) fires once the local callback server is up; Orbit launches the user's default browser.
    • When loginAnthropic resolves, persist the credentials via pi-coding-agent's authStorage.
    • Single in-flight lock so multiple windows don't fight.
  2. Three IPC endpoints in ipc-handlers.ts:

    • auth:login(provider) — kicks off the flow; resolves on success or error.
    • auth:status() — returns the current sign-in state per provider (signed in / handle / expiry; or none).
    • auth:logout(provider) — clear credentials.
    • Preload exposure: window.orbit.signIn(provider), window.orbit.authStatus(), window.orbit.signOut(provider).
  3. Welcome screen (index.html + app.ts):

    • Add a primary "Sign in with Claude" button above the API-key field.
    • Keep the API-key input as a fallback (corporate networks, custom endpoints, sandboxed deployments).
    • On click, call signIn(\"anthropic\"), show a small spinner while waiting, dismiss the welcome on success.
  4. Preferences modal:

    • Show signed-in state ("Signed in as <email>" or "Using API key (last 4: …)") with a "Sign out" link.
    • Sign-in button below for users who want to swap from API-key to OAuth (or vice versa).
  5. Migration on first run: invoke migrations.js's legacy-oauth migrator at agent startup so existing pi-coding-agent users on this machine pick up their tokens automatically.

Pitfalls / things to plan for

  • Random callback portloginAnthropic picks a free local port; Linux/macOS will prompt for a firewall exception once. On Windows, the first launch shows a firewall dialog. Mention this in the welcome flow if helpful.
  • Corporate networks that block claude.ai/oauth — keep the API-key path as a permanent fallback, do not remove it.
  • "Only intended for CLI use" — pi-ai's note refers to the http.createServer callback; Electron's main process is Node-side, so this is fine. Do not try to call loginAnthropic from the renderer.
  • Token-refresh visibility — pi-coding-agent should refresh transparently on 401, but if it surfaces an error to the agent shell when the refresh token also expires, Orbit should display "Sign-in expired — please sign in again" instead of letting it silently break the next turn.

Out of scope / future

  • GitHub Copilot, Gemini CLI, OpenAI Codex sign-ins — same code path; once Anthropic works, these are 1-line registrations in the auth handler. File as a follow-up issue once the Anthropic flow is shipping.
  • An "Account" tab in Preferences listing all providers + their statuses. Nice-to-have; not blocking the MVP.

Estimate

Half a day to a day for a polished MVP — the OAuth callback orchestration is the only "real" code, everything else is wiring buttons and state pills.

Happy to put up a PR for this once approved if no one else has it queued.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions