Connecting Codex Between Two Windows PCs Over SSH

A configuration record for continuing Codex work from a Windows laptop while using the files and compute environment of a Windows workstation over a private Tailscale network.

Goal and setup

I use a high-performance Windows workstation in my lab and a Windows laptop at home. I wanted to continue Codex work from the laptop while keeping the workstation’s files and compute environment unchanged.

Codex Remote Connections can add an SSH host. I initially assumed that an SSH connection alone would be enough, but a Windows-to-Windows connection required an additional step. SSH authentication worked, but Codex could not start its remote app server. The eventual solution was to change the default shell of Windows OpenSSH to Git Bash.

This is a work record for future setup rather than a general tutorial. The actual computer names, IP addresses, usernames, and SSH fingerprints have been generalized.

  • Client: Windows laptop
  • Remote work environment: Windows workstation
  • Private network: Tailscale, which was already configured for openclaw
  • Transport: Microsoft OpenSSH
  • Authentication: a passphrase-protected ED25519 key
  • Remote runtime: Git Bash and Codex CLI

Network access and OpenSSH Server

I did not expose port 22 to the internet through router port forwarding. Connections between the two computers were allowed only through Tailscale addresses. The Windows Firewall on the workstation allowed TCP port 22 only from the laptop’s Tailscale IP address.

On the workstation, I installed OpenSSH Server in an elevated PowerShell session and configured sshd to start automatically.

  • Add-WindowsCapability -Online -Name OpenSSH.Server~~~~0.0.1.0
  • Start-Service sshd
  • Set-Service -Name sshd -StartupType Automatic
  • In C:\ProgramData\ssh\sshd_config, I limited access to one Windows account and enabled public-key authentication:
  • AllowUsers <WINDOWS_USER>
  • PubkeyAuthentication yes
  • PasswordAuthentication yes
  • Initially, I temporarily left password authentication enabled to install and verify the key.

Firewall rule

Rather than allowing SSH from the whole internet, I allowed only the laptop’s Tailscale IP address.

  • New-NetFirewallRule `
  • -DisplayName "OpenSSH for Codex over Tailscale" `
  • -Direction Inbound `
  • -Protocol TCP `
  • -LocalPort 22 `
  • -RemoteAddress <LAPTOP_TAILSCALE_IP> `
  • -Action Allow
  • A Tailscale device may receive a different IP address when it is re-registered. If SSH suddenly stops working, I would first check the source address in this firewall rule.

A dedicated SSH key and administrator key installation

On the laptop, I created a new ED25519 key specifically for this connection rather than reusing an existing SSH key.

  • ssh-keygen `
  • -t ed25519 `
  • -a 64 `
  • -f "$env:USERPROFILE\.ssh\codex-workstation" `
  • -C "laptop-to-workstation"
  • I set a passphrase. Of the generated files, the file without an extension is the private key. It must not be copied to another computer or posted to a blog, messenger, or repository. Only the .pub file should be transferred to the workstation.
  • If the remote Windows account belongs to the Administrators group, Windows OpenSSH uses the following file instead of the usual ~/.ssh/authorized_keys file:
  • C:\ProgramData\ssh\administrators_authorized_keys

Permissions for the administrator key file

I added the one-line public key from the laptop to administrators_authorized_keys and restricted its ACL. On localized Windows installations, such as Korean Windows, the Administrators group name may be localized, so using the SID instead of the group name is safer.

  • icacls.exe $auth /inheritance:r
  • icacls.exe $auth /grant "*S-1-5-32-544:F" "*S-1-5-18:F"

Laptop SSH configuration

Codex searches for a concrete host alias rather than a pattern entry such as Host *. I added the following to %USERPROFILE%\.ssh\config on the laptop:

  • Host codex-workstation
  • HostName <TAILSCALE_MAGICDNS_NAME_OR_IP>
  • User <WINDOWS_USER>
  • IdentityFile ~/.ssh/codex-workstation
  • IdentitiesOnly yes
  • ServerAliveInterval 30
  • ServerAliveCountMax 3
  • I did not add StrictHostKeyChecking no. On the first connection, I checked that the actual server fingerprint matched the ED25519 fingerprint I had verified beforehand.

Connection checks and ssh-agent

Before adding the host to Codex, I checked Tailscale reachability, port 22, and ordinary SSH access. After connecting, I checked hostname, whoami, where.exe codex, codex --version, and codex login status. The remote PC already had Codex CLI installed and was already authenticated with the ChatGPT account.

  • tailscale ping <REMOTE_HOST>
  • Test-NetConnection <REMOTE_HOST> -Port 22
  • ssh codex-workstation
  • To prevent the Codex desktop app from requesting the key passphrase on every connection, I enabled the Windows OpenSSH Authentication Agent on the laptop and added the key:
  • Set-Service -Name ssh-agent -StartupType Automatic
  • Start-Service -Name ssh-agent
  • ssh-add "$env:USERPROFILE\.ssh\codex-workstation"
  • I then separately confirmed that the connection worked without password fallback:

Key-only authentication

  • ssh `
  • -o BatchMode=yes `
  • -o PasswordAuthentication=no `
  • -o KbdInteractiveAuthentication=no `
  • codex-workstation hostname
  • Only after key-only access succeeded did I back up sshd_config on the workstation and disable password authentication. I checked the configuration syntax and restarted sshd.
  • PasswordAuthentication no
  • & "$env:WINDIR\System32\OpenSSH\sshd.exe" `-t `-f "$env:ProgramData\ssh\sshd_config"","Restart-Service sshd"]},{