You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Design issue — future work, not scheduled. Follows the #247 LAN phase; analysis done 2026-08-07.
Problem
#247 gives remote clients plain HTTP + a shared token, honestly scoped to trusted LANs. First-class encrypted connections built into LPDO (no external tools) require solving two problems, and the second one dominates:
Transport crypto — easy (rustls).
Trust bootstrapping + webview delivery — the real work:
A LAN server (IP address, no domain) cannot obtain a publicly-trusted certificate (no CA issues for IPs/.local), so it must be self-signed.
The Tauri webview (WebView2/WebKit) enforces browser TLS rules: self-signed/pinned certs are rejected with no clean per-app override. Any design that ends in danger_accept_invalid_certs is encryption theater and must be rejected outright.
Proposed architecture (the Syncthing model)
Server identity = certificate fingerprint. On first network bind, generate a self-signed cert (rcgen), serve HTTPS (axum-server + rustls). The fingerprint is the server's stable identity, like an SSH host key / Syncthing device ID.
Pairing (TOFU + human verification). On first connect the client shows the fingerprint it sees; the server shows its own (console/log, or in the local GUI); user confirms they match — Bluetooth-pairing style. Pinned thereafter. A changed fingerprint is a hard failure with a loud warning, never a click-through.
Auth upgrades in the same pass: keep the token, bind it to the TLS channel (channel binding — a stolen token is useless off-channel); store it in the OS keychain (Tauri keyring) instead of localStorage; failed-attempt rate limiting; optionally per-client tokens so one device can be revoked; tighten the permissive CORS when serving remotely.
Scope warning
The proxy + custom verifier + pairing UX is a larger chunk than all of #247 phase 1, and the security-sensitive parts (the rustls verifier above all) need adversarial review, not just tests. The pairing UX is where the design succeeds or fails — schedule design time for it, not just implementation.
Explicitly rejected alternatives (from the analysis)
danger_accept_invalid_certs anywhere — worse than the current honest no-TLS warning.
mTLS with user-managed client certs — cert distribution UX is not viable for this audience.
Hand-rolled internet-facing auth on the single shared token — internet exposure needs accounts/lockouts/audit or (better) stays on overlays.
Non-blocking status
Encrypted access is already documented and recommended via Tailscale/WireGuard or an SSH tunnel (docs/remote-server.md, "Encrypted connections") — the SSH variant even keeps the server loopback-only with no open port at all. This issue is for making encryption first-class in-app; it becomes worth its cost roughly when remote access turns into a headline feature (e.g. the #210 portable-client idea).
Acceptance sketch
Fresh pair of machines: pairing flow completes with fingerprint verification; traffic is TLS; a MITM (cert swap) is rejected with the loud-warning UX.
Design issue — future work, not scheduled. Follows the #247 LAN phase; analysis done 2026-08-07.
Problem
#247 gives remote clients plain HTTP + a shared token, honestly scoped to trusted LANs. First-class encrypted connections built into LPDO (no external tools) require solving two problems, and the second one dominates:
danger_accept_invalid_certsis encryption theater and must be rejected outright.Proposed architecture (the Syncthing model)
rcgen), serve HTTPS (axum-server+ rustls). The fingerprint is the server's stable identity, like an SSH host key / Syncthing device ID.127.0.0.1:<ephemeral>; the proxy terminates TLS to the remote server using a custom rustls verifier that checks exactly the pinned fingerprint (pinning — NOT accept-anything). Native calls (upload GUI: large PGN import fails — 'File too large (max 100 MB)' (Megabase); path-first + streamed upload #154, backup CLI: import-pgn / backup fail against the hardened system daemon (ProtectHome/PrivateTmp) for files in $HOME or /tmp #121) and the CLI use the same pinned-reqwest logic directly.Scope warning
The proxy + custom verifier + pairing UX is a larger chunk than all of #247 phase 1, and the security-sensitive parts (the rustls verifier above all) need adversarial review, not just tests. The pairing UX is where the design succeeds or fails — schedule design time for it, not just implementation.
Explicitly rejected alternatives (from the analysis)
danger_accept_invalid_certsanywhere — worse than the current honest no-TLS warning.Non-blocking status
Encrypted access is already documented and recommended via Tailscale/WireGuard or an SSH tunnel (docs/remote-server.md, "Encrypted connections") — the SSH variant even keeps the server loopback-only with no open port at all. This issue is for making encryption first-class in-app; it becomes worth its cost roughly when remote access turns into a headline feature (e.g. the #210 portable-client idea).
Acceptance sketch