5.2 KiB
5.2 KiB
Analysis — Codex App Server: Embeddable Agent Protocol & BYO Auth
Part of codex-app-server-byo-auth/index
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(withclientInfoidentifying your product) →initializednotification → then any method. Requests before initialization getNot 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(orresume/fork),turn/start, then read streamed notifications (item/*,turn/completed), optionallyturn/steermid-flight,turn/interruptto cancel. - Capabilities opt-in:
experimentalApi: trueunlocks gated methods/fields (e.g.thread/backgroundTerminals/*,process/spawn).requestAttestationopt-in for desktop hosts. - Bindings:
codex app-server generate-ts/generate-json-schemaproduce per-version exact schemas — no drift between your types and the protocol.
Auth modes (the core of this research)
account/login/start accepts:
chatgpt(managed browser flow) — Codex owns OAuth, persists + auto-refreshes tokens.useHostedLoginSuccessPage,appBrandoptions.chatgptDeviceCode— same managed lifecycle, but the user approves via a device code on another device. Best for web — no account on your side needed.chatgptAuthTokens(experimental) — host app already owns the user's ChatGPT auth: supplyaccessToken,chatgptAccountId, optionalchatgptPlanType; app-server requests fresh tokens from you on 401. You own the refresh loop.apiKey— classic BYOK.- Bedrock (
amazonBedrock) — AWS credential chain or Codex-managed key.
account/updatednotification reports auth mode changes +planType;account/readreports account/plan details;account/rateLimits/read+account/usage/readlet 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;
chatgptAccountIdis 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-serverprocess 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-serverprocesses 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.namefeeds 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/readto 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/consumeexists but is user-side. - Compliance: identify your client; enterprise integrations should be on OpenAI's known-clients list.
- Not identity: can't use
chatgptAccountIdas your user key.