relmio 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -7,6 +7,30 @@ checks the registry separately after publication.
7
7
 
8
8
  ## Unreleased
9
9
 
10
+ ## [0.6.0] - 2026-08-15
11
+
12
+ ### Added
13
+
14
+ - Add an experimental loopback-only Codex Chat Adapter for trusted local
15
+ backends and development servers, with bearer authentication, multi-turn
16
+ conversation IDs, strict resource bounds, and a small Relmio-specific
17
+ `POST /chat` contract.
18
+
19
+ ### Changed
20
+
21
+ - Make Codex device sign-in target-aware so the experimental Relmio `/chat`
22
+ adapter and native App Server retain isolated, persistent ChatGPT credentials;
23
+ a Platform API key powers neither target and remains reserved for the generic
24
+ OpenAI-compatible `/v1` endpoint.
25
+
26
+ ### Security
27
+
28
+ - Reject browser-origin adapter requests, keep the adapter separate from
29
+ Platform-key-backed generic OpenAI-compatible `/v1` semantics, explicitly deny
30
+ model turns access to the private Codex credential store, run chat turns
31
+ read-only without network access, and preserve loopback-only publication plus
32
+ credential rotation.
33
+
10
34
  ## [0.5.0] - 2026-08-15
11
35
 
12
36
  ### Added
package/README.md CHANGED
@@ -47,8 +47,9 @@ Relmio is a local browser wizard with separate setup paths. Its existing
47
47
  VPS/n8n path installs a private
