Files
flynn/docs/plans/2026-02-15-credential-system-v2-api-and-oauth-checklist.md
T

260 lines
7.6 KiB
Markdown

# Credential System v2 (API + OAuth/token) — Implementation Checklist
> **Archived (2026-02-18):** Historical implementation checklist. Canonical status is tracked in `docs/plans/state.json`; unchecked boxes here are not active backlog unless explicitly re-opened.
**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).