Bundle
@sysit/dsh-remote-access
Out-of-tree dsh web-profile bundle: serve the Web UI on all interfaces (env DSH_WEB_HOST) behind the built-in ?token= BrowserAuth and auto-print the LAN URL. Single webserver row — no auth fork, stays composable with built-in BrowserAuth.
- Source
- sysit
- License
- MIT
- Updated
- Updated 6 days ago
Readme
# dsh-remote-access
Out-of-tree [deepseek-harness](https://github.com/deepseek-harness) web-profile **bundle** that lets the `dsh --profile web` GUI listen on **all interfaces** (`0.0.0.0`) so you can open it from another device — while keeping the **built-in `?token=` BrowserAuth and never touching authentication**.
It is intentionally tiny: **one `webserver` row**. Unlike earlier plugins, it does **not** fork `web-startup` / `webserver` / `connection` and does **not** invent its own token gate. That is precisely why it survives dsh upgrades: the auth and the LAN `?token=` URL printing already come from dsh itself; this bundle only lets `host` be non-loopback.
## How it works
- dsh's `BrowserAuth` (`client/connection`) issues a **host-bound** cookie (`dsh-auth-<sha256(authority)>`) when you open the printed `?token=` URL. It already works for a LAN bind.
- `web-app` prints the LAN URL `(LAN: http://<ip>:<port>/?token=...)` whenever the server binds `0.0.0.0`.
- The only blocker in stock dsh is `web-startup` refusing `--host 0.0.0.0`. This bundle **does not unblock that flag**; instead it overrides the `webserver` row's `host` from an env var, so you never pass `--host`.
- Result: zero third-party, zero plugins that own the auth, and a **profile-level patch** the loader re-reads on every boot — so it needs no re-apply after a dsh upgrade.
## Install
```sh
# from a git checkout
dsh plugin --profile web install github:sysit/dsh-remote-access
# or from a local path (e.g. while developing)
dsh plugin --profile web install file:/Path/dsh-remote-access
```
That adds `@sysit/dsh-remote-access` to the profile's `dsh.profile.bundles` (after `dsh-web-app`, so its `webserver` override wins).
## Use
| Want | Command |
|---|---|
| **Remote** (default when set) | `export DSH_WEB_HOST=0.0.0.0 && dsh --profile web --no-open` |
| **Loopback only** | unset `DSH_WEB_HOST`, or `DSH_WEB_HOST=127.0.0.1 dsh --profile web` |
| launchd/KeepAlive | add `export DSH_WEB_HOST="\${DSH_WEB_HOST:-0.0.0.0}"` to the launch script |
On a remote bind the startup log prints both:
```
dsh web: http://127.0.0.1:3080/?token=eqeU… (LAN: http://192.168.1.5:3080/?token=eqeU…)
```
Open the `LAN:` URL on another device — no 401, no plugin auth, no relay. The token is **per-process** (changes each restart); the browser cookie is valid up to `cookieMaxAgeDays` (default 30 days), so an already-open tab keeps working across restarts.
## Upgrade handling
Nothing to re-apply. The patch is a declarative layer in `~/.dsh/profiles/<profile>/` (outside the dsh repo), re-read on every boot. After a dsh upgrade, smoke-check:
```sh
launchctl kickstart -k gui/$(id -u)/com.deepseek-ai.dsh-web # restart your web service
tail -5 ~/Library/Logs/dsh/web.out.log # expect `?token=` + `(LAN: ...)`
```
If dsh ever renames the `webserver` row id or its config keys, regenerate the row from the current official patch:
```sh
dsh --profile web --dump-config # current webserver keys
cat packages/bundle/web-app/cordis.patch.yml # official webserver row
```
## Security notes
- `0.0.0.0` exposes the harness to your network. The `?token=` gate + host-bound cookie are the auth; treat the printed token as a secret and use `--no-open` when remote.
- Cross-site/DNS-rebinding defense stays on (dsh `api-request-trust`); `trustedHosts` still pick up LAN literals automatically.
- The `/api` RPC surface is only as exposed as you make it — prefer SSH forwarding or a VPN if the network is not trusted.
## License
MIT
Install
dsh plugin --profile web add github:sysit/dsh-remote-access
Profile: web
With the hub plugin installed, ask your agent to install it by name — it resolves the same plan shown here.
dsh plugin --profile web add github:stvlynn/dsh.fish#path:packages/dsh-plugin-hub
install sysit-dsh-remote-access from the hub
- This source has no pinned commit, so a later push upstream changes what installs. Prefer pinning a commit.