Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions docs-site/src/content/docs/guides/providers.md
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,46 @@ active account without logging the others out. Identity-less Kimi and Kiro crede
active slot, while `chatgpt` is always single-slot because Codex pool accounts have a separate ledger.
Tokens stay in `~/.opencodex/auth.json`; `/api/oauth/accounts` returns masked metadata only.

### OAuth reliability

opencodex coordinates token refresh and Codex pool routing so concurrent requests do not race the
credential store. This is reliability and diagnostics work — it does **not** guarantee protection
from provider enforcement, rate limits, or account actions.

**Refresh coordination.** Before a routed call, an expired access token is refreshed once per
`(provider, account)`:

1. In-process single-flight — concurrent callers share one refresh promise.
2. Per-account file lock — cross-process writers serialize on the same account.
3. Generation CAS — persist only when the stored credential generation still matches; a newer writer
wins, and an older refresh result cannot overwrite it.

Terminal refresh failures mark the account as needing reauthentication instead of retrying forever.

**Cooldowns (Codex pool).** Upstream `429` / quota responses set a hard cooldown from
`Retry-After`, quota `reset` headers (capped), or a short default backoff. Accounts on an explicit
`Retry-After` cooldown are not probed early; reset-derived cooldowns may receive a paced probe lease
so recovery can be detected without flooding the provider.

**Session affinity.** Codex thread→account affinity is process-local (in-memory only; not persisted
across proxy restarts). On credential failures (`401` / `403`) the account is quarantined for
reauth and affinities for that account are cleared. On `429`, the account enters cooldown, affinities
are cleared, and pool selection may rotate — threads are not pinned through a rate-limit response.

**Codex client metadata.** The ChatGPT forward path passes through the curated `FORWARD_HEADERS`
allowlist (authorization, `chatgpt-account-id`, originator, session/thread ids, and related Codex
headers — see [Adapters](/reference/adapters/)). Pool mode overwrites only auth and
`chatgpt-account-id` to match the selected credential. opencodex does **not** fabricate official
client identity (for example `originator`, session, or thread headers) when the caller did not send
them.

**Diagnostics and reauth.** Human `ocx status` prints an OAuth health block (redacted account ids,
no tokens). `ocx doctor` adds an OAuth reliability section with writable-store / single-flight checks
and WARN rows that include a recovery Action. When an OAuth provider account needs reauthentication, run
`ocx login <provider>` (or use Reauthenticate in the dashboard). Codex pool accounts are not an
`ocx login` provider — reauthenticate via the dashboard Codex account pool. See
[`ocx status` / `ocx doctor`](/reference/cli/) in the CLI reference.

### Kiro credential import

`ocx login kiro` searches the platform Kiro CLI stores and opens SQLite databases read-only. Two
Expand Down
11 changes: 8 additions & 3 deletions docs-site/src/content/docs/reference/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,14 @@ loopback; configured `corsAllowOrigins` entries extend the local-origin allowlis

OAuth implementations live in `oauth/`; access tokens are loaded or refreshed immediately before a
routed call, while `oauth/token-guardian.ts` can proactively refresh only providers whose policy
allows it. Codex/ChatGPT pool credentials and thread affinity live under `codex/` and are kept out of
management responses. Request usage is normalized to `OcxUsage`, surfaced in Responses terminal
events, and aggregated by `usage/` for the dashboard and optional JSONL diagnostics.
allows it. Refresh is coordinated with in-process single-flight, a per-account file lock, and
generation CAS so concurrent writers cannot clobber a newer credential. A shared health projection
(`oauth/health.ts`) feeds `ocx status`, `ocx doctor`, the management API, and the dashboard.
Codex/ChatGPT pool credentials and process-local thread affinity live under `codex/` and are kept out
of management responses; affinity clears on `401` / `403` / `429` (not pinned through rate limits)
and is not persisted across restarts. Request usage is normalized to `OcxUsage`, surfaced in
Responses terminal events, and aggregated by `usage/` for the dashboard and optional JSONL
diagnostics.

## Transport and compaction

Expand Down
18 changes: 18 additions & 0 deletions docs-site/src/content/docs/reference/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,16 @@ Idempotently ensure a background proxy is running, then sync its live model cata
Print a read-only diagnostic summary: proxy PID, `/healthz` reachability, dashboard URL,
config path, default provider, Codex autostart setting, service state, and shim state.

Human output also includes an **OAuth health** block after the OAuth logins summary: `OAuth health:
ok` when every known account is healthy, or `OAuth health: warning` with one redacted line per
non-healthy account (provider, masked account id, status such as reauthentication required / rate or
quota limited / refresh conflict) plus an optional `Action:` hint. Account ids are redacted; tokens
and emails are never printed. The `--json` contract does not currently include this health block.

Use `--json` for a machine-readable, read-only diagnostics contract:

```bash
ocx status
ocx status --json
```

Expand Down Expand Up @@ -327,8 +334,14 @@ credentials under `~/.opencodex/`; API-key login providers open their key dashbo
key, validate it when possible, and save the resulting provider config. The command prints the
currently accepted OAuth and API-key provider ids when the name is missing or unknown.

Use the same command to **reauthenticate** after `ocx status` / `ocx doctor` reports
reauthentication required or a terminal refresh failure (or use Reauthenticate in the dashboard).
Codex pool accounts are not a public `ocx login` provider — reauthenticate via the dashboard Codex
account pool (Reauthenticate) instead.

```bash
ocx login xai
ocx login anthropic
```

### `ocx logout <provider>`
Expand Down Expand Up @@ -404,6 +417,11 @@ Run read-only environment and connectivity diagnostics: state paths and filesyst
installs, proxy environment/config, ChatGPT reachability, Codex plugin and project-config warnings,
and pending history migration. It prints repair hints but does not apply them.

The **OAuth reliability** section reports whether credential storage is writable, whether refresh
single-flight / lock files can be created under `OPENCODEX_HOME`, non-healthy OAuth or Codex pool
accounts (redacted ids) with a recovery `Action:`, and a static OK that the Codex forward path does
not fabricate official-client metadata. Doctor never mutates credentials or applies repairs.

### `ocx debug [provider|usage …]`

Read or change runtime debug overrides through the running proxy's management API.
Expand Down
Loading
Loading