summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
Diffstat (limited to 'docs')
-rw-r--r--docs/oauth-provider-auth.md72
1 files changed, 72 insertions, 0 deletions
diff --git a/docs/oauth-provider-auth.md b/docs/oauth-provider-auth.md
index 9ae63a7..a29f13b 100644
--- a/docs/oauth-provider-auth.md
+++ b/docs/oauth-provider-auth.md
@@ -493,3 +493,75 @@ None of these are required for Copilot or Codex auth correctness.
- The correct Codex subscription-backed model request endpoint and wire API.
- Whether to add OS keychain storage in the first pass or after file-backed
auth works end to end.
+
+---
+
+## Implementation status (as built)
+
+The first pass landed as a clean break (no compatibility shim): every networked
+provider must name an `[auth.<name>]` session via `auth = "<name>"`;
+provider-level `api_key`/`api_key_env_var` are gone. Resolved decisions for the
+open questions above: TOML uses `key_env_var`; `auth` is required for networked
+providers; Codex device auth is modelled as a `dialect = "codex"` variant of
+the generic `oauth_device` type; keychain storage is deferred (file-backed
+`$PANTO_HOME/auth/<name>.json`, owner-only `0600`).
+
+### What core owns (libpanto)
+
+- `auth.zig` — auth config types (`AuthConfig`), the persisted `TokenSet`, token
+ storage (load/save/delete), the device flow (both dialects), refresh, the
+ Copilot exchange, JWT `exp` parsing, Codex account-id extraction, and the
+ pure credential/refresh-predicate helpers. No Lua dependency.
+- `http_helper.zig` — a non-streaming request/response helper over the
+ process-global `std.http.Client`, plus dotted-JSON-path readers.
+- Providers gained `extra_headers`, merged onto the built-in request headers.
+
+### What the CLI owns (`src/`)
+
+- `config_file.zig` parses `[auth.<name>]` and the `auth = "<name>"` reference,
+ resolving `api_key` sessions eagerly (literal/env). Providers always survive
+ resolution; an unresolved session fails the request with a clear error.
+- `auth_manager.zig` resolves the active provider's auth before each turn
+ (load → login → refresh → exchange → build credential), patching the live
+ `ProviderConfig` (bearer, dynamic `base_url`, merged headers).
+- The TUI runs an inline device login when no token is stored, and forces one
+ refresh/exchange retry on a `ProviderAuthFailed` (401/403).
+- `panto auth status | login <name> | logout <name>` subcommands provide a
+ line-based login path outside the TUI.
+
+### Device-flow specifics (verified against reference clients)
+
+- **GitHub Copilot** (`dialect = "token"`): request `/login/device/code`, poll
+ `/login/oauth/access_token` until the OAuth token (`ghu_…`) arrives, then a
+ per-~30-min exchange (GET `/copilot_internal/v2/token`) yields the chat token,
+ its expiry, and `endpoints.api` (the runtime `base_url`). Copilot speaks the
+ OpenAI Chat Completions wire format, so it is a plain `openai_chat` provider —
+ this path is structurally complete.
+- **OpenAI Codex** (`dialect = "codex"`): POST
+ `…/deviceauth/usercode` → poll `…/deviceauth/token` (403/404 = pending). The
+ poll **returns a server-generated PKCE `code_verifier` alongside the
+ authorization code**, so the client does *not* generate PKCE for device flow;
+ it relays the verifier when exchanging the code at `/oauth/token` for
+ `{access,refresh,id}_token`. Refresh uses `grant_type=refresh_token`. The
+ account id comes from the `id_token` JWT claim `https://api.openai.com/auth`
+ → `chatgpt_account_id`, sent as `chatgpt-account-id`.
+
+### Codex model endpoint — resolved open question
+
+Research confirmed the Codex subscription endpoint is **not** Chat Completions:
+it is the OpenAI **Responses API** at
+`https://chatgpt.com/backend-api/codex/responses` (request body uses `input`
+items, `reasoning`, `include: ["reasoning.encrypted_content"]`, `store: false`;
+headers `Authorization: Bearer`, `chatgpt-account-id`,
+`OpenAI-Beta: responses=experimental`, `originator: codex_cli_rs`). That is a
+new wire dialect, implemented as the `openai_responses` provider style (see
+below), distinct from `openai_chat`.
+
+### Verification status
+
+Unit tests cover config parsing, token storage round-trips, JWT/account-id
+extraction, credential building, refresh/exchange predicates, form encoding,
+and header merging. The HTTP-dependent flows (device login, refresh, exchange,
+Responses streaming) follow verified reference implementations but require live
+credentials (a GitHub Copilot subscription / a ChatGPT plan) to confirm
+end-to-end against the real endpoints.