relmio 0.3.0 → 0.4.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.
@@ -0,0 +1,374 @@
1
+ # Local Docker endpoints
2
+
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:
6
+
7
+ | Wizard option | Local interface | Upstream sign-in | Intended client |
8
+ |---|---|---|---|
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
+ | **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
+
12
+ 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.
16
+
17
+ This is a documentation-backed engineering boundary, not legal advice or a
18
+ guarantee that a particular account or use case is permitted. Review the
19
+ agreements and policies that apply to your account.
20
+
21
+ ## Requirements
22
+
23
+ - macOS, Linux, or Linux under WSL2. Native Windows is not supported because
24
+ this release depends on POSIX owner-only directory and file permissions for
25
+ local credentials.
26
+ - 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)
28
+ - One of these provider credentials:
29
+ - an OpenAI Platform API key for the OpenAI-compatible endpoint; or
30
+ - a ChatGPT account eligible for Codex for the App Server endpoint
31
+ - A trusted local app that can keep the Relmio capability secret
32
+
33
+ The local path does not need a VPS or SSH access and does not modify the
34
+ existing n8n deployment. It creates a separate Relmio-managed Docker Compose
35
+ project on the local computer.
36
+
37
+ ## Install with the browser wizard
38
+
39
+ 1. Start Relmio on the computer that will run the endpoint. Use one of the
40
+ commands in the [README](../README.md#quick-install), or run:
41
+
42
+ ```bash
43
+ npx --yes --ignore-scripts relmio@latest
44
+ ```
45
+
46
+ 2. Open the one-time local wizard URL printed in the terminal and choose
47
+ **Local endpoints**.
48
+ 3. Choose **OpenAI API: compatible clients** or **Codex with ChatGPT: agent
49
+ clients**.
50
+ 4. Keep the default port or select another unused local port. For the OpenAI
51
+ API option, add any browser origins that must be allowed and enter your
52
+ Platform API key.
53
+ 5. Review the exact bind address, managed path, protocol, and limitations.
54
+ Confirm the plan before Relmio writes files or starts Docker.
55
+ 6. Copy the generated local capability when the result screen displays it.
56
+ Relmio shows the raw capability once and persists only its SHA-256 verifier.
57
+ “Shown once” describes the wizard display; the bearer remains valid until
58
+ you update the endpoint to rotate it.
59
+ 7. If you selected Codex, complete the device-code sign-in shown by the wizard.
60
+
61
+ Relmio refuses to overwrite an existing unmanaged directory or use a symlink
62
+ inside its managed path. Its local files live under:
63
+
64
+ ```text
65
+ ~/.relmio/local/openai-api
66
+ ~/.relmio/local/codex-chatgpt
67
+ ```
68
+
69
+ Advanced or test environments can set `RELMIO_HOME` before starting the
70
+ wizard to an absolute managed base whose final component is `.relmio`.
71
+
72
+ Each target directory contains `.managed-by-relmio.json`. Its schema-2 marker
73
+ records the target, port, Docker socket URI, installation ID, and unique Compose
74
+ project name; it contains no credential. Relmio uses that identity to distinguish
75
+ its resources from another checkout or user's resources on the same Docker
76
+ Engine.
77
+
78
+ ## Safe updates and credential rotation
79
+
80
+ Rerun the browser wizard, select the same target and port, and review the plan
81
+ again. Relmio verifies the existing marker and Docker resource ownership,
82
+ reuses that installation's unique Compose identity, replaces only that managed
83
+ service, and generates a new local client capability. Copy the new capability
84
+ from the one-time result and update the client; the previous capability no
85
+ longer authenticates.
86
+
87
+ For `openai-api`, every update requires the current Platform API key again. To
88
+ rotate both credentials, supply the replacement Platform key during the update;
89
+ Relmio atomically reseeds its private named volume and independently rotates the
90
+ local client capability. For `codex-chatgpt`, an update retains the private
91
+ Codex home and workspace volumes unless you explicitly delete them, but still
92
+ rotates the local capability.
93
+
94
+ Do not hand-edit the marker, Compose file, credential volume, or verifier. If
95
+ the marker or resource labels do not attest as one Relmio installation, the
96
+ wizard stops without overwriting them.
97
+
98
+ ## OpenAI API: compatible clients
99
+
100
+ The result screen provides:
101
+
102
+ ```text
103
+ Base URL: http://127.0.0.1:12435/v1
104
+ API key field: <the Relmio local capability shown once by the wizard>
105
+ ```
106
+
107
+ Use the Relmio capability shown once by the wizard, not the upstream Platform
108
+ key, in your local
109
+ client's API-key field. The gateway authenticates the local request with that
110
+ capability, replaces its authorization header with the protected Platform key,
111
+ and forwards only `GET /v1/models`, `POST /v1/responses`, and
112
+ `POST /v1/chat/completions` to `https://api.openai.com`.
113
+
114
+ For a quick private test:
115
+
116
+ ```bash
117
+ export RELMIO_LOCAL_KEY="<capability shown once by the wizard>"
118
+ curl http://127.0.0.1:12435/v1/models \
119
+ -H "Authorization: Bearer $RELMIO_LOCAL_KEY"
120
+ ```
121
+
122
+ The upstream key is passed only over stdin to a transient, network-disabled
123
+ seed helper, which atomically writes it into a private, labeled Docker volume.
124
+ The gateway mounts that volume read-only. Relmio does not create a host key
125
+ file, put the key in the generated Compose environment, return it from the
126
+ wizard, forward it from the client, or use it for the Codex option. OpenAI's
127
+ API documentation says API credentials are secrets and should not be exposed
128
+ in client-side code. Treat the local capability the same way.
129
+
130
+ ### Browser origins
131
+
132
+ Native clients and local backends normally send no `Origin` header and can use
133
+ the endpoint after bearer authentication. A browser request is allowed only
134
+ when its exact `http` or `https` origin was entered during setup. For example,
135
+ `http://localhost:3000` and `http://127.0.0.1:3000` are different origins.
136
+
137
+ Relmio does not accept wildcard origins, `null`, credentials, paths, queries,
138
+ or fragments. An allowed origin is a cross-origin request control, not a
139
+ secret-storage system: JavaScript, browser extensions, or anyone who can read
140
+ the page can still recover a bearer value embedded in a frontend bundle. Use
141
+ browser access only for a private, same-owner local development app. Prefer a
142
+ native client or a local backend when the capability must remain confidential.
143
+
144
+ ### Billing and credits
145
+
146
+ Requests use the OpenAI Platform project associated with the supplied API key
147
+ and are billed or credited there under the Platform account's current terms,
148
+ limits, and pricing. A ChatGPT subscription or Codex for Open Source benefit
149
+ is not substituted for Platform API billing on this route. OpenAI documents
150
+ API-key use as usage-based access and ChatGPT sign-in as subscription access in
151
+ its [Codex authentication guide](https://learn.chatgpt.com/docs/auth).
152
+
153
+ ## Codex with ChatGPT: agent clients
154
+
155
+ The result screen provides:
156
+
157
+ ```text
158
+ Endpoint: ws://127.0.0.1:14500
159
+ Authorization: Bearer <the Relmio capability shown once by the wizard>
160
+ Protocol: Codex App Server JSON-RPC
161
+ ```
162
+
163
+ After installation, select the wizard's ChatGPT sign-in action, open the
164
+ official verification URL, enter the device code, and complete authentication.
165
+ Relmio starts the login through the official Codex App Server account method;
166
+ it never returns the resulting ChatGPT access or refresh tokens.
167
+
168
+ A compatible Codex CLI can connect like this:
169
+
170
+ ```bash
171
+ export CODEX_REMOTE_TOKEN="<capability shown once by the wizard>"
172
+ codex --remote ws://127.0.0.1:14500 \
173
+ --remote-auth-token-env CODEX_REMOTE_TOKEN
174
+ ```
175
+
176
+ This is not an OpenAI `/v1` endpoint. A client must implement the official
177
+ App Server initialization and JSON-RPC protocol, including its thread, turn,
178
+ approval, and event messages.
179
+
180
+ ### Experimental and high-trust boundary
181
+
182
+ OpenAI documents the App Server command and WebSocket transport as experimental
183
+ and unsupported for production workloads. The raw server rejects requests that
184
+ carry a browser `Origin` header, so it is not a direct browser/web-app endpoint.
185
+ Use it only with a trusted native client controlled by the same account owner.
186
+
187
+ Possession of the Relmio capability can grant access to App Server's broad
188
+ agent and account surface inside the container, including the signed-in Codex
189
+ session and files in its private workspace; a capable client may be able to
190
+ recover the container's ChatGPT session credential. Treat the capability like
191
+ the ChatGPT credential itself. Do not give it to another user, bundle it in an
192
+ app, or expose the WebSocket on a LAN, domain, reverse proxy, or public IP.
193
+
194
+ Relmio limits the effect of that access by giving Codex a private named Docker
195
+ workspace and credential volume. The service receives no host directory,
196
+ Docker socket, SSH key, browser profile, or host home-directory mount. This
197
+ reduces host exposure; it does not make an untrusted App Server client safe.
198
+
199
+ ## Network and container boundary
200
+
201
+ Both local Compose projects publish exactly one host mapping:
202
+
203
+ ```text
204
+ 127.0.0.1:<selected-port>:<container-port>
205
+ ```
206
+
207
+ They are not available through the computer's LAN address. Each long-running
208
+ service runs as a non-root user, drops Linux capabilities, sets
209
+ `no-new-privileges`, uses a read-only root filesystem, and has bounded
210
+ temporary storage and resource limits. Neither service mounts the Docker
211
+ socket or a general host directory. The one-shot OpenAI seed helper has no
212
+ network, port, or logs and retains only `CHOWN` while running as root long
213
+ enough to atomically set ownership on the volume entry.
214
+ The OpenAI gateway receives only its private API-key named volume, mounted
215
+ read-only; Codex receives no host path and uses separate private named volumes.
216
+
217
+ The loopback binding and capability are complementary controls. Other
218
+ processes running as the same local user may still be able to reach a loopback
219
+ port, so protect the capability and keep the computer itself trusted.
220
+
221
+ ## Recovery and uninstall
222
+
223
+ The commands below are intentionally scoped to one persisted installation.
224
+ They are not safe until you verify ownership. First open, but do not execute or
225
+ shell-evaluate, the exact target's `.managed-by-relmio.json`. Manually copy its
226
+ literal values only after confirming all of these conditions:
227
+
228
+ - `schemaVersion` is `2` and `target` is the target you intend to operate on;
229
+ - `installId` is exactly 32 lowercase hexadecimal characters;
230
+ - `projectName` is exactly `relmio-<target>-<installId>`;
231
+ - `dockerHost` is a `unix:///absolute/socket/path` that you recognize; and
232
+ - the absolute Compose path is inside that same managed target directory, is
233
+ not a symlink, and names `docker-compose.yml`.
234
+
235
+ In every example, manually replace each angle-bracket placeholder with the
236
+ already-validated literal. Do not use `eval`, source the JSON, or construct a
237
+ Docker command from unvalidated marker text. The only valid service name is
238
+ `gateway` for `openai-api` or `codex` for `codex-chatgpt`.
239
+
240
+ ### Recover from a failed install
241
+
242
+ If Relmio reports that it could not confirm cleanup, keep the marker and
243
+ managed files in place. List only candidate containers, networks, and volumes
244
+ for the recorded installation:
245
+
246
+ ```bash
247
+ docker --host <dockerHost> ps -a \
248
+ --filter label=io.relmio.managed=true \
249
+ --filter label=io.relmio.target=<target> \
250
+ --filter label=io.relmio.install=<installId>
251
+ docker --host <dockerHost> network ls \
252
+ --filter label=io.relmio.managed=true \
253
+ --filter label=io.relmio.target=<target> \
254
+ --filter label=io.relmio.install=<installId>
255
+ docker --host <dockerHost> volume ls \
256
+ --filter label=io.relmio.managed=true \
257
+ --filter label=io.relmio.target=<target> \
258
+ --filter label=io.relmio.install=<installId>
259
+ ```
260
+
261
+ Inspect every listed object individually, using its literal name or ID rather
262
+ than a wildcard:
263
+
264
+ ```bash
265
+ docker --host <dockerHost> container inspect <literal-container-id>
266
+ docker --host <dockerHost> network inspect <literal-network-id>
267
+ docker --host <dockerHost> volume inspect <literal-volume-name>
268
+ ```
269
+
270
+ Confirm all three labels—`io.relmio.managed=true`, the exact target, and the
271
+ exact installation ID—match the marker. If any label or identity differs,
272
+ stop. Only after they all match may you stop and remove the one managed
273
+ service:
274
+
275
+ ```bash
276
+ docker --host <dockerHost> compose \
277
+ --project-name <projectName> \
278
+ --file <absolute-managed-compose> \
279
+ rm --stop --force <gateway-or-codex>
280
+ ```
281
+
282
+ This recovery command does not target other services, remove the project
283
+ network, or delete volumes. After confirming the service is gone, rerun the
284
+ wizard and approve a fresh plan.
285
+
286
+ ### Uninstall Codex while retaining its data
287
+
288
+ After the same marker and label verification, stop the target and remove its
289
+ container and project network with:
290
+
291
+ ```bash
292
+ docker --host <dockerHost> compose \
293
+ --project-name <projectName> \
294
+ --file <absolute-managed-compose> \
295
+ down
296
+ ```
297
+
298
+ Do not add `--volumes`. The named Codex home and workspace volumes retain the
299
+ ChatGPT login and workspace. Keep the managed target directory and marker as
300
+ well; they preserve the ownership identity needed to safely reuse or later
301
+ delete those volumes. Never remove the parent `~/.relmio`, use a wildcard, or
302
+ remove the other target.
303
+
304
+ ### Permanently uninstall the OpenAI API endpoint
305
+
306
+ After repeating the OpenAI target's marker and label checks, delete its one
307
+ managed service, project network, and API-key volume with the exact
308
+ project-scoped command:
309
+
310
+ ```bash
311
+ docker --host <dockerHost> compose \
312
+ --project-name <projectName> \
313
+ --file <absolute-managed-compose> \
314
+ down --volumes
315
+ ```
316
+
317
+ For this target, `--volumes` irreversibly deletes the private volume containing
318
+ the Platform API key. After Docker confirms that every matching labeled
319
+ resource is gone, you may remove only the exact
320
+ `~/.relmio/local/openai-api` managed directory through your file manager.
321
+
322
+ ### Permanently delete Codex credentials and workspace
323
+
324
+ Back up anything intentionally retained from the private Codex workspace and
325
+ confirm you want to erase its ChatGPT login. Then repeat the marker and label
326
+ checks and run this exact project-scoped command:
327
+
328
+ ```bash
329
+ docker --host <dockerHost> compose \
330
+ --project-name <projectName> \
331
+ --file <absolute-managed-compose> \
332
+ down --volumes
333
+ ```
334
+
335
+ `--volumes` irreversibly deletes the managed Codex home and workspace volumes,
336
+ including the container's ChatGPT credentials. After Docker confirms the
337
+ matching resources are gone, you may remove only the exact
338
+ `~/.relmio/local/codex-chatgpt` managed directory through your file manager.
339
+
340
+ ## Troubleshooting
341
+
342
+ - **Docker unavailable:** start Docker Desktop or the Docker daemon and verify
343
+ `docker version` and `docker compose version` locally.
344
+ - **Port already in use:** choose another unprivileged port in the wizard and
345
+ review the updated endpoint before confirming.
346
+ - **`401` from `/v1`:** use the Relmio capability shown by the wizard in the
347
+ client's bearer/API-key field. Do not send the Platform key to the local
348
+ endpoint.
349
+ - **Browser request rejected:** enter the exact page origin, including scheme
350
+ and port, then update the managed endpoint. Wildcards are intentionally not
351
+ supported.
352
+ - **Browser cannot connect to Codex:** this is expected. App Server's raw
353
+ WebSocket is for trusted native clients, not browser-origin connections.
354
+ - **Codex reports signed out:** repeat the device-code sign-in in the local
355
+ wizard. Never copy a Codex credential file between users.
356
+ - **Native Windows:** this local Docker feature is unsupported. Run Relmio in a
357
+ POSIX environment such as WSL2, or use macOS/Linux; do not weaken credential
358
+ permissions to force an install.
359
+
360
+ ## Official sources and account terms
361
+
362
+ This design follows the currently documented distinction between Platform API
363
+ credentials and Codex/ChatGPT authentication:
364
+
365
+ - [OpenAI API authentication](https://developers.openai.com/api/reference/overview#authentication)
366
+ - [Codex authentication](https://learn.chatgpt.com/docs/auth)
367
+ - [Codex App Server protocol and WebSocket limitations](https://learn.chatgpt.com/docs/app-server)
368
+ - [Codex for Open Source program terms](https://learn.chatgpt.com/docs/codex-for-oss-terms)
369
+
370
+ Acceptance into Codex for Open Source can provide program benefits, but Relmio
371
+ does not interpret membership as permission to repurpose ChatGPT credentials
372
+ for general API calls, share an account, bypass safeguards, or alter the scope
373
+ of another OpenAI agreement. The local Codex option stays inside the official
374
+ Codex protocol; general `/v1` calls continue to require Platform credentials.