dsh-remote-gateway
Manifest validSource-filtered HTTP/SSE/WebSocket gateway for using the DSH Web UI behind an authenticated reverse proxy, with loopback trust adaptation, in-app host directory selection, and an allowlisted health en
DSH Remote Gateway
A source-filtered gateway for using DeepSeek Harness through an authenticated reverse proxy.
简体中文 · Security · Compatibility

Why
DSH intentionally keeps privileged browser capabilities on loopback. A normal reverse proxy can render the page remotely while settings, plugin bundles, WebSockets, or host directory selection still fail. This plugin provides a narrow compatibility gateway without exposing the internal DSH web server directly.
Features
- Proxies HTTP, SSE, and WebSocket traffic.
- Accepts requests only from explicitly listed source IP addresses.
- Keeps the internal DSH web server bound to
127.0.0.1. - Rewrites the upstream
HostandOriginto the internal loopback authority. - Strips edge authentication and forwarded-client identity headers before requests enter DSH.
- Patches only the exact
dsh-client-connectioncapability probe; every other plugin bundle is passed through byte-for-byte. - Replaces the host-native directory dialog with DSH's in-app filesystem browser, so remote users can choose a workspace on the DSH host.
- Starts and stops with the DSH plugin lifecycle, so an existing systemd, launchd, or other DSH supervisor also supervises the gateway.
Architecture
The reverse proxy is the public security boundary. It must provide TLS and authentication. The gateway's source allowlist is defense in depth, not user authentication.
Install
Requirements:
- DSH web profile
- Node.js 22.19 or newer
- A reverse proxy that supports WebSocket forwarding and authentication
Install from GitHub:
dsh plugin --profile web add github:Jiachi5533/dsh-remote-gateway
Then edit the generated remote-gateway entry in ~/.dsh/profiles/web/cordis.patch.yml:
- id: remote-gateway
name: '@jiachi/dsh-remote-gateway'
config:
host: 0.0.0.0
port: 3080
allowedSources:
- 192.0.2.10 # exact LAN address of the reverse proxy
- 127.0.0.1 # optional local health checks
Restart the DSH web process after the first installation. Configure the reverse proxy to send HTTP and WebSocket traffic to http://DSH_HOST_LAN_IP:3080, and enable HTTPS plus authentication at that proxy.
Never expose port 3080 directly to the internet. Do not add broad network ranges to
allowedSources; the current implementation accepts exact IP addresses only.
Configuration
| Option | Default | Description |
|---|---|---|
host | 0.0.0.0 | Gateway listen address. |
port | 3080 | Gateway listen port. Use 0 only in tests. |
allowedSources | ['127.0.0.1'] | Exact IPv4 or IPv6 source addresses allowed to connect. |
IPv4-mapped addresses are canonicalized, and IPv6 loopback ::1 is treated as 127.0.0.1. The upstream host and port are obtained from DSH itself and cannot be redirected through plugin configuration. Startup fails if the internal DSH web server is not bound to 127.0.0.1.
Allowlisted monitoring systems can check GET /_dsh-remote-gateway/health. It returns 200 ok without contacting the DSH upstream, so it verifies the gateway process and source policy rather than DSH readiness.
Security model
- TLS and user authentication terminate at your reverse proxy.
- Only the reverse proxy's LAN address should be allowed at the gateway.
- The internal DSH web server stays loopback-only.
Authorization,Proxy-Authorization,Forwarded,X-Forwarded-*, andX-Real-IPare removed before proxying upstream.- A source-IP allowlist does not protect against a compromised reverse proxy or another device that can use the same source address.
- DSH plugins execute with the DSH process permissions. Review every third-party plugin before installation.
See SECURITY.md for reporting and operational guidance.
Compatibility
| Component | Status |
|---|---|
DSH 0.1.1-rc.2 | Verified on 2026-08-28 |
| HTTP and SSE | Verified |
| WebSocket upgrade | Verified |
| Settings API | Verified |
| In-app host directory browser | Verified |
| Existing and future standard Host/Client bundles | Passed through unchanged, except the exact connection module path |
The connection compatibility patch is deliberately fail-closed. If a DSH update changes the expected probe, that module returns 502 with an explicit log message instead of silently loading a partly broken remote UI.
Most well-behaved plugins continue to work because their client assets and same-origin requests are transparently forwarded. A plugin may still need its own remote adaptation if it hard-codes localhost, opens a native host dialog, or independently rejects non-loopback browser locations.
Upgrade and removal
Update by re-adding the GitHub source from dsh-market or the CLI, then restart DSH:
dsh plugin --profile web add github:Jiachi5533/dsh-remote-gateway
Remove it with:
dsh plugin --profile web remove @jiachi/dsh-remote-gateway
After removal, delete any remaining remote-gateway, directory-picker-browse, and ui-directory-picker-browse rows that were added by this plugin from the profile patch, then restart DSH.
Troubleshooting
403 forbidden: the TCP source address is not present inallowedSources. Add the reverse proxy's LAN IP, not the remote browser's public IP.502 ... compatibility probe matched 0 times: the installed DSH client connection module changed. Pin a verified DSH version or open an issue with both version numbers.- Page loads but WebSocket fails: enable WebSocket upgrade forwarding in the reverse proxy.
- Native folder dialog appears: confirm both browse picker rows in
cordis.patch.ymlare enabled and the nativedirectory-pickerrow is disabled. - New UI plugin is missing: restart DSH after installing the plugin, then hard-refresh the browser.
Development
npm test
The test suite covers source filtering, IPv4-mapped addresses, trust-header rewriting, fail-closed module patching, and byte-preserving proxy behavior for unrelated plugin bundles.
License
Comments
Loading…
Similar plugins
by siberiah2o
Remote access gateway for the DeepSeek Harness Web GUI: login auth + HTTP/WebSocket reverse proxy to the loopback DSH server.
★ 0
JavaScript
Aug 21, 2026
dsh plugin --profile web add dsh-plugin-remoteby clarknu
HTTPS + login gateway for the DeepSeek Harness web surface: access your DSH Web UI securely from another machine on your LAN, or from the internet via port forwarding. Fail-closed defaults (loopback-o
★ 8
↓ 167/wk
MIT
JavaScript
Sep 14, 2026
dsh plugin --profile web add dsh-gatewayby JUANWANG-BUAA
Auditable, token-gated DeepSeek Harness remote gateway: mobile QR access, per-device sessions, Host/Origin rewrite, settings/credentials/directory support.
★ 51
↓ 204/wk
MIT
TypeScript
Oct 24, 2026
dsh plugin --profile web add dsh-full-remoteby luodeb
Authentication reverse-proxy gateway plugin for DeepSeek Harness Web
★ 3
↓ 68/wk
BSD-3-Clause
TypeScript
Aug 17, 2026
dsh plugin --profile web add dsh-web-auth-gatewayRemote access for the DSH Web GUI: LAN QR access, cloudflared quick tunnels, and frp reverse proxying via your own server, with a built-in auth portal.
★ 0
↓ 71/wk
dsh plugin --profile web add dsh-webgateby idoall
LAN access for the official DSH Web UI through a gated reverse proxy: DSH keeps its own loopback binding, and a second port adds a password gate, self-signed HTTPS and per-device pairing that can be r
★ 3
↓ 626/wk
MIT
TypeScript
Oct 27, 2026
dsh plugin --profile web add dsh-lan-guard