starmux 0.13.0 → 0.14.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/LICENSE +1 -1
- package/README.md +20 -30
- package/dist/src/access-control.js +1 -2
- package/dist/src/access-dashboard.js +2 -3
- package/dist/src/account-access-policy.js +54 -0
- package/dist/src/authorized-workspace-roots.js +0 -1
- package/dist/src/batch-read-policy.js +30 -0
- package/dist/src/cli/instances.js +6 -175
- package/dist/src/cli/oauth.js +0 -1
- package/dist/src/cli/starmux-status.js +10 -14
- package/dist/src/cli/starmux-supervisor.js +0 -1
- package/dist/src/cli/starmux.js +13 -25
- package/dist/src/config-schemas.js +0 -9
- package/dist/src/configured-mcp-upstreams.js +0 -1
- package/dist/src/contracts.js +0 -1
- package/dist/src/current-permission-probe.js +0 -1
- package/dist/src/dc-workspace-http.js +57 -33
- package/dist/src/deny-dashboard.js +2 -3
- package/dist/src/desktop-commander-facade.js +4 -4
- package/dist/src/explicit-deny-rules.js +2 -3
- package/dist/src/global-core-control.js +2 -3
- package/dist/src/home-write-sandbox.js +0 -1
- package/dist/src/http-host-policy.js +20 -0
- package/dist/src/instance-runtime.js +3 -3
- package/dist/src/instance-store.js +28 -22
- package/dist/src/instance-worker.js +2 -3
- package/dist/src/invocation.js +1 -2
- package/dist/src/local-desktop-read-probe.js +5 -88
- package/dist/src/managed-workspace-policy.js +38 -4
- package/dist/src/mcp-results.js +0 -1
- package/dist/src/mcp-upstream-router.js +0 -1
- package/dist/src/oauth-keycloak.js +0 -1
- package/dist/src/oauth-resource.js +0 -1
- package/dist/src/ops-dashboard.js +2 -179
- package/dist/src/permissions-dashboard.js +3 -4
- package/dist/src/platform.js +3 -4
- package/dist/src/privacy-diagnostics.js +0 -1
- package/dist/src/private-mcp-activity.js +0 -1
- package/dist/src/private-store-lock.js +0 -1
- package/dist/src/project-dev-presets.js +0 -1
- package/dist/src/project-git-workflow.js +0 -1
- package/dist/src/project-workspace-policy.js +10 -6
- package/dist/src/runtime-identity.js +0 -14
- package/dist/src/runtime-paths.js +0 -3
- package/dist/src/tool-dispatch.js +45 -46
- package/dist/src/validation.js +0 -1
- package/dist/src/workspace-grants.js +1 -2
- package/package.json +13 -17
- package/scripts/prepare.mjs +1 -1
- package/CONTRIBUTING.md +0 -18
- package/SECURITY.md +0 -7
- package/app/README.md +0 -29
- package/dist/src/access-control.js.map +0 -1
- package/dist/src/access-dashboard.js.map +0 -1
- package/dist/src/authorized-workspace-roots.js.map +0 -1
- package/dist/src/cli/access.js +0 -53
- package/dist/src/cli/access.js.map +0 -1
- package/dist/src/cli/community-remote-revoke.js +0 -32
- package/dist/src/cli/community-remote-revoke.js.map +0 -1
- package/dist/src/cli/instances.js.map +0 -1
- package/dist/src/cli/live-home-settings.js +0 -35
- package/dist/src/cli/live-home-settings.js.map +0 -1
- package/dist/src/cli/mac-mcp-gateway.js +0 -257
- package/dist/src/cli/mac-mcp-gateway.js.map +0 -1
- package/dist/src/cli/oauth.js.map +0 -1
- package/dist/src/cli/permissions-owner.js +0 -27
- package/dist/src/cli/permissions-owner.js.map +0 -1
- package/dist/src/cli/service-setup.js +0 -26
- package/dist/src/cli/service-setup.js.map +0 -1
- package/dist/src/cli/setup-wizard.js +0 -149
- package/dist/src/cli/setup-wizard.js.map +0 -1
- package/dist/src/cli/starmux-status.js.map +0 -1
- package/dist/src/cli/starmux-supervisor.js.map +0 -1
- package/dist/src/cli/starmux.js.map +0 -1
- package/dist/src/cli/verify-setup.js +0 -53
- package/dist/src/cli/verify-setup.js.map +0 -1
- package/dist/src/community-remote-revocations.js +0 -135
- package/dist/src/community-remote-revocations.js.map +0 -1
- package/dist/src/config-schemas.js.map +0 -1
- package/dist/src/configured-mcp-upstreams.js.map +0 -1
- package/dist/src/contracts.js.map +0 -1
- package/dist/src/current-permission-probe.js.map +0 -1
- package/dist/src/dc-workspace-http.js.map +0 -1
- package/dist/src/deny-dashboard.js.map +0 -1
- package/dist/src/desktop-commander-facade.js.map +0 -1
- package/dist/src/explicit-deny-rules.js.map +0 -1
- package/dist/src/gateway-status-format.js +0 -66
- package/dist/src/gateway-status-format.js.map +0 -1
- package/dist/src/global-core-control.js.map +0 -1
- package/dist/src/home-write-sandbox.js.map +0 -1
- package/dist/src/instance-migration.js +0 -138
- package/dist/src/instance-migration.js.map +0 -1
- package/dist/src/instance-runtime.js.map +0 -1
- package/dist/src/instance-store.js.map +0 -1
- package/dist/src/instance-worker.js.map +0 -1
- package/dist/src/invocation.js.map +0 -1
- package/dist/src/live-profile-home-settings.js +0 -80
- package/dist/src/live-profile-home-settings.js.map +0 -1
- package/dist/src/local-desktop-read-probe.js.map +0 -1
- package/dist/src/managed-workspace-policy.js.map +0 -1
- package/dist/src/mcp-results.js.map +0 -1
- package/dist/src/mcp-upstream-router.js.map +0 -1
- package/dist/src/oauth-keycloak.js.map +0 -1
- package/dist/src/oauth-resource.js.map +0 -1
- package/dist/src/operator-cli.js +0 -559
- package/dist/src/operator-cli.js.map +0 -1
- package/dist/src/ops-dashboard.js.map +0 -1
- package/dist/src/permissions-dashboard.js.map +0 -1
- package/dist/src/platform.js.map +0 -1
- package/dist/src/privacy-diagnostics.js.map +0 -1
- package/dist/src/private-mcp-activity.js.map +0 -1
- package/dist/src/private-store-lock.js.map +0 -1
- package/dist/src/project-dev-presets.js.map +0 -1
- package/dist/src/project-git-workflow.js.map +0 -1
- package/dist/src/project-workspace-policy.js.map +0 -1
- package/dist/src/read-scope.js +0 -44
- package/dist/src/read-scope.js.map +0 -1
- package/dist/src/release1-onboarding.js +0 -120
- package/dist/src/release1-onboarding.js.map +0 -1
- package/dist/src/release1-service.js +0 -131
- package/dist/src/release1-service.js.map +0 -1
- package/dist/src/remote-auth.js +0 -47
- package/dist/src/remote-auth.js.map +0 -1
- package/dist/src/runtime-identity.js.map +0 -1
- package/dist/src/runtime-paths.js.map +0 -1
- package/dist/src/starmux-migration.js +0 -172
- package/dist/src/starmux-migration.js.map +0 -1
- package/dist/src/tool-dispatch.js.map +0 -1
- package/dist/src/validation.js.map +0 -1
- package/dist/src/workspace-grants.js.map +0 -1
- package/docs/ACCESS_CONTROL.md +0 -51
- package/docs/CLIENTS.md +0 -22
- package/docs/CONNECT_CHATGPT.md +0 -148
- package/docs/INSTALL.md +0 -62
- package/docs/INSTANCES.md +0 -83
- package/docs/OAUTH.md +0 -116
- package/docs/PLATFORMS.md +0 -29
- package/docs/README.md +0 -16
- package/docs/REMOTE_SETUP.md +0 -280
- package/docs/SECURITY.md +0 -15
- package/docs/assets/starmux-app-en.png +0 -0
- package/docs/assets/starmux-architecture.svg +0 -315
- package/src/dc-workspace-http.mjs +0 -3
- package/test/fixtures/p1-fixture.txt +0 -2
package/docs/README.md
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
# Starmux documentation
|
|
2
|
-
|
|
3
|
-
Start locally, connect your client, then explore advanced configuration as needed.
|
|
4
|
-
|
|
5
|
-
1. [Install and start](INSTALL.md) — npm, workspace, coding mode and everyday commands.
|
|
6
|
-
2. [Connect remotely](REMOTE_SETUP.md) — the complete path through HTTPS or Tunnel to your AI client.
|
|
7
|
-
3. [Choose authentication](ACCESS_CONTROL.md) — API keys, OAuth and protected ingress.
|
|
8
|
-
|
|
9
|
-
## Go further
|
|
10
|
-
|
|
11
|
-
- [OAuth and ChatGPT](OAUTH.md)
|
|
12
|
-
- [Connect ChatGPT (HTTPS & Tunnel)](CONNECT_CHATGPT.md)
|
|
13
|
-
- [Instances and JSONC configuration](INSTANCES.md)
|
|
14
|
-
- [Permissions and security](SECURITY.md)
|
|
15
|
-
- [Client compatibility](CLIENTS.md) and [platform support](PLATFORMS.md)
|
|
16
|
-
- [Contributing](../CONTRIBUTING.md)
|
package/docs/REMOTE_SETUP.md
DELETED
|
@@ -1,280 +0,0 @@
|
|
|
1
|
-
# Remote installation: HTTPS + API key, or ChatGPT OAuth
|
|
2
|
-
|
|
3
|
-
This guide follows the paths exercised with the real Gateway and Desktop Commander. Start with [local installation](INSTALL.md). Commands use the installed `starmux` CLI. Shell examples use POSIX syntax; on Windows set environment variables in PowerShell and use the corresponding `.bat` Keycloak commands.
|
|
4
|
-
|
|
5
|
-
For help choosing between the three authentication modes, read [the access-control comparison](ACCESS_CONTROL.md#choose-an-authentication-mode). For other guides, use the [documentation index](README.md).
|
|
6
|
-
|
|
7
|
-
## Choose authentication independently of transport
|
|
8
|
-
|
|
9
|
-
| Authentication | Choose it when | CLI Command |
|
|
10
|
-
| --- | --- | --- |
|
|
11
|
-
| **None** (`none` / `ingress`) | Connecting locally, or your tunnel already restricts callers | `starmux auth mode none` |
|
|
12
|
-
| **Bearer API key** | Your client accepts an `Authorization: Bearer <key>` header (e.g., WorkBuddy, Cursor) | `starmux auth key "My AI Client"` |
|
|
13
|
-
| **OAuth 2.0** | Your client requires a browser login/consent flow (e.g., ChatGPT Web) | `starmux auth oauth setup ...` |
|
|
14
|
-
|
|
15
|
-
HTTPS reverse proxy and Tunnel are network transport choices; API key and OAuth are authentication choices. Each Starmux instance has one active authentication mode at a time. Switching to OAuth disables API keys on that instance (and vice versa). See the [client matrix](CLIENTS.md).
|
|
16
|
-
|
|
17
|
-
## 1. Start locally
|
|
18
|
-
|
|
19
|
-
```sh
|
|
20
|
-
starmux up
|
|
21
|
-
starmux status
|
|
22
|
-
```
|
|
23
|
-
|
|
24
|
-
Use `starmux up --code` for file editing, Shell and Git. The first activation asks for confirmation. Examples below use port **18893**; use the actual port printed by `status`.
|
|
25
|
-
|
|
26
|
-
The full route is:
|
|
27
|
-
|
|
28
|
-
```text
|
|
29
|
-
AI client → HTTPS / protected Tunnel → authentication → 127.0.0.1:18893/mcp → tools
|
|
30
|
-
```
|
|
31
|
-
|
|
32
|
-
Starmux starts the local service. Choose one of the following routes to connect a remote client. Each key or login uses the instance's approved tool permissions.
|
|
33
|
-
|
|
34
|
-
## 2. HTTPS + Bearer API key
|
|
35
|
-
|
|
36
|
-
### Create the credential before exposing MCP
|
|
37
|
-
|
|
38
|
-
```sh
|
|
39
|
-
starmux auth key "WorkBuddy"
|
|
40
|
-
starmux auth
|
|
41
|
-
starmux up
|
|
42
|
-
```
|
|
43
|
-
|
|
44
|
-
Save the secret shown once in the client's private configuration. Gateway keeps its digest, not the secret. A credential ID from `auth` is not the Bearer secret.
|
|
45
|
-
|
|
46
|
-
### Route HTTPS to the loopback Core
|
|
47
|
-
|
|
48
|
-
Install Caddy, point your own DNS A/AAAA record at a reachable address, and arrange a valid certificate. Save this as your Caddyfile, replacing the hostname and local port:
|
|
49
|
-
|
|
50
|
-
```caddyfile
|
|
51
|
-
{
|
|
52
|
-
admin off
|
|
53
|
-
}
|
|
54
|
-
mcp.example.com {
|
|
55
|
-
handle /mcp {
|
|
56
|
-
reverse_proxy 127.0.0.1:18893 {
|
|
57
|
-
header_up Host 127.0.0.1:18893
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
handle {
|
|
61
|
-
respond "Not found" 404
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
```sh
|
|
67
|
-
caddy validate --config /absolute/path/Caddyfile --adapter caddyfile
|
|
68
|
-
caddy run --config /absolute/path/Caddyfile --adapter caddyfile
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
Caddy's automatic certificate provisioning requires a working ACME validation route. Binding standard ports may require OS service/administrator setup. Keep the process running or install it as a managed service. Keep `/access`, `/dashboard` and all owner-management routes private. The proxy preserves the client's Authorization header; do not replace it with a shared privileged credential.
|
|
72
|
-
|
|
73
|
-
**Already have a certificate, or using port 8443?** The tested IPv6 variant uses `https://mcp.example.com:8443` as the site address, `bind YOUR_PUBLIC_IPV6` and `tls /absolute/path/cert.crt /absolute/path/cert.key` inside the site block. Include `:8443` in the client URL. Certificate renewal and proxy reload remain your responsibility. An IPv6-only endpoint requires an IPv6-capable client execution environment; test from another network rather than assuming DNS proves reachability.
|
|
74
|
-
|
|
75
|
-
### Configure WorkBuddy or another header-capable client
|
|
76
|
-
|
|
77
|
-
For WorkBuddy, merge this entry into `~/.workbuddy/mcp.json` without replacing unrelated servers:
|
|
78
|
-
|
|
79
|
-
```json
|
|
80
|
-
{
|
|
81
|
-
"mcpServers": {
|
|
82
|
-
"starmux": {
|
|
83
|
-
"type": "streamable-http",
|
|
84
|
-
"url": "https://mcp.example.com/mcp",
|
|
85
|
-
"headers": {
|
|
86
|
-
"Authorization": "Bearer smx_REPLACE_WITH_YOUR_API_KEY"
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
}
|
|
90
|
-
}
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
Protect the file with owner-only permissions (Unix `chmod 600`, or equivalent Windows ACLs), then reload the client's MCP configuration. The placeholder is not a working key. Do not commit the real file.
|
|
94
|
-
|
|
95
|
-
For a Codex HTTP MCP configuration, the official client supports an environment-sourced Bearer value:
|
|
96
|
-
|
|
97
|
-
```toml
|
|
98
|
-
[mcp_servers.my_gateway]
|
|
99
|
-
url = "https://mcp.example.com/mcp"
|
|
100
|
-
bearer_token_env_var = "STARMUX_TOKEN"
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
Set that variable securely in the environment of the actual Codex process; setting it in an unrelated terminal does not configure an already running desktop app. This is a documented configuration example, not a claim that this exact Codex API-key path has received project acceptance. See [official Codex MCP configuration](https://learn.chatgpt.com/docs/extend/mcp?surface=cli).
|
|
104
|
-
|
|
105
|
-
### Verify, then test revocation
|
|
106
|
-
|
|
107
|
-
1. From the remote client, explicitly select this Gateway and call `health_check`.
|
|
108
|
-
2. Read an owner-approved test file. If trusted coding is enabled, create, read back and run a small script in a dedicated test directory. Do not substitute the client's own local tools.
|
|
109
|
-
3. Run `starmux auth`, identify that client's credential, then `starmux auth revoke CREDENTIAL_ID`.
|
|
110
|
-
4. The next MCP request with that key must fail with HTTP 401. A missing/wrong key must also fail. Already-running tools are not canceled.
|
|
111
|
-
5. Create a new key to restore access; update the client's private configuration.
|
|
112
|
-
|
|
113
|
-
Local `starmux verify` in API-key mode reads `STARMUX_TOKEN` from its environment. Local PASS confirms the local endpoint; verify remote access with a real tool call from your client.
|
|
114
|
-
|
|
115
|
-
## 3. OAuth: deploy the authorization server
|
|
116
|
-
|
|
117
|
-
This is currently an **operator setup**, not a one-click wizard. The tested provider is Keycloak **26.8.1**, Java **21**, with persistent PostgreSQL **17**. The Gateway package does not install or operate these services for you. Use official distributions and maintain backups/upgrades; the pinned version describes the tested baseline, not a promise of indefinite security support.
|
|
118
|
-
|
|
119
|
-
For the tested Tunnel layout, use one HTTPS origin for both MCP and the issuer:
|
|
120
|
-
|
|
121
|
-
```text
|
|
122
|
-
https://auth.example.com/mcp → Core 127.0.0.1:18893
|
|
123
|
-
https://auth.example.com/realms/gateway/... → Keycloak 127.0.0.1:18080
|
|
124
|
-
```
|
|
125
|
-
|
|
126
|
-
Create your ChatGPT custom MCP definition and copy its **exact callback URL**. Keep that definition while configuring the provider; a callback from another definition is not interchangeable.
|
|
127
|
-
|
|
128
|
-
### Prepare Keycloak and persistent storage
|
|
129
|
-
|
|
130
|
-
1. Install Java 21 and unpack the official Keycloak 26.8.1 distribution into a private operator directory. Provision a dedicated persistent PostgreSQL database and role with access only to that database. Do not use the Gateway's disposable in-memory test deployment for real accounts.
|
|
131
|
-
2. Generate the realm import; use your hostname and callback:
|
|
132
|
-
|
|
133
|
-
```sh
|
|
134
|
-
starmux auth oauth init-keycloak \
|
|
135
|
-
--resource https://auth.example.com/mcp \
|
|
136
|
-
--callback https://chatgpt.com/connector/oauth/YOUR_CALLBACK_ID > gateway-realm.json
|
|
137
|
-
```
|
|
138
|
-
|
|
139
|
-
3. Place this file in Keycloak's `data/import/gateway-realm.json`. Configure the following environment variables in a private service environment file or secret manager. Values below are placeholders; do not paste real passwords into shell history or Git:
|
|
140
|
-
|
|
141
|
-
```text
|
|
142
|
-
KC_DB=postgres
|
|
143
|
-
KC_DB_URL=jdbc:postgresql://127.0.0.1:5432/gateway
|
|
144
|
-
KC_DB_USERNAME=gateway
|
|
145
|
-
KC_DB_PASSWORD=<database-role-password>
|
|
146
|
-
KC_BOOTSTRAP_ADMIN_USERNAME=gateway-admin
|
|
147
|
-
KC_BOOTSTRAP_ADMIN_PASSWORD=<temporary-bootstrap-password>
|
|
148
|
-
```
|
|
149
|
-
|
|
150
|
-
4. With that environment loaded, start the provider:
|
|
151
|
-
|
|
152
|
-
```sh
|
|
153
|
-
/absolute/path/keycloak-26.8.1/bin/kc.sh start \
|
|
154
|
-
--features=resource-indicators \
|
|
155
|
-
--http-enabled=true --http-host=127.0.0.1 --http-port=18080 \
|
|
156
|
-
--hostname=https://auth.example.com \
|
|
157
|
-
--proxy-headers=xforwarded --proxy-trusted-addresses=127.0.0.1 \
|
|
158
|
-
--import-realm
|
|
159
|
-
```
|
|
160
|
-
|
|
161
|
-
Run the provider under a service manager for sustained use. Realm import initializes a new realm; it is not a general update mechanism for an existing realm. Do not use public `start-dev`. Keycloak's resource-indicators feature is experimental in this tested version.
|
|
162
|
-
|
|
163
|
-
5. Manage Keycloak locally with its admin CLI, or through a separately protected administrative route. The public proxy below intentionally does not expose `/admin`. For local CLI access, authenticate with `bin/kcadm.sh config credentials --server http://127.0.0.1:18080 --realm master --user gateway-admin` and enter the password when prompted. Use an owner-only home/config for the admin CLI's stored credentials.
|
|
164
|
-
6. In realm `gateway`, create a dedicated enabled owner account with a non-temporary password; record its user ID. For CLI provisioning, `kcadm.sh create users -r gateway -f /private/path/owner.json` accepts a private user representation with `username`, `enabled: true`, profile fields and `credentials: [{"type":"password","value":"<owner-password>","temporary":false}]`. Create that file with an editor and owner-only permissions. Do not put it in the repository. Meet the realm's required profile fields; if email is unnecessary, explicitly make it optional rather than inventing an address.
|
|
165
|
-
7. Obtain the generated secret for client `gateway-chatgpt` using the protected admin interface/CLI and store it securely for entry into ChatGPT. The client requires authorization code + S256 + consent, with no password/implicit grant. Retire bootstrap administrator credentials according to Keycloak's operational guidance.
|
|
166
|
-
|
|
167
|
-
See [Keycloak deployment](https://www.keycloak.org/server/configuration) and [reverse proxy requirements](https://www.keycloak.org/server/reverseproxy) for platform-specific administration and service hardening.
|
|
168
|
-
|
|
169
|
-
### Publish only the required HTTPS routes
|
|
170
|
-
|
|
171
|
-
Use this Caddyfile instead of the API-key-only one:
|
|
172
|
-
|
|
173
|
-
```caddyfile
|
|
174
|
-
{
|
|
175
|
-
admin off
|
|
176
|
-
}
|
|
177
|
-
auth.example.com {
|
|
178
|
-
@mcp path /mcp /.well-known/oauth-protected-resource /.well-known/oauth-protected-resource/mcp
|
|
179
|
-
handle @mcp {
|
|
180
|
-
reverse_proxy 127.0.0.1:18893 {
|
|
181
|
-
header_up Host 127.0.0.1:18893
|
|
182
|
-
}
|
|
183
|
-
}
|
|
184
|
-
@oauth path /realms/gateway/.well-known/* /realms/gateway/protocol/openid-connect/* /realms/gateway/login-actions/* /resources/*
|
|
185
|
-
handle @oauth {
|
|
186
|
-
reverse_proxy 127.0.0.1:18080 {
|
|
187
|
-
header_up X-Forwarded-Proto https
|
|
188
|
-
header_up X-Forwarded-Host auth.example.com
|
|
189
|
-
header_up X-Forwarded-Port 443
|
|
190
|
-
}
|
|
191
|
-
}
|
|
192
|
-
handle {
|
|
193
|
-
respond "Not found" 404
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
```
|
|
197
|
-
|
|
198
|
-
Validate and run Caddy as in the API-key section. This allowlist is for the **provided-client** setup; it does not publish DCR registration or administrative APIs. On an IPv6-only host, optionally bind the actual stable IPv6 address and keep its AAAA record current.
|
|
199
|
-
|
|
200
|
-
Before enabling public MCP access, configure Core authentication as below. If the proxy is already running while Core still uses ingress mode, keep the `/mcp` route disabled until OAuth mode is set. Issuer metadata can be exposed first for configuration.
|
|
201
|
-
|
|
202
|
-
## 4. Configure Starmux and ChatGPT
|
|
203
|
-
|
|
204
|
-
```sh
|
|
205
|
-
starmux auth oauth setup \
|
|
206
|
-
--issuer https://auth.example.com/realms/gateway \
|
|
207
|
-
--resource https://auth.example.com/mcp \
|
|
208
|
-
--client-id gateway-chatgpt \
|
|
209
|
-
--token-auth client_secret_basic \
|
|
210
|
-
--subject OWNER_USER_ID
|
|
211
|
-
starmux auth oauth doctor
|
|
212
|
-
starmux auth mode oauth
|
|
213
|
-
starmux up
|
|
214
|
-
```
|
|
215
|
-
|
|
216
|
-
Authentication changes apply to subsequent requests immediately. Repeating `starmux up` is safe and reuses the running instance. `doctor` verifies provider discovery, not a remote login. Confirm that unauthenticated `/mcp` requests return 401, while `https://auth.example.com/.well-known/oauth-protected-resource/mcp` is publicly readable.
|
|
217
|
-
|
|
218
|
-
In ChatGPT's custom MCP definition choose OAuth and **custom/provided client**, client ID `gateway-chatgpt`, its client secret, token authentication `client_secret_basic`, and base/default scope `gateway:access`. Keep OIDC/domain claim off for this setup. Let discovery populate endpoints. Do not select DCR or CIMD for this reference deployment. See the complete [field table](OAUTH.md#what-to-enter-in-chatgpt) and [OpenAI authentication documentation](https://developers.openai.com/plugins/build/auth).
|
|
219
|
-
|
|
220
|
-
### Direct HTTPS
|
|
221
|
-
|
|
222
|
-
Use `https://auth.example.com/mcp` as the server URL. Core and Keycloak use that same resource identifier. This configuration is supported by the resource-server design; real ChatGPT direct-HTTPS acceptance is still separate from the tested Tunnel path. Verify reachability from the client's actual network, especially for IPv6-only deployments.
|
|
223
|
-
|
|
224
|
-
### Official OpenAI Tunnel — tested ChatGPT path
|
|
225
|
-
|
|
226
|
-
Provision your own Tunnel and runtime credential using [OpenAI's guide](https://developers.openai.com/api/docs/guides/secure-mcp-tunnels). The existing [Tunnel guide](CONNECT_CHATGPT.md#2-secure-mcp-tunnel--no-inbound-port) explains workspace permissions. For OAuth on the tested tunnel-client **0.0.16** layout:
|
|
227
|
-
|
|
228
|
-
- Set `--mcp.server-url url=https://auth.example.com/mcp`.
|
|
229
|
-
- Set `--mcp.oauth-trusted-origin https://auth.example.com`.
|
|
230
|
-
- Keep the Tunnel ID and runtime secret in private client configuration; neither is the OAuth client secret.
|
|
231
|
-
- Retain automatic OAuth target registration. Do not substitute generic Harpoon targets or disable TLS checks. The tested layout registered ten typed OAuth targets.
|
|
232
|
-
- Choose that Tunnel in ChatGPT, then discover OAuth metadata.
|
|
233
|
-
|
|
234
|
-
**Important resource-alias step:** Tunnel discovery rewrites the MCP resource identifier. Copy the exact discovered **Resource** value from ChatGPT. Do not invent it, use a wildcard, or copy the maintainer's Tunnel ID.
|
|
235
|
-
|
|
236
|
-
1. In Keycloak, register a dedicated bearer-only OpenID Connect resource client (e.g. `gateway-tunnel-resource`) with the attribute `resource_url` equal to that exact value; disable login/service-account flows for it.
|
|
237
|
-
2. In client scope `gateway:access`, add an **Audience** mapper with Included Client Audience `gateway-tunnel-resource` and Add to access token enabled. Registering only the client is insufficient: Keycloak must grant the audience before it narrows the issued token to the requested resource URL.
|
|
238
|
-
3. Re-run the Core configure command above with `--resource-aliases 'EXACT_DISCOVERED_RESOURCE_URL'` appended, then run `starmux auth oauth doctor`. Multiple exact aliases can be comma-separated (maximum eight). Reconfiguration without the option removes existing aliases, so include all intended aliases when updating. The canonical `--resource` remains unchanged.
|
|
239
|
-
4. Save the ChatGPT settings, sign in as the allowed owner and consent to the owner-approved tools.
|
|
240
|
-
|
|
241
|
-
Aliases are explicitly configured identifiers for this same Gateway, not trust in all Tunnel traffic. Core still verifies signature, issuer, client, subject, scope, lifetime and session revocation. No Core network-transport-specific identity inference is introduced.
|
|
242
|
-
|
|
243
|
-
The browser and the Starmux host must both reach the public issuer. See [network troubleshooting](#network-troubleshooting) if discovery or login fails.
|
|
244
|
-
|
|
245
|
-
## 5. Acceptance, management and recovery
|
|
246
|
-
|
|
247
|
-
From a fresh ChatGPT conversation, select the OAuth plugin and request `health_check`, followed by a read/write/run test confined to an explicitly approved disposable directory. Compare the result with Core audit entries showing `verified-oauth`; a successful login or tool list alone does not prove coding works.
|
|
248
|
-
|
|
249
|
-
```sh
|
|
250
|
-
starmux auth
|
|
251
|
-
starmux auth revoke CONNECTION_ID
|
|
252
|
-
```
|
|
253
|
-
|
|
254
|
-
Revocation blocks that **session** on subsequent requests, including new tokens issued by refresh for the same session. It does not cancel already-running tools, undo files written earlier, revoke all clients, or globally disable that account. To deny an account completely, remove its subject from the configured allowlist. Reauthentication with a fresh authorized provider session can restore access; do not erase revocation records. If provider SSO keeps reusing the revoked session, end that provider session before logging in again.
|
|
255
|
-
|
|
256
|
-
Manage keys/sessions in the local **Dashboard → Access control**. The macOS App's **Open Dashboard** action reaches the same store; a separate native OAuth setup screen is not shipped. Read [owner token and file permissions](ACCESS_CONTROL.md) before administering it.
|
|
257
|
-
|
|
258
|
-
| Symptom | Check |
|
|
259
|
-
| --- | --- |
|
|
260
|
-
| Local Core healthy, remote connection fails | Proxy/Tunnel route, TLS, DNS and actual remote address-family reachability |
|
|
261
|
-
| Metadata discovery fails | Both protected-resource paths, issuer discovery and same-origin Tunnel configuration |
|
|
262
|
-
| Keycloak rejects requested resource | Exact discovered resource, resource client's attribute, granted audience mapper and Core aliases |
|
|
263
|
-
| HTTP 401 after revoke or idle expiry | Do not retry tools indefinitely; inspect local revocation state, then use a fresh authorized login if appropriate |
|
|
264
|
-
| HTTP 403 | Allowed owner/client and `gateway:access`; do not expand permissions just to hide a failure |
|
|
265
|
-
| OAuth works but a write is denied | Existing workspace/OS/upstream policy still applies |
|
|
266
|
-
| Web answer/app fails to render | Correlate actual tool/audit results (`starmux logs -f`) before deciding whether execution failed; never automatically repeat a side-effecting call |
|
|
267
|
-
| CLI changes do not affect the server | Check `starmux ls` and `starmux status` to ensure you are targeting the intended instance (`-i <name>`) |
|
|
268
|
-
|
|
269
|
-
The local App, Core, proxy, database, provider and Tunnel have separate process lifecycles. Stopping Core stops new tool service; it does not automatically shut down the others. Persist private configuration and PostgreSQL/Caddy data, configure service startup deliberately, and repeat acceptance after reboot or deployment changes.
|
|
270
|
-
|
|
271
|
-
[OAuth contracts and acceptance evidence](OAUTH.md) · [Access control](ACCESS_CONTROL.md) · [Install](INSTALL.md) · [README](../README.md)
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
## Network troubleshooting
|
|
275
|
-
|
|
276
|
-
| Symptom | Check |
|
|
277
|
-
| --- | --- |
|
|
278
|
-
| Issuer discovery or login cannot connect | Resolve the hostname and test HTTPS from both the host and the browser network. |
|
|
279
|
-
| IPv6-only endpoint is unreachable | Confirm IPv6 routing, current AAAA record, proxy bind and client network support. |
|
|
280
|
-
| Fake-IP DNS or TUN interception breaks discovery | Correct the hostname route in the local network tool; retain TLS certificate verification. |
|
package/docs/SECURITY.md
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
# Security and permissions
|
|
2
|
-
|
|
3
|
-
Starmux is a self-hosted connection and routing layer around real upstream MCP tools. Treat exposure to remote clients as a powerful privilege.
|
|
4
|
-
|
|
5
|
-
- The default **restricted read-only** role enforces project-scoped access and disables arbitrary Shell/write operations.
|
|
6
|
-
- The **trusted coding** role (`starmux up --code`) can edit files and run commands using your OS account permissions. Migrated macOS Home-only configurations keep their previous sandbox until explicitly changed.
|
|
7
|
-
- HTTP MCP listens on loopback (`127.0.0.1`) by default. **Never expose the raw loopback port publicly.** Direct HTTPS requires a publicly reachable TLS endpoint **and caller authentication**. DNS/TLS alone are insufficient.
|
|
8
|
-
- OpenAI Tunnel is outbound and uses OpenAI's forwarding infrastructure. Tunnel readiness alone is **not** caller authorization unless paired with tunnel access controls or Starmux authentication.
|
|
9
|
-
- **OAuth** mode validates tokens and allowed accounts/clients, and supports local session revocation, including refreshed tokens in that session. A fresh authorized session can restore access; session revocation is not an account ban.
|
|
10
|
-
- **Bearer API key** mode authenticates a client credential on every MCP request and supports instant revocation. The default **`none` (`ingress`)** mode does not verify a token in Starmux. See [access control](ACCESS_CONTROL.md). Keys inherit your instance's workspace permissions.
|
|
11
|
-
- Filesystem permissions, macOS TCC/FDA and permissions in the actual upstream Desktop Commander remain relevant.
|
|
12
|
-
- Do not commit API keys, tunnel runtime profiles, passwords or protected files; use personal private configuration and report vulnerabilities privately.
|
|
13
|
-
- Multi-user/multi-host orchestration and user-defined policy scripts are **not shipped** in this preview.
|
|
14
|
-
|
|
15
|
-
See [connection steps](CONNECT_CHATGPT.md) and [platform support](PLATFORMS.md).
|
|
Binary file
|