Repository navigation
Description
Summary
Give each remote environment's internal-browser previews a SOCKS-routed preview profile (the Orca model), so pages load at their true origin (http://localhost:5173) on every topology the desktop can tunnel, with cookies, OAuth redirects (including response_mode=form_post), and CORS behaving exactly as on the server. This is Phase 2 ("fidelity") of the internal-browser roadmap: an upgrade over the preview gateway, not a replacement.
Current state
- Preview gateway (Phase 1, feat: internal browser preview gateway (Phase 1) #60) reaches server-loopback dev servers on LAN/WSL/SSH and browser mode, but gives each target a new origin (
http://<server>:<gateway port>orhttp://127.0.0.1:<random>). - SSH same-port (
feat/preview-ssh-same-port) keeps the real origin over desktop SSH when the local port is free, and makes the gateway cookieSameSite=Laxso GET OAuth callbacks work. Remaining gaps it cannot close: busy local ports (falls back to a new origin),form_postOAuth callbacks, LAN/WSL (always a new origin), and anything the gateway rewrites. - Per-environment preview storage already exists (same branch, spec §6): the local environment keeps
preview-profile/bibcodepreview01; every other environment has its own profile (preview-profiles/<hash>or a macOS data store), each held by one long-lived native preview host (recreating child webviews disconnected the app). That is the profile boundary a per-environment proxy needs.
Research (from docs/plans/2026-10-06-internal-browser-and-mobile-emulator-research.md §2.4 (a), §2.6)
-
WebviewBuilder::proxy_url(http|socks5)exists (tauri-2.11.5/src/webview/mod.rs:1002-1013) but wry applies it to the profile/data store, not the view:Engine How wry applies it Consequence WebView2 appends --proxy-server=…to the environment's browser args (wry-0.55.1/src/webview2/mod.rs:304-317)needs its own data_directory(now true per environment). Chromium bypasses loopback implicitly → must pass--proxy-bypass-list=<-loopback>throughadditional_browser_args(Windows-only, replaces wry defaults that must be re-added)WebKitGTK website_data_manager.set_network_proxy_settings(Custom, …)with an empty ignore list (wry-0.55.1/src/webkitgtk/mod.rs:267-278)per WebContext (per profile); loopback handling unverified WKWebView KVC proxyConfigurationsonWKWebsiteDataStore(wry-0.55.1/src/wkwebview/mod.rs:326-343) behind wrymac-proxy= Taurimacos-proxyfeature (not enabled in BiBCode)per data store (now per environment); macOS 14+; loopback handling unverified -
SOCKS endpoint per topology: SSH:
ssh -D 127.0.0.1:<port>on the desktop's managed connection (like today's-Lchildren inapps/desktop/src-tauri/src/ssh.rs). LAN/WSL/relay: a new tunnel RPC (Orca'snetwork.browserTunnel), i.e. a new protocol surface carried over the typed WebSocket RPC. -
Security: a loopback SOCKS listener is reachable by any local process; Orca makes it CONNECT-only on loopback (
orca/src/main/browser/remote-browser-socks-server.ts:60,104-107). DNS-prefetch and WebRTC can leak around the proxy and need a policy. -
Browser mode gets nothing (no webview) — the gateway stays the browser-mode path.
-
Blockers: Linux child-webview geometry (wry moves children only under X11 or a
gtk::Fixedparent; tauri#10420/#16132/#15656), the macOS feature flag, the WebView2 bypass list.
Recommended plan (design document first)
- Spike (throwaway): on each engine, a preview profile with a SOCKS proxy to a test server — confirm loopback is proxied (WebView2 with
<-loopback>, WebKitGTK empty ignore list, WKWebViewproxyConfigurations), and that DNS resolves through the proxy (socks5h-like behaviour). - Design doc: routing policy (which environments/URLs use SOCKS vs gateway; fallback to the gateway when the tunnel is down), profile lifecycle (proxy is fixed at environment creation → recreate-free host per environment already in place), tunnel RPC shape (auth scope
orchestration:operate, per-connection flow control, limits), SOCKS server hardening (CONNECT-only, loopback, per-environment credentials if possible), leak policy (DNS prefetch off, WebRTC off for proxied profiles), macOS feature enablement. - Desktop: enable
macos-proxy; per-environmentproxy_url; WebView2additional_browser_argswith the bypass list; a CONNECT-only loopback SOCKS server (Rust, no sidecar) bridging tossh -D(SSH) or the tunnel RPC (others). - Server: tunnel RPC (
network.browserTunnel-like) that opens loopback TCP connections on the server for an authorized environment, with bounded buffers and backpressure; reuse admission/limits patterns from the gateway. - Web: resolver chooses "load canonical URL directly" for SOCKS-routed environments; gateway remains the fallback and the browser-mode path.
- Docs/runbooks for every engine and topology.
Security considerations
- CONNECT-only, loopback-only SOCKS listener; consider per-environment auth so one environment's profile cannot route through another's tunnel.
- Tunnel RPC must only reach the server's loopback (or an explicit allowlist), never arbitrary hosts, unless deliberately designed.
- Leak policy for DNS prefetch and WebRTC in proxied profiles.
Open questions
- Is SOCKS worth it given the gateway + SSH same-port coverage? (The research says "only if Phase 1 falls short" — collect cases:
form_postOAuth, LAN/WSL origin, busy ports.) - Tunnel RPC over the existing typed RPC (base64 JSON, stop-and-wait streams) vs a dedicated authenticated binary WebSocket (a carve-out to the typed-RPC rule)?
- Linux: fix child-webview geometry (
gtk::Fixed) first, or ship SOCKS without Linux?
Acceptance criteria
- On Windows, macOS 14+, and Linux desktops, a preview of
http://localhost:5173from an SSH, LAN, WSL, or relay environment loads athttp://localhost:5173through that environment, with OAuthform_postcallbacks and CORS allowlists working. - Loopback on the client is never reached by a proxied profile; DNS and WebRTC leak tests pass.
- Turning SOCKS off (or a tunnel failure) falls back to the gateway with an actionable notice.
- Tests: SOCKS server unit tests, tunnel RPC tests, per-engine proxy configuration tests; native validation report per OS.
References
docs/plans/2026-10-06-internal-browser-and-mobile-emulator-research.md§2.4 (a), §2.6, §5 Phase 2 item 10docs/superpowers/specs/2026-10-09-preview-ssh-same-port-design.md§6 (per-environment preview storage)apps/desktop/src-tauri/src/preview/host.rs,apps/desktop/src-tauri/src/ssh.rs,apps/web/src/browser/previewGateway.ts
Activity
feat(server): preview tunnels to the server's loopback over RPC (#69)
feat(desktop): load remote environments' previews at their real origi…
fix(desktop): serve preview SOCKS connections only from this account'…
fix(preview): tunnel wildcard addresses from a Linux preview (#69)
merge: release v0.9.3 (PR #108)
mubeda commentedon Oct 15, 2026
Shipped in v0.9.3 for the Linux desktop (ec1c5e3, 464c481, 1715a40, 80ddab9).
preview.tunnelOpen/Write/Read/Close); it only ever dials127.0.0.1and::1.localhost,*.localhost,127.0.0.0/8,::1, and the wildcard binds0.0.0.0and::) through a per-environment SOCKS server, so the page loads at its real origin (http://localhost:5173, HTTPS included). Other hosts connect from this computer, as an unproxied browser would./proc/net/tcp*).Closing as shipped for Linux. Windows (WebView2) and macOS (WKWebView) profiles are not built yet; please open a new issue against v0.9.3 for each platform when you want them.