Repository navigation
[Feature]: Render SSH-environment browser pages locally and route their traffic through the SSH host (instead of streaming) #27869
Description
Before submitting
- I searched existing issues and did not find a duplicate.
Area
apps/desktop (preview/browser), packages/ssh
Problem
For SSH (and other remote) environments, the in-app browser is a server-rendered stream. On anything but a fast link it is laggy: input latency, frame queueing, and the stream stalling on "Connecting…". Related reports: #17090, #20283, #27610.
Remote loopback dev servers (e.g. Vite on 127.0.0.1:5173) are also not reachable from the client, because the SSH tunnel only forwards the T3 server port (#26890, closed as completed without a fix). The implementation in #26469 was closed unmerged. Port forwarding alone would not fix the lag, since the page would still be streamed.
Proposed solution (modelled on Orca)
Reference: https://www.onorca.dev/docs/browser/overview
(source: stablyai/orca src/main/browser/local-ssh-browser-route.ts, remote-browser-socks-server.ts, browser-certificate-trust-controller.ts)
For a workspace on a paired Remote Orca Server, new browser pages render on this desktop by default while HTTP(S), WebSocket, DNS, and loopback traffic still go through the remote host. Input, selection, and popups stay native to this device without changing the page's network identity.
- Render locally. The preview webview is created on the desktop client. Input, selection and popups stay native.
- Per-SSH-environment local SOCKS5 server on 127.0.0.1 (random port, kept stable across SSH reconnects). The webview session proxy points at it.
- Each SOCKS CONNECT becomes a TCP stream over the existing SSH connection (direct-tcpip). The hostname is sent unresolved, so DNS and loopback are resolved on the remote host.
- Forwarding probe. Detect SSH servers with
AllowTcpForwarding no, show a clear message, and fall back to streamed mode. - Settings (new pages only): "This device" / "Server (streamed)", plus a toolbar indicator showing where traffic goes. "Reopen on server" if local rendering fails.
- Downloads of a locally rendered remote page stay on the remote host.
Target workflow
In a thread on an SSH environment I open the in-app browser and visit:
http://localhost:5173(remote loopback dev server)http://myapp.test/https://myapp.test(defined only in the remote's /etc/hosts or local DNS: dnsmasq, Valet, Herd)http://internal-service:8080(reachable only from the remote's network)
without manual ssh -L and without client-side changes.
Plain HTTP and untrusted certificates: allow, with explicit trust
Remote dev setups are commonly plain HTTP or use self-signed / private-CA certs. T3 must not just block these.
- Plain HTTP: load normally. Show a "Not secure" badge in the toolbar. Do not force an HTTPS upgrade for loopback or remote-local hosts.
- Invalid or self-signed HTTPS: show an interstitial with the cert details (host, SHA-256 fingerprint, error) and a Trust this certificate action.
- Trust is pinned to host:port + leaf cert SHA-256, so a changed cert prompts again.
- Scope options: this session / remember for this environment.
- Manageable and revocable in Settings → Browser → Trusted hosts.
- Per-host "Always allow HTTP/insecure for this host" for users who knowingly serve everything over HTTP (e.g.
*.test), revocable the same way. - Sub-resource and non-main-frame cert errors fail closed unless the host was already trusted, so one trusted page can't silently widen trust.
Alternatives
- Per-port
ssh -Lauto-forwarding (feat(ssh): auto forward remote ports to local over SSH #26469): fixes reachability, not lag, and breaks origin-sensitive apps when the local port differs from the remote one. - Keep streaming and tune it: helps, but cannot match native input and rendering.
Non-goals / open questions
- Paired-server (non-SSH) environments could reuse a multiplexed tunnel later. Orca built a custom TCP multiplexer for that; out of scope here.
- Whether mkcert/Valet roots on the remote should be importable into the client trust store, vs. only per-cert pinning.
Impact
Major degradation for remote/SSH workflows, where the preview is the main way to check the running app.
Activity