48
48
  [openai-oauth](https://github.com/EvanZhouDev/openai-oauth) Docker sidecar
49
49
  beside an existing self-hosted n8n instance. Its local Docker path can install
50
- either an OpenAI-compatible gateway backed by a Platform API key or the
51
- official Codex App Server backed by ChatGPT sign-in.
50
+ an OpenAI-compatible gateway backed by a Platform API key, the official Codex
51
+ App Server, or a small server-side Codex chat adapter backed by ChatGPT
52
+ sign-in.
52
53
 
53
54
  The existing n8n image, Compose file, container, and workflows stay untouched.
54
55
 
@@ -118,6 +119,14 @@ The existing VPS/n8n wizard remains available from native Windows.
118
119
  |---|---|---|---|
119
120
  | **OpenAI API: compatible clients** | `http://127.0.0.1:12435/v1` by default | Server-side OpenAI Platform API key only | Private local app, SDK, or same-owner development web app |
120
121
  | **Codex with ChatGPT: agent clients** | `ws://127.0.0.1:14500` by default | ChatGPT sign-in through Codex | Trusted native Codex/App Server client |
122
+ | **Codex Chat Adapter: development backends** | `http://127.0.0.1:14501/chat` by default | ChatGPT sign-in through Codex | Trusted local backend or development server |
123
+
124
+ The Chat Adapter starts each model turn with network access disabled and an
125
+ explicit filesystem policy that permits only Codex's minimal runtime files and
126
+ the empty private workspace. The model-accessible sandbox denies
127
+ `/home/node/.codex`, where the official Codex client keeps its ChatGPT session.
128
+ The adapter bearer must stay in your server-side development environment,
129
+ never browser code.
121
130
 
122
131
  The OpenAI-compatible `/v1` endpoint is powered only by a Platform API key,
123
132
  which the wizard seeds over stdin into a private, labeled Docker volume; it
@@ -137,18 +146,24 @@ and the capability must never be embedded in a public frontend bundle. Platform
137
146
  requests use that API project's billing, credits, limits, and permissions, not
138
147
  a ChatGPT subscription.
139
148
 
140
- ChatGPT sign-in powers only the official experimental Codex App Server JSON-RPC
141
- protocol. It does not expose `/v1`, and Relmio never translates a ChatGPT
142
- OAuth/session token into a general API credential. OpenAI documents the WebSocket transport as
143
- experimental and unsupported for production, and it rejects browser-origin
144
- connections. Use it only with a trusted native client owned by the same person.
145
- Its capability is high-trust because it can operate the signed-in
146
- Codex session and files inside the isolated container workspace.
147
-
148
- Both services bind exactly to `127.0.0.1`, require the generated capability,
149
- and mount no host directory or Docker socket. The Codex service gets private
150
- named credential and workspace volumes. This local path does not connect to a
151
- VPS or modify n8n.
149
+ ChatGPT sign-in powers Codex, not the OpenAI Platform API. The native target
150
+ keeps the official experimental App Server JSON-RPC protocol. The separate
151
+ adapter offers only Relmio's `POST /chat` request and returns a conversation ID
152
+ plus final text; it is not `/v1/chat/completions`, `/v1/responses`, or an
153
+ OpenAI SDK replacement. A local backend can keep its Relmio bearer secret while
154
+ a browser calls that backend. Direct browser-origin requests to both Codex
155
+ targets are rejected.
156
+
157
+ OpenAI documents the underlying App Server WebSocket transport as experimental
158
+ and unsupported for production. The raw App Server capability is especially
159
+ high-trust because it can operate the signed-in Codex session and files inside
160
+ the isolated container workspace. Keep either target loopback-only, same-owner,
161
+ and limited to local development.
162
+
163
+ All three services bind exactly to `127.0.0.1`, require the generated capability,
164
+ and mount no host directory or Docker socket. Each Codex target gets its own
165
+ private named credential and workspace volumes. This local path does not
166
+ connect to a VPS or modify n8n.
152
167
 
153
168
  Read the complete [Local Docker endpoints
154
169
  guide](https://github.com/Demonbane18/relmio/blob/main/docs/local-endpoints.md)
@@ -29,28 +29,37 @@ flowchart LR
29
29
  W --> D["Local Docker Engine"]
30
30
  D --> G["OpenAI-compatible gateway<br>127.0.0.1:12435/v1"]
31
31
  D --> A["Codex App Server<br>127.0.0.1:14500"]
32
+ D --> H["Codex Chat Adapter<br>127.0.0.1:14501/chat"]
32
33
  G -->|"Platform API key"| P["OpenAI Platform API"]
33
34
  A -->|"Official Codex sign-in"| C["ChatGPT/Codex service"]
35
+ H -->|"Official App Server lifecycle"| C
34
36
  ```
35
37
 
36
- The two services are intentionally not interchangeable:
38
+ The three services are intentionally not interchangeable:
37
39
 
38
40
  | Target | Wire protocol | Upstream credential |
39
41
  |---|---|---|
40
42
  | `openai-api` | OpenAI-compatible HTTP `/v1` | OpenAI Platform API key |
41
43
  | `codex-chatgpt` | Official Codex App Server JSON-RPC | ChatGPT sign-in managed by Codex |
44
+ | `codex-chat` | Relmio-specific HTTP `POST /chat` | ChatGPT sign-in managed by Codex |
42
45
 
43
46
  Relmio never adapts a ChatGPT/Codex credential into the local `/v1` gateway.
44
47
  The OpenAI gateway replaces the caller's Relmio capability with the
45
- protected Platform key only at the upstream boundary. The Codex service keeps
46
- the native initialization, thread, turn, approval, and event protocol.
47
-
48
- Both projects publish exactly one literal `127.0.0.1` binding and require a
48
+ protected Platform key only at the upstream boundary. The native Codex service
49
+ keeps the initialization, thread, turn, approval, and event protocol. The
50
+ adapter invokes that same official lifecycle behind a bounded, read-only
51
+ conversational contract without claiming OpenAI API compatibility. Its model
52
+ sandbox denies network access and uses a root-deny filesystem policy with only
53
+ minimal runtime paths plus `/workspace` readable; `/home/node/.codex` is
54
+ explicitly denied so a model turn cannot read the persisted ChatGPT session.
55
+
56
+ Each project publishes exactly one literal `127.0.0.1` binding and requires a
49
57
  generated bearer capability. Their managed roots are
50
- `~/.relmio/local/openai-api` and `~/.relmio/local/codex-chatgpt`. The Codex
51
- credential and workspace use private named Docker volumes; no host directory
52
- or Docker socket is mounted. See [Local Docker endpoints](local-endpoints.md)
53
- for setup and trust limitations.
58
+ `~/.relmio/local/openai-api`, `~/.relmio/local/codex-chatgpt`, and
59
+ `~/.relmio/local/codex-chat`. The Codex credentials and workspaces use
60
+ target-specific private named Docker volumes; no host directory or Docker
61
+ socket is mounted. See [Local Docker endpoints](local-endpoints.md) for setup
62
+ and trust limitations.
54
63
 
55
64
  Before installation, Relmio resolves the selected Docker context to a local
56
65
  Unix socket and pins that exact socket on every later Docker command. Remote
@@ -182,3 +191,6 @@ sidecar authenticates upstream with the mounted OAuth file.
182
191
  or mismatched managed identity blocks local mutation.
183
192
  - A Codex login failure returns a sanitized status without returning App
184
193
  Server output or ChatGPT tokens.
194
+ - A chat adapter request with a browser Origin, invalid bearer, malformed body,
195
+ protocol overflow, timeout, or failed turn is rejected with a sanitized
196
+ response and its App Server helper is terminated.
@@ -2,7 +2,8 @@
2
2
 
3
3
  ## Status
4
4
 
5
- Approved for implementation on `codex/local-openai-endpoint` on 2026-08-13.
5
+ Originally approved on 2026-08-13 and extended for the additive
6
+ `codex/local-codex-chat-adapter` target on 2026-08-15.
6
7
 
7
8
  This spec is product and engineering guidance based on the current official
8
9
  OpenAI documentation. It is not a legal opinion. Relmio must not claim that
@@ -13,16 +14,19 @@ OpenAI has endorsed, certified, or pre-approved the project.
13
14
  Add a local Docker installation path to the Relmio browser wizard without
14
15
  weakening the existing VPS/n8n safety boundary.
15
16
 
16
- Relmio offers two intentionally different local providers:
17
+ Relmio offers three intentionally different local client contracts:
17
18
 
18
19
  1. `openai-api` is an OpenAI-compatible HTTP gateway backed by the user's
19
20
  OpenAI Platform API key.
20
21
  2. `codex-chatgpt` is the official Codex App Server protocol backed by the
21
22
  user's ChatGPT/Codex sign-in.
23
+ 3. `codex-chat` is a small Relmio-specific HTTP chat adapter backed by the
24
+ same official App Server lifecycle and ChatGPT/Codex sign-in.
22
25
 
23
26
  Relmio must never exchange, translate, or present a ChatGPT/Codex credential as
24
- a general OpenAI API bearer credential. The Codex provider must not expose an
25
- OpenAI-shaped `/v1` compatibility surface.
27
+ a general OpenAI API bearer credential. Neither Codex target may expose an
28
+ OpenAI-shaped `/v1` compatibility surface. The adapter owns only its narrow
29
+ `POST /chat` contract.
26
30
 
27
31
  ## Official-source boundary
28
32
 
@@ -53,7 +57,7 @@ The existing VPS/n8n wizard remains a separate legacy setup path. The wizard
53
57
  landing experience adds a prominent **Local endpoints** option which opens a
54
58
  dedicated local installer.
55
59
 
56
- The local installer starts with two provider cards:
60
+ The local installer starts with three provider cards:
57
61
 
58
62
  ### OpenAI API
59
63
 
@@ -81,7 +85,21 @@ The local installer starts with two provider cards:
81
85
  - An explicit statement that this is Codex JSON-RPC, not OpenAI `/v1`
82
86
  - An explicit experimental/non-production notice
83
87
 
84
- Both flows show a review screen and require a final confirmation before any
88
+ ### Codex Chat Adapter
89
+
90
+ - Label: **Codex Chat Adapter — development backends**
91
+ - Default HTTP port: `14501`
92
+ - Uses the same pinned official Codex CLI and official device-code sign-in.
93
+ - Result:
94
+ - Endpoint: `http://127.0.0.1:<port>`
95
+ - A newly generated Relmio bearer token, displayed once
96
+ - A device-code sign-in action
97
+ - An explicit server-side-only statement
98
+ - An explicit statement that `POST /chat` is Relmio-specific, not OpenAI
99
+ `/v1`
100
+ - An explicit experimental/non-production notice
101
+
102
+ All three flows show a review screen and require a final confirmation before any
85
103
  filesystem or Docker write.
86
104
 
87
105
  This release supports macOS, Linux, and Linux under WSL2. Native Windows is
@@ -143,7 +161,9 @@ is released in a `finally` path after both success and failure.
143
161
  ### `POST /api/local/codex/login`
144
162
 
145
163
  Starts an official Codex App Server device-code login through a one-shot stdio
146
- App Server process attached to the same persistent Codex home volume.
164
+ App Server process attached to the selected Codex target's persistent home
165
+ volume. The request identifies either `codex-chatgpt` or `codex-chat`;
166
+ every other target is rejected before process construction.
147
167
 
148
168
  Every login attempt resolves the managed Codex directory and attests its
149
169
  schema-2 marker and matching Docker resources, even in a fresh wizard process.
@@ -249,12 +269,77 @@ The host mapping is exactly `127.0.0.1:<selected-port>:4500`.
249
269
  The capability is therefore password-equivalent and limited to a trusted,
250
270
  same-owner native client.
251
271
 
272
+ ## Codex Chat Adapter contract
273
+
274
+ The adapter container starts a dependency-free Node HTTP service and launches
275
+ the pinned official `codex app-server --strict-config --stdio` process only
276
+ for a bounded chat operation. It uses the target's private Codex home and
277
+ workspace volumes and never exposes the App Server transport on the host.
278
+
279
+ ### Listener and authentication
280
+
281
+ - Container listener: `0.0.0.0:14501`
282
+ - Host publication: `127.0.0.1:<selected-port>:14501`
283
+ - `GET /health` is the only unauthenticated, non-forwarding route.
284
+ - Every route except `GET /health` requires exactly one
285
+ `Authorization: Bearer <Relmio capability>` header.
286
+ - Only the SHA-256 verifier is persisted and comparison is constant-time.
287
+ - Requests with an `Origin` header are rejected and no CORS permission is
288
+ emitted.
289
+
290
+ ### Request and response
291
+
292
+ The accepted JSON object contains only:
293
+
294
+ ```json
295
+ {
296
+ "input": "Required nonempty conversational input",
297
+ "conversationId": "Optional App Server thread ID"
298
+ }
299
+ ```
300
+
301
+ The successful response contains only:
302
+
303
+ ```json
304
+ {
305
+ "conversationId": "The started or resumed thread ID",
306
+ "output": "The authoritative final agent message"
307
+ }
308
+ ```
309
+
310
+ The adapter performs `initialize`, `initialized`, `thread/start` or
311
+ `thread/resume`, and `turn/start`. The turn is constrained to the empty
312
+ private workspace with a read-only sandbox. Its filesystem policy denies root
313
+ by default, permits only Codex's minimal runtime paths and `/workspace`, and
314
+ explicitly denies `/home/node/.codex`; turn network access is disabled. The
315
+ instruction not to inspect or modify files, run commands, call tools, or access
316
+ external resources remains defense in depth, not the credential boundary.
317
+ `item/completed` agent-message text is authoritative; bounded deltas are kept
318
+ separate by `itemId`, with only the most recent item's text used as a
319
+ compatibility fallback. Success requires `turn/completed` with
320
+ `status: completed`.
321
+
322
+ ### Resource and failure bounds
323
+
324
+ - Header, body, input, conversation ID, stdout, stderr, line, and output sizes
325
+ are bounded.
326
+ - Concurrent chats, turn duration, child-process termination grace, and the
327
+ final wait for an unreaped process are bounded. The concurrency slot remains
328
+ occupied until the helper closes or that final bound expires.
329
+ - Client disconnect, timeout, malformed protocol, overflow, and failed turns
330
+ terminate the helper.
331
+ - HTTP errors are generic and never include App Server output, process errors,
332
+ ChatGPT credentials, or stderr.
333
+ - Installation and credential rotation verify readiness/authentication without
334
+ starting a model turn or requiring sign-in before the device-code step.
335
+
252
336
  ## Local filesystem and process boundary
253
337
 
254
338
  Managed roots:
255
339
 
256
340
  - `~/.relmio/local/openai-api`
257
341
  - `~/.relmio/local/codex-chatgpt`
342
+ - `~/.relmio/local/codex-chat`
258
343
 
259
344
  `RELMIO_HOME` may replace `~/.relmio` for testing or advanced use, but it must
260
345
  be an absolute path whose final component is `.relmio`.
@@ -282,7 +367,7 @@ Controls:
282
367
 
283
368
  ## Container hardening
284
369
 
285
- Both long-running endpoint services:
370
+ All three long-running endpoint services:
286
371
 
287
372
  - run as a non-root user;
288
373
  - set `no-new-privileges`;
@@ -326,26 +411,29 @@ gateway; it is removed immediately after seeding.
326
411
  | LAN/public exposure | literal `127.0.0.1` Compose binding plus template and runtime inspection tests |
327
412
  | Local cross-site request | bearer capability, exact Origin allowlist, strict preflight, Host validation |
328
413
  | Upstream key disclosure | separate local/upstream credentials, stdin-seeded private named volume, redacted errors, no body logging |
329
- | ChatGPT token repurposing | official App Server only; no `/v1` adapter for Codex |
414
+ | ChatGPT token repurposing | official App Server lifecycle only; the adapter is Relmio-specific and exposes no `/v1` route |
330
415
  | Command injection | validated scalar values, spawn argument arrays, no shell |
331
416
  | Managed-path takeover | refuse unmanaged roots and every symlinked component |
332
417
  | Streaming resource exhaustion | header/body/concurrency/time bounds and backpressure |
333
418
  | Docker privilege compromise | document Docker control as a privileged local boundary; mount no Docker socket into services |
334
419
  | Secret recovery from UI | show capabilities once; never use browser storage; rotate on reinstall |
335
- | Codex capability compromise | explicit credential-equivalent warning; trusted same-owner native clients only; private container volumes and no host mounts |
420
+ | Codex capability compromise | explicit trust warning; target-specific least-privilege interfaces, private container volumes, no host mounts, and server-side-only adapter use |
421
+ | Model-induced credential read | root-deny model filesystem profile, minimal runtime read allowlist, explicit `/home/node/.codex` deny, empty private workspace, and no turn network access |
336
422
 
337
423
  ## Acceptance criteria
338
424
 
339
- - The browser wizard visibly offers both local providers and the legacy VPS
425
+ - The browser wizard visibly offers all three local contracts and the legacy VPS
340
426
  path remains separate.
341
- - Platform keys are accepted only by `openai-api`; ChatGPT auth is accepted only
342
- by official App Server.
427
+ - Platform keys are accepted only by `openai-api`; both Codex targets use only
428
+ official App Server-backed ChatGPT authentication.
343
429
  - Generated Compose files publish only literal loopback bindings.
344
430
  - Every non-health gateway operation that can reach OpenAI and every App Server
345
431
  WebSocket handshake is capability-authenticated; exact-origin CORS preflight
346
432
  is a non-forwarding metadata exception.
347
433
  - Gateway unit/integration tests cover auth, origins, Host validation,
348
434
  streaming, cancellation, upstream errors, and secret redaction.
435
+ - Adapter tests cover auth, Origin rejection, request/protocol validation,
436
+ process cleanup, bounds, concurrency, final-output selection, and redaction.
349
437
  - Local installer tests prove confirmation, unmanaged-root refusal, symlink
350
438
  refusal, port collision behavior, exact Docker arguments, file modes, and
351
439
  absence of n8n commands.
@@ -1,18 +1,20 @@
1
1
  # Local Docker endpoints
2
2
 
3
3
  Relmio can install a provider endpoint in Docker on the same computer as your
4
- app. The local installer is deliberately split into two protocols with two
5
- different authentication methods:
4
+ app. The local installer keeps three explicit client contracts across two
5
+ different provider authentication methods:
6
6
 
7
7
  | Wizard option | Local interface | Upstream sign-in | Intended client |
8
8
  |---|---|---|---|
9
9
  | **OpenAI API: compatible clients** | OpenAI-compatible HTTP under `/v1` | Server-side OpenAI Platform API key only | A private local app, SDK, or same-owner development web app |
10
10
  | **Codex with ChatGPT: agent clients** | Official Codex App Server JSON-RPC over WebSocket | ChatGPT sign-in through Codex | A trusted native Codex/App Server client owned by the same person |
11
+ | **Codex Chat Adapter: development backends** | Relmio-specific HTTP `POST /chat` | ChatGPT sign-in through Codex | A trusted local backend or development server owned by the same person |
11
12
 
12
13
  Relmio does not exchange or translate a ChatGPT OAuth/session credential into
13
- an OpenAI-compatible `/v1` bearer credential. The Codex option keeps Codex's
14
- thread, turn, approval, and streamed-event semantics instead of pretending to
15
- be the OpenAI API.
14
+ an OpenAI-compatible `/v1` bearer credential. The native Codex option keeps
15
+ Codex's thread, turn, approval, and streamed-event semantics. The adapter
16
+ translates only a small Relmio-owned `/chat` contract into that official
17
+ protocol; it does not imitate the OpenAI API.
16
18
 
17
19
  This is a documentation-backed engineering boundary, not legal advice or a
18
20
  guarantee that a particular account or use case is permitted. Review the
@@ -24,10 +26,11 @@ agreements and policies that apply to your account.
24
26
  this release depends on POSIX owner-only directory and file permissions for
25
27
  local credentials.
26
28
  - Docker Engine or Docker Desktop with Docker Compose v2 on the local computer
27
- - A free loopback port (`12435` by default for OpenAI API or `14500` for Codex)
29
+ - A free loopback port (`12435` for OpenAI API, `14500` for native Codex,
30
+ or `14501` for the Codex Chat Adapter by default)
28
31
  - One of these provider credentials:
29
32
  - an OpenAI Platform API key for the OpenAI-compatible endpoint; or
30
- - a ChatGPT account eligible for Codex for the App Server endpoint
33
+ - a ChatGPT account eligible for Codex for either Codex target
31
34
  - A trusted local app that can keep the Relmio capability secret
32
35
 
33
36
  The local path does not need a VPS or SSH access and does not modify the
@@ -45,8 +48,8 @@ project on the local computer.
45
48
 
46
49
  2. Open the one-time local wizard URL printed in the terminal and choose
47
50
  **Local endpoints**.
48
- 3. Choose **OpenAI API: compatible clients** or **Codex with ChatGPT: agent
49
- clients**.
51
+ 3. Choose **OpenAI API: compatible clients**, **Codex with ChatGPT: agent
52
+ clients**, or **Codex Chat Adapter: development backends**.
50
53
  4. Keep the default port or select another unused local port. For the OpenAI
51
54
  API option, add any browser origins that must be allowed and enter your
52
55
  Platform API key.
@@ -64,6 +67,7 @@ inside its managed path. Its local files live under:
64
67
  ```text
65
68
  ~/.relmio/local/openai-api
66
69
  ~/.relmio/local/codex-chatgpt
70
+ ~/.relmio/local/codex-chat
67
71
  ```
68
72
 
69
73
  Advanced or test environments can set `RELMIO_HOME` before starting the
@@ -81,8 +85,9 @@ To replace only the credential used by your local client, select **Rotate client
81
85
  credential** on the installed endpoint's Ready screen. Relmio first stages and
82
86
  shows the new one-time capability while the previous capability remains active.
83
87
  It then updates and validates the managed Compose configuration, recreates only
84
- the attested service, and verifies the new bearer against `/v1/models` or the
85
- authenticated Codex WebSocket handshake before reporting success.
88
+ the attested service, and verifies the new bearer against `/v1/models`, the
89
+ authenticated Codex WebSocket handshake, or the adapter's authenticated probe
90
+ before reporting success.
86
91
 
87
92
  This client-only rotation preserves the upstream Platform API key in its private
88
93
  named volume and preserves the Codex home and workspace volumes. If activation
@@ -97,8 +102,8 @@ managed update. Relmio verifies the marker and Docker resource ownership and
97
102
  reuses the installation's unique Compose identity. For `openai-api`, provide the
98
103
  current or replacement Platform API key during that full update; Relmio reseeds
99
104
  its private named volume independently from the local client capability. A full
100
- `codex-chatgpt` update retains the private Codex home and workspace volumes unless
101
- you explicitly delete them.
105
+ `codex-chatgpt` or `codex-chat` update retains the private Codex home and
106
+ workspace volumes unless you explicitly delete them.
102
107
 
103
108
  Do not hand-edit the marker, Compose file, credential volume, or verifier. If
104
109
  the marker or resource labels do not attest as one Relmio installation, the
@@ -205,9 +210,61 @@ workspace and credential volume. The service receives no host directory,
205
210
  Docker socket, SSH key, browser profile, or host home-directory mount. This
206
211
  reduces host exposure; it does not make an untrusted App Server client safe.
207
212
 
213
+ ## Codex Chat Adapter: development backends
214
+
215
+ The adapter result screen provides:
216
+
217
+ ```text
218
+ Endpoint: http://127.0.0.1:14501
219
+ Authorization: Bearer <the Relmio capability shown once by the wizard>
220
+ Protocol: Relmio Codex Chat HTTP
221
+ ```
222
+
223
+ After completing the same official Codex device-code sign-in, a local backend
224
+ can start a conversation with:
225
+
226
+ ```bash
227
+ export RELMIO_CODEX_CHAT_KEY="<capability shown once by the wizard>"
228
+ curl http://127.0.0.1:14501/chat \
229
+ -H "Authorization: Bearer $RELMIO_CODEX_CHAT_KEY" \
230
+ -H "Content-Type: application/json" \
231
+ --data '{"input":"Reply with a short hello."}'
232
+ ```
233
+
234
+ The response contains only the App Server thread ID and final conversational
235
+ text:
236
+
237
+ ```json
238
+ {
239
+ "conversationId": "thread-id-from-the-first-response",
240
+ "output": "Hello!"
241
+ }
242
+ ```
243
+
244
+ Send that `conversationId` with the next `input` to continue the same
245
+ conversation. The adapter initializes the official App Server, starts or
246
+ resumes the thread, runs a read-only conversational turn, and returns the
247
+ authoritative final agent message. The model sandbox has no network access and
248
+ uses a root-deny filesystem policy that reads only Codex's minimal runtime
249
+ paths and the empty private workspace. It explicitly denies
250
+ `/home/node/.codex`, the private volume containing the ChatGPT session.
251
+
252
+ This route is deliberately not `/v1/chat/completions` or `/v1/responses`.
253
+ OpenAI SDKs and tools that require those schemas still need the Platform-backed
254
+ OpenAI API target. The adapter rejects every request carrying an `Origin`
255
+ header and sends no CORS permission, so browser JavaScript must not call it
256
+ directly. Keep the bearer in a trusted local backend or development server and
257
+ let the browser call that server's own session-aware route.
258
+
259
+ The adapter is experimental because it depends on the experimental App Server
260
+ interface. It is loopback-only, single-owner development tooling, not a hosted,
261
+ LAN, multi-user, or production service. It enforces bounded request bodies,
262
+ output, concurrency, process lifetime, and sanitized failures, but those
263
+ controls do not create a general-purpose API entitlement.
264
+
208
265
  ## Network and container boundary
209
266
 
210
- Both local Compose projects publish exactly one host mapping:
267
+ Every local Compose project publishes exactly one host mapping:
211
268
 
212
269
  ```text
213
270
  127.0.0.1:<selected-port>:<container-port>
@@ -216,12 +273,13 @@ Both local Compose projects publish exactly one host mapping:
216
273
  They are not available through the computer's LAN address. Each long-running
217
274
  service runs as a non-root user, drops Linux capabilities, sets
218
275
  `no-new-privileges`, uses a read-only root filesystem, and has bounded
219
- temporary storage and resource limits. Neither service mounts the Docker
276
+ temporary storage and resource limits. None of the services mounts the Docker
220
277
  socket or a general host directory. The one-shot OpenAI seed helper has no
221
278
  network, port, or logs and retains only `CHOWN` while running as root long
222
279
  enough to atomically set ownership on the volume entry.
223
280
  The OpenAI gateway receives only its private API-key named volume, mounted
224
- read-only; Codex receives no host path and uses separate private named volumes.
281
+ read-only; both Codex targets receive no host path and use target-specific
282
+ private named volumes.
225
283
 
226
284
  The loopback binding and capability are complementary controls. Other
227
285
  processes running as the same local user may still be able to reach a loopback
@@ -244,7 +302,8 @@ literal values only after confirming all of these conditions:
244
302
  In every example, manually replace each angle-bracket placeholder with the
245
303
  already-validated literal. Do not use `eval`, source the JSON, or construct a
246
304
  Docker command from unvalidated marker text. The only valid service name is
247
- `gateway` for `openai-api` or `codex` for `codex-chatgpt`.
305
+ `gateway` for `openai-api`, `codex` for `codex-chatgpt`, or `codex-chat`
306
+ for `codex-chat`.
248
307
 
249
308
  ### Recover from a failed install
250
309
 
@@ -285,7 +344,7 @@ service:
285
344
  docker --host <dockerHost> compose \
286
345
  --project-name <projectName> \
287
346
  --file <absolute-managed-compose> \
288
- rm --stop --force <gateway-or-codex>
347
+ rm --stop --force <gateway-or-codex-or-codex-chat>
289
348
  ```
290
349
 
291
350
  This recovery command does not target other services, remove the project
@@ -344,7 +403,8 @@ docker --host <dockerHost> compose \
344
403
  `--volumes` irreversibly deletes the managed Codex home and workspace volumes,
345
404
  including the container's ChatGPT credentials. After Docker confirms the
346
405
  matching resources are gone, you may remove only the exact
347
- `~/.relmio/local/codex-chatgpt` managed directory through your file manager.
406
+ `~/.relmio/local/codex-chatgpt` or `~/.relmio/local/codex-chat` managed
407
+ directory for the target you verified through your file manager.
348
408
 
349
409
  ## Troubleshooting
350
410
 
@@ -358,8 +418,9 @@ matching resources are gone, you may remove only the exact
358
418
  - **Browser request rejected:** enter the exact page origin, including scheme
359
419
  and port, then update the managed endpoint. Wildcards are intentionally not
360
420
  supported.
361
- - **Browser cannot connect to Codex:** this is expected. App Server's raw
362
- WebSocket is for trusted native clients, not browser-origin connections.
421
+ - **Browser cannot connect to Codex:** this is expected. Both Codex targets
422
+ reject browser-origin requests. Use the raw App Server from a trusted native
423
+ client or keep the Chat Adapter bearer in a local backend.
363
424
  - **Codex reports signed out:** repeat the device-code sign-in in the local
364
425
  wizard. Never copy a Codex credential file between users.
365
426
  - **Native Windows:** this local Docker feature is unsupported. Run Relmio in a
@@ -373,6 +434,7 @@ credentials and Codex/ChatGPT authentication:
373
434
 
374
435
  - [OpenAI API authentication](https://developers.openai.com/api/reference/overview#authentication)
375
436
  - [Codex authentication](https://learn.chatgpt.com/docs/auth)
437
+ - [Codex permission profiles](https://learn.chatgpt.com/docs/permissions)
376
438
  - [Codex App Server protocol and WebSocket limitations](https://learn.chatgpt.com/docs/app-server)
377
439
  - [Codex for Open Source program terms](https://learn.chatgpt.com/docs/codex-for-oss-terms)
378
440