Replies: 1 comment
|
核验成立(当前 main HEAD 补两个设计点: 1. 把"narration only"做成不变量 + 测试,而不是文档承诺 你的 #3210 同一部署里已证明:Host-preserving 代理(tailscale serve)会把客户端提供的 2. 给 agent/插件同时暴露 loopback 提示
其余部分(parse-time origin 校验、默认行为不变、18/18 测试)都很干净,支持进仓库。 |
|
核验成立(当前 main HEAD 补两个设计点: 1. 把"narration only"做成不变量 + 测试,而不是文档承诺 你的 #3210 同一部署里已证明:Host-preserving 代理(tailscale serve)会把客户端提供的 2. 给 agent/插件同时暴露 loopback 提示
其余部分(parse-time origin 校验、默认行为不变、18/18 测试)都很干净,支持进仓库。 |
Uh oh!
There was an error while loading. Please reload this page.
The setup.
dsh webbinds loopback (rightly — the GUI is an RCE surface) and a reverse proxy publishes it properly: TLS, a real hostname, verified identity. The natural instance istailscale serve(https://host.tailnet.ts.net:8443 → http://127.0.0.1:3080), but the same shape applies to Caddy/nginx on a home LAN. With--trusted-hostdeclared, this mostly works today: the SPA loads, WebSockets upgrade,/apipasses the browser-trust fence (all verified empirically on v0.1.0-rc.7 + tailscale 1.102.2).The gap. Everything the runtime narrates about where it lives is hardcoded to loopback (
localWebUrl()indsh-web-app):DSH_WEB_URLtells every agent shell the GUI is athttp://127.0.0.1:3080— an origin the remote operator's browser cannot resolve, so any user-facing link an agent or plugin mints from it is dead on arrival;app:web-surfaceprompt section orients the model the same way;In our deployment this is the single largest source of "plugin broke when I went remote": skills that share diagrams minted
127.0.0.1:8765links; a shared-browser viewer needed a second SSH forward; agents handed users localhost URLs in chat. All inherited from one hardcoded string.The proposal (implemented, tested). One opt-in config:
When set, it becomes the canonical user-facing URL for the prompt section,
DSH_WEB_URL, and the URL line (loopback/LAN kept as parenthetical local hints). When unset, behavior is byte-identical to today — the pre-existing web-app tests pass unchanged, and new tests cover both the set and the loader-shaped-undefined paths. The flag validates to a bare http(s) origin at parse time (normalized case, trailing slash stripped; bare hosts, paths, queries, credentials, non-http schemes fail the invocation loudly).No trust implications: this is narration only. The
/apifence is untouched;--trusted-hostremains the only way a non-loopback Host passes it.Tested change: web-app suite 18/18 green (4 new tests),
tsc -bclean. Branch: mrlfarano:external-url · diff: compare with master (5 files, +138/−4, tests included).Happy to rework any part of the shape (config name, flag semantics, URL-line format) — the goal is simply that a proxied deployment stops lying about its own address.
(PR creation appears restricted to collaborators, so posting here per CONTRIBUTING — glad to turn this into a PR whenever the team wants it.)
All reactions