research/codex-app-server-byo-auth/analysis.md

63 lines
5.2 KiB
Markdown

# Analysis — Codex App Server: Embeddable Agent Protocol & BYO Auth
> Part of [[codex-app-server-byo-auth/index|Codex App Server — Embeddable Agent Protocol & BYO Auth]]
## Protocol deep-dive
### Transports and lifecycle
- Default transport is stdio (newline-delimited JSON). WebSocket and unix socket are alternatives; **WebSocket is explicitly experimental and unsupported for production workloads** (docs: "The app-server command and WebSocket transport are experimental and aren't supported for production workloads").
- Every connection: `initialize` (with `clientInfo` identifying your product) → `initialized` notification → then any method. Requests before initialization get `Not initialized`.
- Core primitives: **Thread** (a conversation), **Turn** (one user request + agent work), **Item** (units: user message, agent message, command run, file change, tool call).
- Lifecycle: `thread/start` (or `resume`/`fork`), `turn/start`, then read streamed notifications (`item/*`, `turn/completed`), optionally `turn/steer` mid-flight, `turn/interrupt` to cancel.
- Capabilities opt-in: `experimentalApi: true` unlocks gated methods/fields (e.g. `thread/backgroundTerminals/*`, `process/spawn`). `requestAttestation` opt-in for desktop hosts.
- Bindings: `codex app-server generate-ts` / `generate-json-schema` produce per-version exact schemas — no drift between your types and the protocol.
### Auth modes (the core of this research)
`account/login/start` accepts:
1. **`chatgpt`** (managed browser flow) — Codex owns OAuth, persists + auto-refreshes tokens. `useHostedLoginSuccessPage`, `appBrand` options.
2. **`chatgptDeviceCode`** — same managed lifecycle, but the user approves via a device code on another device. **Best for web** — no account on your side needed.
3. **`chatgptAuthTokens`** (experimental) — host app already owns the user's ChatGPT auth: supply `accessToken`, `chatgptAccountId`, optional `chatgptPlanType`; app-server requests fresh tokens from you on 401. You own the refresh loop.
4. **`apiKey`** — classic BYOK.
5. **Bedrock** (`amazonBedrock`) — AWS credential chain or Codex-managed key.
- `account/updated` notification reports auth mode changes + `planType`; `account/read` reports account/plan details; `account/rateLimits/read` + `account/usage/read` let your app surface the user's plan limits.
## The BYOK harness pattern
### "Sign in with ChatGPT" ≠ identity provider
- Google/GitHub sign-in → identity (email, profile). ChatGPT sign-in via app-server → model capability ("run Codex workloads billed to this user's ChatGPT plan"). No email/profile returned; `chatgptAccountId` is OpenAI-side only.
- Composable pattern: gmail/github = identity layer; ChatGPT = optional model-access layer.
### The no-sign-in + BYOK shape
Works for both local and hosted apps. The one design decision that matters: **where does the key live?**
| Shape | Key placement | Notes |
| --- | --- | --- |
| Local/desktop app | Client-side (localStorage/file), never leaves machine | Cleanest; BYOK-as-auth works perfectly, no server secrets |
| Hosted web, no sign-in | User's browser (localStorage, per-session) OR your DB | DB = you hold third-party secrets (security surface); browser = per-session, simpler |
| Hosted + device-code | Token stays in Codex's own credential store, not yours | Best "no-account" web option |
### Adapter pattern (maps to user's Effect Layer/DI)
One provider interface, multiple implementations:
- `ApiKeyProvider` (OpenRouter/OpenAI key)
- `ChatGptAuthProvider` (app-server device-code or external tokens)
The harness (agent loop, tools, UI) is provider-agnostic — same as the user's Service + Layer adapter composition pattern from the job-aggregator/law-retrieval projects.
## Architecture shapes
### A. Desktop-embedded (stable, recommended first)
- Each user runs their own `codex app-server` process locally (stdio or unix socket), app connects over the local transport.
- Key/auth stored client-side. No server secrets. WebSocket not needed.
- Best fit: local tools, CLI-adjacent products, developer apps.
### B. Hosted multi-tenant (more work, experimental transport)
- Per-user `codex app-server` processes on your infra, bridged over wss (WebSocket is experimental/unsupported for prod — this is the main risk).
- Key placement decision is critical: your DB (security surface) vs user's browser vs Codex-managed device-code tokens.
- Compliance: `clientInfo.name` feeds OpenAI's Compliance Logs Platform; contact OpenAI to get on a known-clients list for enterprise use.
- Capacity: each user's ChatGPT plan rate limits apply (`account/rateLimits/read` to surface them).
## Risks / caveats
- **Gray-area posture**: Anthropic banned the Claude-equivalent BYO-subscription pattern; OpenAI currently tolerates this via the official protocol, but that posture can change.
- **Transport**: WebSocket experimental — hosted production means real engineering (per-user processes + bridge), not a drop-in.
- **Capacity**: user's plan bounds capacity; `account/rateLimitResetCredit/consume` exists but is user-side.
- **Compliance**: identify your client; enterprise integrations should be on OpenAI's known-clients list.
- **Not identity**: can't use `chatgptAccountId` as your user key.