relmio 0.2.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 +190 -0
- package/LICENSE +21 -0
- package/README.md +122 -0
- package/SPEC.md +140 -0
- package/docs/architecture.md +127 -0
- package/docs/brand.md +43 -0
- package/docs/images/brand/relmio-concept-source.png +0 -0
- package/docs/images/brand/relmio-mark.svg +16 -0
- package/docs/images/setup/01-local-sign-in-ready.png +0 -0
- package/docs/images/setup/02-vps-identity-confirmed.png +0 -0
- package/docs/images/setup/03-n8n-detected.png +0 -0
- package/docs/images/setup/04-install-plan.png +0 -0
- package/docs/images/setup/05-bridge-ready.png +0 -0
- package/docs/maintenance.md +157 -0
- package/docs/manual-install.md +282 -0
- package/docs/n8n-configuration.md +199 -0
- package/docs/npm-publish.md +285 -0
- package/docs/roadmap.md +109 -0
- package/docs/security.md +105 -0
- package/docs/troubleshooting.md +193 -0
- package/docs/video-outline.md +152 -0
- package/package.json +45 -0
- package/scripts/build-npm-package.js +112 -0
- package/scripts/check-release-metadata.js +100 -0
- package/scripts/check-syntax.js +59 -0
- package/scripts/preview.js +69 -0
- package/src/cli.js +57 -0
- package/src/domain/safety.js +59 -0
- package/src/domain/templates.js +65 -0
- package/src/domain/validation.js +76 -0
- package/src/infrastructure/ssh.js +268 -0
- package/src/services/discovery.js +96 -0
- package/src/services/installer.js +239 -0
- package/src/services/oauth.js +351 -0
- package/src/ui/app.js +526 -0
- package/src/ui/index.html +440 -0
- package/src/ui/styles.css +645 -0
- package/src/ui/time.js +15 -0
- package/src/web/server.js +489 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,190 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
This project follows semantic versioning. Each completed release uses one
|
|
4
|
+
version across `package.json`, `package-lock.json`, this file, the Git tag,
|
|
5
|
+
and npm. Local checks validate the repository metadata; the publishing guide
|
|
6
|
+
checks the registry separately after publication.
|
|
7
|
+
|
|
8
|
+
## Unreleased
|
|
9
|
+
|
|
10
|
+
No unreleased changes.
|
|
11
|
+
|
|
12
|
+
## [0.2.0] - 2026-07-29
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- Add a provider-neutral product roadmap with a gated SuperGrok/xAI OAuth
|
|
17
|
+
feasibility track, entitlement checks, and explicit security boundaries.
|
|
18
|
+
- Add a trusted-publisher GitHub Actions workflow for short-lived npm
|
|
19
|
+
authentication after the first package publication.
|
|
20
|
+
|
|
21
|
+
### Changed
|
|
22
|
+
|
|
23
|
+
- Rename the public product and npm package to Relmio and `relmio` so the
|
|
24
|
+
project can grow beyond its initial n8n setup path.
|
|
25
|
+
- Replace the generic plus icon with an original two-lane relay mark and add a
|
|
26
|
+
small brand guide with reusable SVG and source concept assets.
|
|
27
|
+
- Publish a concise npm-specific README with absolute image and documentation
|
|
28
|
+
URLs while preserving the full GitHub README and its Mermaid diagrams.
|
|
29
|
+
- Build and inspect a deterministic npm tarball so the registry receives the
|
|
30
|
+
npm-specific README instead of the repository README.
|
|
31
|
+
- Keep the legacy `n8n-openai-oauth-setup` executable alias and every deployed
|
|
32
|
+
`n8n-openai-oauth` compatibility and safety identifier unchanged.
|
|
33
|
+
|
|
34
|
+
## [0.1.8] - 2026-07-29
|
|
35
|
+
|
|
36
|
+
### Changed
|
|
37
|
+
|
|
38
|
+
- Restore the complete manual sidecar installation path to the README for
|
|
39
|
+
wizard failures, debugging, and contributor reproduction.
|
|
40
|
+
- Add plain-English Mermaid diagrams that explain the private sidecar and help
|
|
41
|
+
readers choose between the browser wizard and manual setup.
|
|
42
|
+
- Keep the README and standalone manual Docker templates synchronized with
|
|
43
|
+
automated documentation checks.
|
|
44
|
+
|
|
45
|
+
## [0.1.7] - 2026-07-28
|
|
46
|
+
|
|
47
|
+
### Changed
|
|
48
|
+
|
|
49
|
+
- Add prominent workflow-backup reminders to the README, manual guide,
|
|
50
|
+
troubleshooting guide, and browser wizard before VPS access.
|
|
51
|
+
|
|
52
|
+
## [0.1.6] - 2026-07-28
|
|
53
|
+
|
|
54
|
+
### Added
|
|
55
|
+
|
|
56
|
+
- Add a public npm quick-start guide with five sanitized setup screenshots,
|
|
57
|
+
Mermaid architecture diagrams, and a YouTube walkthrough outline.
|
|
58
|
+
- Add individual Base URL/API-key copy controls and n8n recipes for OpenAI
|
|
59
|
+
Chat Model, AI Agent, Basic LLM Chain, and HTTP Request nodes.
|
|
60
|
+
- Add a release metadata validator that keeps the package, lockfile, changelog,
|
|
61
|
+
and release tag on one version.
|
|
62
|
+
- Add GitHub Actions checks with immutable action pins, no persisted checkout
|
|
63
|
+
credential, and the repository's pinned npm `10.9.8` runtime.
|
|
64
|
+
|
|
65
|
+
### Changed
|
|
66
|
+
|
|
67
|
+
- Expand troubleshooting for stale wizard sessions, npm versions, local OAuth
|
|
68
|
+
callbacks, SSH failures, Docker networks, real port mappings, and manual
|
|
69
|
+
sidecar collisions.
|
|
70
|
+
- Use the wizard-only `~/.n8n-openai-oauth/auth.json` path consistently in the
|
|
71
|
+
manual and maintenance guides.
|
|
72
|
+
- Replace pre-publication wording and add the local context file to the shared
|
|
73
|
+
ignore policy.
|
|
74
|
+
- Disable npm lifecycle scripts explicitly in every documented and nested
|
|
75
|
+
`npx` invocation.
|
|
76
|
+
- Add a prominent workflow-backup reminder before local setup and inside the
|
|
77
|
+
wizard because VPS access remains a real write boundary even with sidecar-only
|
|
78
|
+
commands.
|
|
79
|
+
- Separate OpenAI credential fields from OpenAI Chat Model settings and explain
|
|
80
|
+
the Responses API compatibility behavior for Chat Model node version 1.3.
|
|
81
|
+
- Polish the public README with a collapsible contents list, clickable project
|
|
82
|
+
links, experimental-use disclaimers, and a contributor guide.
|
|
83
|
+
- Document Graphify as an optional local maintainer map while keeping raw graph
|
|
84
|
+
exports out of Git and npm.
|
|
85
|
+
|
|
86
|
+
### Fixed
|
|
87
|
+
|
|
88
|
+
- Prevent sanitized preview mode from generating or opening a live OpenAI
|
|
89
|
+
authorization URL.
|
|
90
|
+
- Refuse to show the ready screen when the sidecar returns no usable model ID.
|
|
91
|
+
- Tag the exact commit that passed CI and was published instead of relying on
|
|
92
|
+
the shell's current `HEAD`.
|
|
93
|
+
- Make the sanitized preview follow the production OAuth service contract and
|
|
94
|
+
show the correct private n8n Base URL.
|
|
95
|
+
- Fall back to a temporary selected text field when a browser denies the
|
|
96
|
+
modern Clipboard API, so the final credential copy buttons still work.
|
|
97
|
+
- Always remove the fallback copy field and restore focus when legacy browser
|
|
98
|
+
clipboard access throws.
|
|
99
|
+
- Stop and remove only the named wizard-managed sidecar service when its final
|
|
100
|
+
safety check detects an unexpected host-port publication; report an explicit
|
|
101
|
+
manual cleanup path if that removal cannot be confirmed.
|
|
102
|
+
- Clean up the sidecar when publication inspection fails or returns malformed
|
|
103
|
+
metadata, rate-limit install attempts, close the VPS connection after every
|
|
104
|
+
install outcome, and show actionable browser recovery messages.
|
|
105
|
+
|
|
106
|
+
## [0.1.5] - 2026-07-28
|
|
107
|
+
|
|
108
|
+
### Fixed
|
|
109
|
+
|
|
110
|
+
- Detect a newly approved ChatGPT credential as soon as its complete file is
|
|
111
|
+
available instead of waiting for the OAuth helper process to close.
|
|
112
|
+
- Poll the local sign-in state more frequently during the first ten seconds
|
|
113
|
+
so the wizard responds quickly after browser approval.
|
|
114
|
+
- Show the local credential's update time and announce when a fresh sign-in
|
|
115
|
+
has been saved.
|
|
116
|
+
|
|
117
|
+
## [0.1.4] - 2026-07-28
|
|
118
|
+
|
|
119
|
+
### Fixed
|
|
120
|
+
|
|
121
|
+
- Run ChatGPT login against a new wizard-only credential file so the bridge
|
|
122
|
+
CLI never needs an interactive terminal to confirm replacement.
|
|
123
|
+
- Validate the completed credential before storing it at
|
|
124
|
+
`~/.n8n-openai-oauth/auth.json` with owner-only permissions.
|
|
125
|
+
- Stop reusing or overwriting the Codex app credential at
|
|
126
|
+
`~/.codex/auth.json`.
|
|
127
|
+
- Open the exact fresh authorization URL returned by the pinned bridge CLI
|
|
128
|
+
and report its completion separately, avoiding stale browser sign-in tabs.
|
|
129
|
+
- Verify Docker Compose publisher metadata so an internal-only `10531/tcp`
|
|
130
|
+
declaration is not mistaken for a published VPS host port.
|
|
131
|
+
- Explain that browser extensions which intercept the localhost OAuth callback
|
|
132
|
+
must be disabled temporarily during a fresh sign-in.
|
|
133
|
+
|
|
134
|
+
## [0.1.3] - 2026-07-27
|
|
135
|
+
|
|
136
|
+
### Fixed
|
|
137
|
+
|
|
138
|
+
- Let the explicit **Refresh ChatGPT sign-in** action confirm replacement of
|
|
139
|
+
an existing local OAuth credential. Previously, the bridge CLI prompt had
|
|
140
|
+
no input stream, defaulted to “No,” and the wizard reported that sign-in did
|
|
141
|
+
not finish.
|
|
142
|
+
- Clarify when the wizard will reuse an existing credential and when to
|
|
143
|
+
refresh it.
|
|
144
|
+
|
|
145
|
+
## [0.1.2] - 2026-07-27
|
|
146
|
+
|
|
147
|
+
### Fixed
|
|
148
|
+
|
|
149
|
+
- Provide a writable `/home/node/.local` tmpfs so the non-root bridge can
|
|
150
|
+
start while the container root filesystem remains read-only.
|
|
151
|
+
- Use the collision-resistant Docker hostname `n8n-openai-oauth` so an
|
|
152
|
+
existing manual `openai-oauth` sidecar cannot capture n8n requests.
|
|
153
|
+
- Treat a wizard-managed deployment as an update, allowing a fresh local
|
|
154
|
+
ChatGPT sign-in to refresh its OAuth credential safely.
|
|
155
|
+
|
|
156
|
+
## [0.1.1] - 2026-07-27
|
|
157
|
+
|
|
158
|
+
### Fixed
|
|
159
|
+
|
|
160
|
+
- Quote the generated Compose healthcheck command so Docker Compose validates
|
|
161
|
+
it as a string.
|
|
162
|
+
|
|
163
|
+
## [0.1.0] - 2026-07-27
|
|
164
|
+
|
|
165
|
+
### Added
|
|
166
|
+
|
|
167
|
+
- Local browser wizard for installing the OpenAI OAuth sidecar beside a
|
|
168
|
+
self-hosted n8n Docker deployment.
|
|
169
|
+
- Read-only n8n and Docker-network discovery.
|
|
170
|
+
- Explicit review and confirmation before remote sidecar writes.
|
|
171
|
+
- Safety checks that prevent changes to the existing n8n Compose project,
|
|
172
|
+
image, container, or host port mappings.
|
|
173
|
+
- `npx`-friendly CLI entry point and beginner documentation.
|
|
174
|
+
|
|
175
|
+
### Security
|
|
176
|
+
|
|
177
|
+
- OAuth credentials stay on the local computer until the user approves an
|
|
178
|
+
SFTP upload to the installer-managed sidecar directory.
|
|
179
|
+
- SSH host-key confirmation is required before password authentication.
|
|
180
|
+
- The sidecar uses an internal-only Docker network endpoint and no published
|
|
181
|
+
VPS port.
|
|
182
|
+
|
|
183
|
+
[0.1.7]: https://github.com/Demonbane18/n8n-openai-oauth-setup/compare/v0.1.6...v0.1.7
|
|
184
|
+
[0.1.6]: https://github.com/Demonbane18/n8n-openai-oauth-setup/compare/v0.1.5...v0.1.6
|
|
185
|
+
[0.1.5]: https://github.com/Demonbane18/n8n-openai-oauth-setup/compare/v0.1.4...v0.1.5
|
|
186
|
+
[0.1.4]: https://github.com/Demonbane18/n8n-openai-oauth-setup/compare/v0.1.3...v0.1.4
|
|
187
|
+
[0.1.3]: https://github.com/Demonbane18/n8n-openai-oauth-setup/compare/v0.1.2...v0.1.3
|
|
188
|
+
[0.1.2]: https://github.com/Demonbane18/n8n-openai-oauth-setup/compare/v0.1.1...v0.1.2
|
|
189
|
+
[0.1.1]: https://github.com/Demonbane18/n8n-openai-oauth-setup/compare/v0.1.0...v0.1.1
|
|
190
|
+
[0.1.0]: https://github.com/Demonbane18/n8n-openai-oauth-setup/releases/tag/v0.1.0
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Demonbane18
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
<img src="https://raw.githubusercontent.com/Demonbane18/n8n-openai-oauth-setup/main/docs/images/brand/relmio-mark.svg" alt="Relmio logo" width="88">
|
|
3
|
+
<h1>Relmio</h1>
|
|
4
|
+
<p>Relay a supported ChatGPT/Codex sign-in to OpenAI-compatible clients, starting with self-hosted n8n.</p>
|
|
5
|
+
<p>
|
|
6
|
+
<a href="https://github.com/Demonbane18/n8n-openai-oauth-setup">Full guide</a>
|
|
7
|
+
·
|
|
8
|
+
<a href="https://github.com/Demonbane18/n8n-openai-oauth-setup/issues/new">Report an issue</a>
|
|
9
|
+
·
|
|
10
|
+
<a href="https://github.com/Demonbane18/n8n-openai-oauth-setup/blob/main/docs/roadmap.md">Roadmap</a>
|
|
11
|
+
</p>
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
Relmio is a local browser wizard that installs a private
|
|
15
|
+
[openai-oauth](https://github.com/EvanZhouDev/openai-oauth) Docker sidecar
|
|
16
|
+
beside an existing self-hosted n8n instance. It guides you through local
|
|
17
|
+
ChatGPT/Codex sign-in, SSH host verification, read-only n8n discovery, an
|
|
18
|
+
exact change plan, and the final n8n credential settings.
|
|
19
|
+
|
|
20
|
+
The existing n8n image, Compose file, container, and workflows stay untouched.
|
|
21
|
+
|
|
22
|
+
## Quick start
|
|
23
|
+
|
|
24
|
+
Run this on your own macOS, Windows, or Linux computer—not on the VPS:
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
npx --yes --ignore-scripts relmio@latest
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Requirements:
|
|
31
|
+
|
|
32
|
+
- Node.js 22 or newer
|
|
33
|
+
- A browser and an eligible ChatGPT/Codex account
|
|
34
|
+
- A self-hosted n8n Docker deployment on a VPS
|
|
35
|
+
- Docker Compose v2, SSH access, and a Docker network shared with n8n
|
|
36
|
+
|
|
37
|
+
Back up your n8n workflows before granting any tool VPS access.
|
|
38
|
+
|
|
39
|
+
## What you get
|
|
40
|
+
|
|
41
|
+
```text
|
|
42
|
+
n8n AI node or HTTP Request
|
|
43
|
+
-> private Docker endpoint: http://n8n-openai-oauth:10531/v1
|
|
44
|
+
-> protected ChatGPT/Codex OAuth session
|
|
45
|
+
-> upstream OpenAI service
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Relmio currently provides tested setup instructions for:
|
|
49
|
+
|
|
50
|
+
- OpenAI Chat Model
|
|
51
|
+
- AI Agent
|
|
52
|
+
- Basic LLM Chain
|
|
53
|
+
- HTTP Request
|
|
54
|
+
|
|
55
|
+
The broader direction is to support local chatbots, custom applications,
|
|
56
|
+
OpenAI-compatible clients, and provider adapters without tying the public
|
|
57
|
+
product name to n8n. SuperGrok/xAI OAuth is a gated feasibility item on the
|
|
58
|
+
[provider roadmap](https://github.com/Demonbane18/n8n-openai-oauth-setup/blob/main/docs/roadmap.md);
|
|
59
|
+
it is not currently advertised as supported.
|
|
60
|
+
|
|
61
|
+
## Visual walkthrough
|
|
62
|
+
|
|
63
|
+
All images below are sanitized previews with reserved addresses, fake server
|
|
64
|
+
data, and no real credential or session information.
|
|
65
|
+
|
|
66
|
+
### 1. Confirm the local ChatGPT/Codex sign-in
|
|
67
|
+
|
|
68
|
+
<img src="https://raw.githubusercontent.com/Demonbane18/n8n-openai-oauth-setup/main/docs/images/setup/01-local-sign-in-ready.png" alt="Sanitized local sign-in ready screen" width="720">
|
|
69
|
+
|
|
70
|
+
### 2. Verify the VPS identity
|
|
71
|
+
|
|
72
|
+
<img src="https://raw.githubusercontent.com/Demonbane18/n8n-openai-oauth-setup/main/docs/images/setup/02-vps-identity-confirmed.png" alt="Sanitized VPS fingerprint confirmation screen" width="720">
|
|
73
|
+
|
|
74
|
+
### 3. Choose the detected n8n container and network
|
|
75
|
+
|
|
76
|
+
<img src="https://raw.githubusercontent.com/Demonbane18/n8n-openai-oauth-setup/main/docs/images/setup/03-n8n-detected.png" alt="Sanitized n8n discovery screen" width="720">
|
|
77
|
+
|
|
78
|
+
### 4. Review the exact sidecar-only plan
|
|
79
|
+
|
|
80
|
+
<img src="https://raw.githubusercontent.com/Demonbane18/n8n-openai-oauth-setup/main/docs/images/setup/04-install-plan.png" alt="Sanitized installation plan screen" width="720">
|
|
81
|
+
|
|
82
|
+
### 5. Copy the verified n8n settings
|
|
83
|
+
|
|
84
|
+
<img src="https://raw.githubusercontent.com/Demonbane18/n8n-openai-oauth-setup/main/docs/images/setup/05-bridge-ready.png" alt="Sanitized verified bridge screen" width="720">
|
|
85
|
+
|
|
86
|
+
Use these values in an n8n OpenAI credential:
|
|
87
|
+
|
|
88
|
+
```text
|
|
89
|
+
API Key: local-only
|
|
90
|
+
Base URL: http://n8n-openai-oauth:10531/v1
|
|
91
|
+
Organization ID: leave empty
|
|
92
|
+
Add Custom Header: Off
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
The `local-only` value is a placeholder required by n8n. It is not an OpenAI
|
|
96
|
+
Platform API key.
|
|
97
|
+
|
|
98
|
+
## Important boundaries
|
|
99
|
+
|
|
100
|
+
- Relmio does not create an OpenAI Platform API key.
|
|
101
|
+
- The OAuth file is a password-equivalent secret; never commit or share it.
|
|
102
|
+
- The sidecar endpoint stays inside the Docker network. Port `10531` must not
|
|
103
|
+
be published on the VPS host.
|
|
104
|
+
- Relmio never edits, rebuilds, recreates, stops, or restarts the existing n8n
|
|
105
|
+
container.
|
|
106
|
+
- This is an unofficial community project, not affiliated with or endorsed by
|
|
107
|
+
OpenAI, xAI, or n8n. Provider access, models, limits, and policies can change.
|
|
108
|
+
- Use it only where your account, subscription, provider terms, and applicable
|
|
109
|
+
policies allow.
|
|
110
|
+
|
|
111
|
+
## Documentation
|
|
112
|
+
|
|
113
|
+
- [Complete GitHub README and manual fallback](https://github.com/Demonbane18/n8n-openai-oauth-setup#readme)
|
|
114
|
+
- [Configure n8n AI and HTTP nodes](https://github.com/Demonbane18/n8n-openai-oauth-setup/blob/main/docs/n8n-configuration.md)
|
|
115
|
+
- [Troubleshooting](https://github.com/Demonbane18/n8n-openai-oauth-setup/blob/main/docs/troubleshooting.md)
|
|
116
|
+
- [Security and limitations](https://github.com/Demonbane18/n8n-openai-oauth-setup/blob/main/docs/security.md)
|
|
117
|
+
- [Refresh, upgrade, rollback, and uninstall](https://github.com/Demonbane18/n8n-openai-oauth-setup/blob/main/docs/maintenance.md)
|
|
118
|
+
- [Changelog](https://github.com/Demonbane18/n8n-openai-oauth-setup/blob/main/CHANGELOG.md)
|
|
119
|
+
|
|
120
|
+
## License
|
|
121
|
+
|
|
122
|
+
[MIT](https://github.com/Demonbane18/n8n-openai-oauth-setup/blob/main/LICENSE)
|
package/SPEC.md
ADDED
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
# Spec: Relmio n8n Setup
|
|
2
|
+
|
|
3
|
+
## Objective
|
|
4
|
+
|
|
5
|
+
Build the first Relmio setup path: a beginner-friendly local wizard and a correct manual guide for connecting a self-hosted n8n Docker deployment to the unofficial `openai-oauth` bridge.
|
|
6
|
+
|
|
7
|
+
The primary user is a non-technical Hostinger VPS owner. Success means they can sign in locally, install a separate Docker sidecar, verify it, and configure n8n without editing, rebuilding, recreating, stopping, or restarting their existing n8n deployment.
|
|
8
|
+
|
|
9
|
+
The project is personal and experimental. It must explain that ChatGPT and OpenAI API billing are separate, that this bridge is unofficial, and that OAuth credentials must be protected like passwords.
|
|
10
|
+
|
|
11
|
+
## Tech stack
|
|
12
|
+
|
|
13
|
+
- Node.js `>=22`
|
|
14
|
+
- npm `10.9.8`
|
|
15
|
+
- ECMAScript modules
|
|
16
|
+
- Node built-in HTTP server, test runner, crypto, child process, and file APIs
|
|
17
|
+
- `ssh2` `1.17.0`
|
|
18
|
+
- `openai-oauth` `2.0.0` inside the generated sidecar image
|
|
19
|
+
- Docker Compose v2 on the target VPS
|
|
20
|
+
|
|
21
|
+
The first release is an `npx`-ready local browser wizard. A signed native desktop wrapper is intentionally deferred until the workflow is stable.
|
|
22
|
+
|
|
23
|
+
## Commands
|
|
24
|
+
|
|
25
|
+
- Install: `npm ci --ignore-scripts`
|
|
26
|
+
- Run wizard: `npm start`
|
|
27
|
+
- Run tests: `npm test`
|
|
28
|
+
- Check JavaScript syntax: `npm run lint`
|
|
29
|
+
- Audit dependencies: `npm audit --audit-level=high`
|
|
30
|
+
- Preview published files: `npm pack --dry-run`
|
|
31
|
+
|
|
32
|
+
## Project structure
|
|
33
|
+
|
|
34
|
+
```text
|
|
35
|
+
src/
|
|
36
|
+
cli.js Local entry point and browser launcher
|
|
37
|
+
domain/ Pure validation and deployment-plan logic
|
|
38
|
+
infrastructure/ SSH/SFTP and local process boundaries
|
|
39
|
+
services/ OAuth, discovery, installation orchestration
|
|
40
|
+
web/ Localhost HTTP server
|
|
41
|
+
ui/ Static browser wizard
|
|
42
|
+
test/ Node test-runner unit and integration tests
|
|
43
|
+
docs/ Manual guide, troubleshooting, security, architecture
|
|
44
|
+
tasks/ Implementation plan and task checklist
|
|
45
|
+
scripts/ Cross-platform project checks
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Code style
|
|
49
|
+
|
|
50
|
+
Use small named functions, explicit return objects, and dependency injection at side-effect boundaries:
|
|
51
|
+
|
|
52
|
+
```js
|
|
53
|
+
export function createDeploymentPlan({ networkName }) {
|
|
54
|
+
const safeNetwork = validateDockerName(networkName);
|
|
55
|
+
|
|
56
|
+
return {
|
|
57
|
+
projectName: "n8n-openai-oauth",
|
|
58
|
+
networkName: safeNetwork,
|
|
59
|
+
mutatesN8n: false,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
## Testing strategy
|
|
65
|
+
|
|
66
|
+
- Write failing unit tests first for validation, generated Docker files, and the forbidden-command safety boundary.
|
|
67
|
+
- Use fake SSH transports for discovery and installation orchestration.
|
|
68
|
+
- Use localhost-only integration tests for the HTTP server.
|
|
69
|
+
- Do not connect tests to the user's VPS or ChatGPT account.
|
|
70
|
+
- Treat a real Hostinger/n8n run as a separately confirmed manual acceptance test.
|
|
71
|
+
|
|
72
|
+
## Threat model
|
|
73
|
+
|
|
74
|
+
### Assets
|
|
75
|
+
|
|
76
|
+
- ChatGPT OAuth credential file
|
|
77
|
+
- VPS root password or SSH agent session
|
|
78
|
+
- SSH host identity
|
|
79
|
+
- Existing n8n deployment and workflows
|
|
80
|
+
|
|
81
|
+
### Trust boundaries
|
|
82
|
+
|
|
83
|
+
- Browser to localhost wizard server
|
|
84
|
+
- Wizard process to target SSH server
|
|
85
|
+
- Local auth file to SFTP upload
|
|
86
|
+
- n8n Docker network to sidecar
|
|
87
|
+
|
|
88
|
+
### Required controls
|
|
89
|
+
|
|
90
|
+
- Bind only to `127.0.0.1` and require an unguessable session token.
|
|
91
|
+
- Enforce same-origin requests and small request bodies.
|
|
92
|
+
- Hold SSH passwords only in request memory and never log them.
|
|
93
|
+
- Confirm the SSH host fingerprint before authentication.
|
|
94
|
+
- Validate Docker names and container names with allowlists.
|
|
95
|
+
- Upload files through SFTP; do not interpolate file contents into shell commands.
|
|
96
|
+
- Show a dry-run plan and require confirmation before remote writes.
|
|
97
|
+
- Generate a sidecar with no `ports`, no Traefik labels, dropped capabilities, and `no-new-privileges`.
|
|
98
|
+
|
|
99
|
+
## Boundaries
|
|
100
|
+
|
|
101
|
+
### Always
|
|
102
|
+
|
|
103
|
+
- Discover n8n through read-only Docker commands.
|
|
104
|
+
- Create a separate Compose project under `/docker/n8n-openai-oauth`.
|
|
105
|
+
- Attach only the sidecar to an existing n8n network.
|
|
106
|
+
- Run tests and secret scans before commits.
|
|
107
|
+
- Preserve a documented uninstall and rollback path.
|
|
108
|
+
|
|
109
|
+
### Ask first
|
|
110
|
+
|
|
111
|
+
- Overwriting an existing installer-managed directory.
|
|
112
|
+
- Selecting among multiple n8n containers or networks.
|
|
113
|
+
- Performing any remote write.
|
|
114
|
+
- Publishing the npm package or making the repository public.
|
|
115
|
+
|
|
116
|
+
### Never
|
|
117
|
+
|
|
118
|
+
- Edit the existing n8n Compose file.
|
|
119
|
+
- Build or modify the n8n image.
|
|
120
|
+
- Restart, stop, recreate, or remove n8n.
|
|
121
|
+
- Publish the bridge port on the VPS.
|
|
122
|
+
- Store or log passwords, tokens, or private keys.
|
|
123
|
+
- Share, pool, or redistribute ChatGPT credentials.
|
|
124
|
+
|
|
125
|
+
## Success criteria
|
|
126
|
+
|
|
127
|
+
- The wizard starts through one command and opens a local browser.
|
|
128
|
+
- It detects a local OAuth credential or starts a fresh local login.
|
|
129
|
+
- It confirms the SSH host key and connects using a password or SSH agent.
|
|
130
|
+
- It detects the running n8n container and its Docker networks using read-only commands.
|
|
131
|
+
- It displays an exact deployment plan before any write.
|
|
132
|
+
- It deploys only the separate sidecar and validates `/health` plus `/v1/models`.
|
|
133
|
+
- It shows `http://n8n-openai-oauth:10531/v1` and a placeholder API key for
|
|
134
|
+
n8n.
|
|
135
|
+
- Automated tests prove no generated install command can modify or restart n8n.
|
|
136
|
+
- Documentation covers the successful path, security limits, uninstall, and observed troubleshooting cases.
|
|
137
|
+
|
|
138
|
+
## Open questions
|
|
139
|
+
|
|
140
|
+
- npm publication is planned as the primary non-technical distribution path; native desktop packaging remains deferred.
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
# Architecture and n8n safety boundary
|
|
2
|
+
|
|
3
|
+
## Design
|
|
4
|
+
|
|
5
|
+
The wizard runs on the user's computer. It authenticates locally, opens one
|
|
6
|
+
verified SSH connection, performs read-only discovery, shows a plan, and then
|
|
7
|
+
creates a separate sidecar project on approval.
|
|
8
|
+
|
|
9
|
+
```mermaid
|
|
10
|
+
flowchart LR
|
|
11
|
+
B["Local browser<br>127.0.0.1"] --> W["Local Node wizard"]
|
|
12
|
+
W --> O["ChatGPT/Codex OAuth login<br>local callback"]
|
|
13
|
+
W -->|verified SSH + SFTP| V["VPS"]
|
|
14
|
+
V --> N["Existing n8n container<br>unchanged"]
|
|
15
|
+
V --> S["New openai-oauth sidecar"]
|
|
16
|
+
N -->|Docker DNS<br>n8n-openai-oauth:10531| S
|
|
17
|
+
S --> C["OpenAI service used by<br>the upstream helper"]
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Why this integration is possible
|
|
21
|
+
|
|
22
|
+
The design combines four existing interfaces rather than changing n8n:
|
|
23
|
+
|
|
24
|
+
1. The n8n OpenAI credential accepts a custom Base URL.
|
|
25
|
+
2. The pinned bridge implements OpenAI-compatible model, Responses, and chat
|
|
26
|
+
completions routes.
|
|
27
|
+
3. Docker Compose can attach a separate project to an existing external
|
|
28
|
+
network.
|
|
29
|
+
4. Docker DNS resolves the private sidecar hostname from the n8n container.
|
|
30
|
+
|
|
31
|
+
n8n therefore talks to the private sidecar with its normal OpenAI request
|
|
32
|
+
shape. The sidecar handles upstream OAuth authentication with its mounted
|
|
33
|
+
credential. No OpenAI Platform API key is created.
|
|
34
|
+
|
|
35
|
+
## The mutation boundary
|
|
36
|
+
|
|
37
|
+
The installer can write only:
|
|
38
|
+
|
|
39
|
+
```text
|
|
40
|
+
/docker/n8n-openai-oauth/
|
|
41
|
+
├── .managed-by-n8n-openai-oauth
|
|
42
|
+
├── Dockerfile
|
|
43
|
+
├── docker-compose.yml
|
|
44
|
+
└── auth/
|
|
45
|
+
└── auth.json
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Its deployment commands always include:
|
|
49
|
+
|
|
50
|
+
```text
|
|
51
|
+
--project-name n8n-openai-oauth
|
|
52
|
+
--file /docker/n8n-openai-oauth/docker-compose.yml
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
The only service passed to `build` or `up` is `openai-oauth`, and `up` includes
|
|
56
|
+
`--no-deps`.
|
|
57
|
+
|
|
58
|
+
## Existing n8n operations
|
|
59
|
+
|
|
60
|
+
| Operation | Wizard behavior |
|
|
61
|
+
|---|---|
|
|
62
|
+
| Read running container list | Allowed |
|
|
63
|
+
| Read n8n network names | Allowed |
|
|
64
|
+
| Run a command inside n8n | Not used during installation |
|
|
65
|
+
| Edit n8n Compose | Forbidden |
|
|
66
|
+
| Build n8n image | Forbidden |
|
|
67
|
+
| Restart or stop n8n | Forbidden |
|
|
68
|
+
| Recreate or remove n8n | Forbidden |
|
|
69
|
+
| Publish a new VPS port | Forbidden |
|
|
70
|
+
| Add a Traefik route | Forbidden |
|
|
71
|
+
|
|
72
|
+
## Why the Base URL uses a service name
|
|
73
|
+
|
|
74
|
+
Docker Compose can attach a separate project to an existing external network.
|
|
75
|
+
Containers on that network can use Docker DNS to reach a service by name.
|
|
76
|
+
That is why n8n uses:
|
|
77
|
+
|
|
78
|
+
```text
|
|
79
|
+
http://n8n-openai-oauth:10531/v1
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
It must not use `127.0.0.1`, and the VPS does not need a public port. See
|
|
83
|
+
[Docker's external-network documentation](https://docs.docker.com/compose/how-tos/networking/#use-an-existing-network).
|
|
84
|
+
|
|
85
|
+
## Request paths
|
|
86
|
+
|
|
87
|
+
The n8n OpenAI credential validates with:
|
|
88
|
+
|
|
89
|
+
```text
|
|
90
|
+
GET /v1/models
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
The OpenAI Chat Model can use:
|
|
94
|
+
|
|
95
|
+
```text
|
|
96
|
+
POST /v1/responses
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
The compatibility path is:
|
|
100
|
+
|
|
101
|
+
```text
|
|
102
|
+
POST /v1/chat/completions
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
The placeholder API key satisfies n8n's required credential field. The
|
|
106
|
+
sidecar authenticates upstream with the mounted OAuth file.
|
|
107
|
+
|
|
108
|
+
## Technical sources
|
|
109
|
+
|
|
110
|
+
- [`openai-oauth` v2.0.0 server routes](https://github.com/EvanZhouDev/openai-oauth/blob/v2.0.0/packages/openai-oauth/src/server.ts)
|
|
111
|
+
- [`openai-oauth` v2.0.0 login flow](https://github.com/EvanZhouDev/openai-oauth/blob/v2.0.0/packages/openai-oauth/src/login.ts)
|
|
112
|
+
- [n8n OpenAI credential documentation](https://docs.n8n.io/integrations/builtin/credentials/openai/)
|
|
113
|
+
- [n8n OpenAI credential source](https://github.com/n8n-io/n8n/blob/master/packages/nodes-base/credentials/OpenAiApi.credentials.ts)
|
|
114
|
+
- [Docker Compose networking](https://docs.docker.com/compose/how-tos/networking/)
|
|
115
|
+
- [Docker Compose `expose`](https://docs.docker.com/reference/compose-file/services/#expose)
|
|
116
|
+
- [Docker port publishing](https://docs.docker.com/engine/network/port-publishing/)
|
|
117
|
+
|
|
118
|
+
## Failure behavior
|
|
119
|
+
|
|
120
|
+
- Invalid host, port, username, container, or network names are rejected.
|
|
121
|
+
- A changed SSH fingerprint blocks authentication.
|
|
122
|
+
- An existing unmanaged install directory is not overwritten.
|
|
123
|
+
- Invalid OAuth JSON is rejected before Docker changes.
|
|
124
|
+
- A failed Compose validation stops before build.
|
|
125
|
+
- A failed build or start does not trigger an n8n action.
|
|
126
|
+
- An unexpected host-port mapping causes verification to fail.
|
|
127
|
+
- The SSH connection closes after installation or when the wizard stops.
|
package/docs/brand.md
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
# Relmio brand
|
|
2
|
+
|
|
3
|
+
Relmio is the public name for the project formerly described as n8n OpenAI
|
|
4
|
+
OAuth Setup.
|
|
5
|
+
|
|
6
|
+
The name is intentionally client-agnostic. The current wizard configures a
|
|
7
|
+
private OpenAI-compatible OAuth sidecar for self-hosted n8n, while the product
|
|
8
|
+
direction can grow to support other OpenAI-compatible clients and SDK-based
|
|
9
|
+
applications.
|
|
10
|
+
|
|
11
|
+
## Mark
|
|
12
|
+
|
|
13
|
+

|
|
14
|
+
|
|
15
|
+
Two independent lanes converge around a right-facing negative-space arrow. The
|
|
16
|
+
shape represents an authenticated upstream connection being relayed through a
|
|
17
|
+
single compatible interface.
|
|
18
|
+
|
|
19
|
+
The mark was developed from the checked-in generated concept source at
|
|
20
|
+
[`images/brand/relmio-concept-source.png`](images/brand/relmio-concept-source.png)
|
|
21
|
+
and redrawn as compact SVG geometry for reliable rendering at small sizes.
|
|
22
|
+
|
|
23
|
+
## Colors
|
|
24
|
+
|
|
25
|
+
| Token | Hex | Use |
|
|
26
|
+
|---|---|---|
|
|
27
|
+
| Relay teal | `#137c74` | Primary lane, actions, active states |
|
|
28
|
+
| Midnight ink | `#12211f` | Secondary lane, text, high-contrast surfaces |
|
|
29
|
+
| Signal tint | `#e7f3f0` | Quiet selected and informational surfaces |
|
|
30
|
+
| Canvas | `#f4f2ed` | Warm application background |
|
|
31
|
+
|
|
32
|
+
Use the two-color mark on light backgrounds. On a dark surface, place the
|
|
33
|
+
unchanged mark on a white or canvas-colored tile with enough padding. Do not
|
|
34
|
+
rotate, stretch, outline, add gradients, or recreate the mark with provider
|
|
35
|
+
brand colors.
|
|
36
|
+
|
|
37
|
+
## Compatibility names
|
|
38
|
+
|
|
39
|
+
The public product and npm package use **Relmio** and `relmio`.
|
|
40
|
+
|
|
41
|
+
Existing remote paths, Docker project/service names, marker files, and local
|
|
42
|
+
credential paths keep their `n8n-openai-oauth` identifiers. Those values are
|
|
43
|
+
operational compatibility and safety boundaries, not the public brand.
|
|
Binary file
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<svg
|
|
2
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
3
|
+
viewBox="0 0 64 64"
|
|
4
|
+
role="img"
|
|
5
|
+
aria-labelledby="relmio-mark-title"
|
|
6
|
+
>
|
|
7
|
+
<title id="relmio-mark-title">Relmio mark</title>
|
|
8
|
+
<path
|
|
9
|
+
fill="#137c74"
|
|
10
|
+
d="M7 8h19l31 24H41L26 20v10L7 17Z"
|
|
11
|
+
/>
|
|
12
|
+
<path
|
|
13
|
+
fill="#12211f"
|
|
14
|
+
d="M7 47l19-13v10l15-12h16L26 56H7Z"
|
|
15
|
+
/>
|
|
16
|
+
</svg>
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|