Repository navigation
fix(editors): open remote projects over Tailscale SSH - #13636
vedprakash2302 wants to merge 2 commits into
Conversation
The server advertised SSH hosts for remote open links only after an sshd answered on its loopback port 22. Tailscale SSH serves only tailnet peers, so hosts that use it instead of OpenSSH showed "No SSH route" even though VS Code and Zed can connect to them. When no sshd answers, the server now runs `tailscale get --json ssh`. If Tailscale SSH is on, it advertises the MagicDNS name as a `tailscale-ssh` target with the account T3 Code runs as, and links name that account before the host. Tailscale SSH signs in as whichever account the client names, and editors otherwise send the local one. The desktop's Zed link check accepts that login the way vscode-remote links already do. Hosts with sshd advertise exactly what they did before. Older clients drop the new target kind and keep showing "No SSH route".
ApprovabilityVerdict: Not approved Macroscope's review found this PR not approvable — This PR introduces automatic Tailscale SSH discovery and new user-qualified editor deep links across server, web, and desktop code. Because it changes remote-access authentication behavior and a desktop URL security boundary, the cross-cutting capability warrants human review. You can add or adjust custom eligibility rules. Learn more. |
|
Navigate logical layers of code changes, visualize relationships, and explore their blast radius. No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Repository: pingdotgg/t3code/.coderabbit.yaml Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (2)
Included review availability: Your plan provides up to 10 included reviews per hour; 9 remain after this review. 📝 WalkthroughWalkthroughRemote-open targets now support Tailscale SSH when local sshd is unavailable. The flow can include a validated local username in VS Code and Zed links. The remote-open picker and documentation distinguish Tailscale SSH from OpenSSH routes. ChangesTailscale SSH remote-open flow
Priority: ⬇️ Low Estimated code review effort: 3 (Moderate) | ~25 minutes Change: Feature Sequence Diagram(s)sequenceDiagram
participant RemoteOpenTargets
participant TailscaleCLI
participant OpenInPicker
participant buildRemoteOpenUrl
participant ElectronShell
RemoteOpenTargets->>TailscaleCLI: Read SSH setting and MagicDNS status
TailscaleCLI-->>RemoteOpenTargets: Return setting and status
RemoteOpenTargets-->>OpenInPicker: Provide SSH target and optional user
OpenInPicker->>buildRemoteOpenUrl: Build editor URL with target and user
buildRemoteOpenUrl-->>OpenInPicker: Return VS Code or Zed URL
OpenInPicker->>ElectronShell: Open editor URL
ElectronShell-->>OpenInPicker: Accept or reject URL
Merge Risk: ⚪ Minimal · up to No actionable issue is established in the Tailscale SSH remote-open change; it is mergeable after normal checks. Security Architecture ReviewSecurity architecture risk: 🔵 Low · up to The new editor links retain account-name validation and rely on tailnet access and SSH policy. Repeated route discovery may add host load, but no authorization bypass was established. Retained concerns
Security review detailsSecurity Blast Radius
Security Findings and Attack Paths
Trust Boundaries and Controls
Resilience and Maintainability Implications
Hardening Proposals
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Comment |
The one-minute cache kept whatever exit its first caller produced. When a client disconnected during discovery, the cache kept that interruption, so on hosts without sshd every config load for the next minute failed, and so did loads already waiting on the same discovery. Discovery now runs on every config load, as the sshd path already runs `tailscale status`. Clients load config when they connect, so the cache rarely saved a read.
|
Note This comment is posted by Julius' dot Closing for missing UI verification. The real editor checks are useful, but the PR changes the Open menu from “No SSH route” to editor choices with a new Tailscale hint and explicitly says those screenshots are not attached. Please add before/after screenshots of that affected menu, then request reconsideration. |
What Changed
For a remote environment, Open in the chat header hands the local editor an SSH deep link to the host. Hosts that serve SSH only through Tailscale SSH now get that link.
tailscale get --json ssh, which Tailscale added in 1.102. If Tailscale SSH is on, the server advertises the host's MagicDNS name as a newtailscale-sshtarget, with the account T3 Code runs as. It reads this on every config load, as the sshd path readstailscale status. Windows hosts skip the check because Tailscale SSH has no Windows server.RemoteOpenTargetgets thetailscale-sshkind and an optionaluser, limited to portable POSIX account names.buildRemoteOpenUrlputs the login before the host, for examplezed://ssh/user@host/path.user@, the form vscode-remote links already pass. Zed links with a password, a port, or a login that starts with-are still refused.docs/user/remote-access.mdgets a short section on opening remote projects in an editor.Hosts with sshd are unchanged. They advertise the same targets from the same single
tailscale statuscall. Older clients, including the App Store build, drop the unknown kind throughForwardCompatibleArrayand keep showing "No SSH route". The mobile app has no remote open.Why
The server advertises hosts only after an sshd answers on its own loopback port 22. Tailscale SSH never answers there because it serves only tailnet peers. A host that runs Tailscale SSH instead of OpenSSH therefore shows "No SSH route", although VS Code and Zed can connect to it.
Once a link exists, the login decides whether it works. Tailscale SSH signs in as whichever account the client names, and editors send the local account name. From a Windows laptop that is
DOMAIN\user, which the tailnet policy rejects. The server's own account owns the project, so the link names it.UI Changes
For a Tailscale SSH host, the Open menu used to show a disabled "No SSH route to <environment>" item. It now lists the editors, with the Tailscale SSH hint on first use. I haven't attached screenshots of the menu yet. The verification below used real editor windows.
Verification
tailscale getreader, decoding new and malformed targets, the desktop link check, and the link builder. The resolver tests check that sshd output and its single CLI call stay the same, that Windows starts no CLI, that a config load cut off mid-discovery doesn't affect the next one, and that logins a link can't carry are left out. Typecheck, lint, and format pass for the six touched packages.[{"kind":"tailscale-ssh","host":"<machine>.<tailnet>.ts.net","user":"<account>"}]in about 0.3 s.Userentry in its SSH config, and it reached the tailnet through aProxyCommandinto WSL's Tailscale. There the current link failed withtailnet policy does not permit you to SSH as user "DOMAIN\\user". The newvscode://vscode-remote/ssh-remote+<account>@<host>/…andzed://ssh/<account>@<host>/…links opened the project in VS Code 1.139 with Remote-SSH 0.128, and in Zed 1.21.Checklist
Model: Claude Opus 5.5; harness: OpenCode.
Summary by CodeRabbit