Files
flynn/docs/plans/2026-02-15-credential-system-v2-api-and-oauth-checklist.md
T
2026-02-15 10:17:07 -08:00

7.4 KiB

Credential System v2 (API + OAuth/token) — Implementation Checklist

Date: 2026-02-15

Parent roadmap: docs/plans/2026-02-15-openclaw-gap-roadmap.md

Goal: Close the gap item "OAuth subscription auth" by supporting both API-key credentials and OAuth/token-based credentials (provider-specific) with consistent UX, per-tier control, and deterministic resolution.

Scope Summary

  • Add auth_mode per tier (default/fast/complex/local and any local_providers entries).
  • Keep backward compatibility with existing use_oauth behavior.
  • Add stored credential support where it currently doesn't exist:
    • OpenAI: stored API key (OAuth already exists)
    • Anthropic: stored auth token (API key already exists)
  • Improve doctor output to surface which auth sources are present (without revealing secrets).

Non-goals (explicitly out of scope for this checklist):

  • Inventing an Anthropic OAuth device flow.
  • Building new provider integrations (Vercel/MiniMax/etc.).

Current Baseline (important constraints)

  • OpenAI OAuth uses the ChatGPT/Codex backend endpoint (SSE) and currently does not support tools on that path.
    • Source: src/models/openai.ts
  • Anthropic supports apiKey and authToken in AnthropicClientConfig.
    • Source: src/models/anthropic.ts
  • Stored credentials live at ~/.config/flynn/auth.json.
    • Source: src/auth/openai.ts, src/auth/anthropic.ts

Design Decisions

1) New config field: auth_mode

Add auth_mode to the per-tier model config:

  • auto (default)
  • api_key
  • oauth

oauth is interpreted as "OAuth/token mode" (provider-specific). For Anthropic, that means auth_token.

2) Backward compatibility: use_oauth

Preserve use_oauth as a compatibility alias.

Recommended rule:

  • If auth_mode is set: it wins.
  • Else if use_oauth: true: treat as auth_mode: oauth.

3) Credential resolution order

For each provider, resolve the required credential type by trying:

  1. config (api_key / auth_token)
  2. env var
  3. auth store (~/.config/flynn/auth.json)

auth_mode controls which credential type is required.

PR Breakdown (atomic, test-backed)

PR 1 — Schema + docs: per-tier auth_mode

Checklist:

  • Add auth_mode to modelConfigBaseSchema in src/config/schema.ts.
  • Update src/config/schema.test.ts to cover defaults + validation.
  • Update README.md config examples (brief mention).
  • Update config/default.yaml comment/help text (brief mention).

Acceptance:

  • Config parses with no changes (defaults preserved).
  • Setting auth_mode: oauth or auth_mode: api_key validates.

Tests:

  • pnpm test:run src/config/schema.test.ts

PR 2 — OpenAI auth store: add API-key storage

Goal: allow OpenAI to run without api_key in YAML.

Checklist:

  • Extend src/auth/openai.ts AuthStore shape to allow openai.api_key alongside existing OAuth info.
  • Add functions:
    • loadStoredOpenAIApiKey()
    • storeOpenAIApiKey(key)
    • clearOpenAIApiKey()
    • getOpenAIApiKey() (env override + store)
  • Keep existing OAuth store code working unchanged.
  • Add/extend tests for new store functions.

Files:

  • src/auth/openai.ts
  • src/auth/openai.test.ts (or add if missing)

Acceptance:

  • Stored OpenAI API key is written to ~/.config/flynn/auth.json with 0600 permissions.
  • OAuth entry remains backward compatible.

Tests:

  • pnpm test:run src/auth/openai.test.ts

PR 3 — Anthropic auth store: add auth-token storage

Goal: allow auth_token to be stored and selected with auth_mode: oauth.

Checklist:

  • Extend src/auth/anthropic.ts auth store shape to include auth_token.
  • Add functions:
    • loadStoredAnthropicAuthToken()
    • storeAnthropicAuthToken(token)
    • clearAnthropicAuthToken()
    • getAnthropicAuthToken()
  • Extend src/auth/anthropic.test.ts.

Files:

  • src/auth/anthropic.ts
  • src/auth/anthropic.test.ts

Acceptance:

  • auth_token can be stored and resolved without being present in YAML.

Tests:

  • pnpm test:run src/auth/anthropic.test.ts

PR 4 — CLI commands for managing new stored credentials

Checklist:

  • Add flynn openai-key command (store API key in auth.json).
  • Extend flynn anthropic-auth to support storing either API key or auth token:
    • recommended: flynn anthropic-auth --token OR flynn anthropic-token
  • Update src/cli/index.ts registration.

Files:

  • src/cli/openai-key.ts (new)
  • src/cli/anthropic-auth.ts (modify)
  • src/cli/index.ts

Acceptance:

  • CLI can store credentials without printing them.
  • Re-running commands detects existing stored credentials and exits cleanly.

Tests:

  • Add targeted unit tests if the CLI layer has existing patterns; otherwise validate via integration tests where feasible.

PR 5 — TUI /login UX: OpenAI choice (OAuth vs API key) + Anthropic token

Checklist:

  • Update /login openai in src/frontends/tui/minimal.ts:
    • Present a simple prompt: "1) OAuth device flow 2) Paste API key"
    • Store selected credential via auth store
  • Add /login anthropic in src/frontends/tui/minimal.ts:
    • "1) Paste API key 2) Paste auth token"
  • Keep existing /login github and /login zai behavior intact.

Files:

  • src/frontends/tui/minimal.ts
  • src/frontends/tui/commands.ts (if command parsing needs to accept new provider)

Acceptance:

  • TUI can store OpenAI API key or OAuth token.
  • TUI can store Anthropic API key or auth token.

Tests:

  • Add or extend minimal TUI tests as needed (existing suite patterns exist for model switching).

PR 6 — Model factory: enforce auth_mode per tier

This is the core runtime change.

Checklist:

  • Update src/daemon/models.ts:
    • Read cfg.auth_mode (or inferred from use_oauth) per tier.
    • For OpenAI:
      • auth_mode=oauth: configure OpenAIClient({ useOAuth: true }) and verify OAuth tokens exist.
      • auth_mode=api_key: configure OpenAIClient({ apiKey: resolvedKey }).
    • For Anthropic:
      • auth_mode=oauth: require auth token (config/env/store).
      • auth_mode=api_key: require API key (config/env/store).
    • For other providers:
      • define behavior explicitly (likely api_key only unless provider already supports token-style auth).
    • Ensure error messages name the expected auth type and remediation.

Files:

  • src/daemon/models.ts
  • potentially src/models/openai.ts (if you decide to unify API key vs OAuth selection naming)

Tests:

  • src/daemon/clientFactory.test.ts
    • auth_mode precedence over use_oauth
    • auto -> api key path
    • oauth -> token path
    • correct failures when missing

Acceptance:

  • Selecting auth_mode changes runtime behavior deterministically.

PR 7 — Doctor: report auth source availability

Checklist:

  • Extend checkModelConnectivity in src/cli/doctor.ts to reflect auth_mode:
    • If auth_mode=api_key, warn/fail when API key is absent from config/env/store.
    • If auth_mode=oauth, warn/fail when OAuth/token is absent.
    • If auth_mode=auto, keep current behavior but improve messaging.
  • Add tests in src/cli/doctor.test.ts.

Acceptance:

  • Doctor output tells user what to do next (command name + env var) without exposing secrets.

Final Integration Checks

  • pnpm typecheck
  • pnpm test:run
  • Update docs/plans/state.json entry for this checklist once implemented (status, summary, test status).