SSH ControlMaster desktop evidence

Environment for all captures: Linux x86_64, Electron 44.10.1, headless-desktop (Xvfb 1920x1080); app viewport 1100x780, light theme. Each commit was built using vp run build:desktop in a separate worktree. Vite ran separately with vp run dev:web; Electron launched with --no-sandbox --disable-gpu, its own T3CODE_HOME, XDG_CONFIG_HOME, and backend port. T3CODE_DEV_SEED=0 was set. No production database was copied. Both began with no saved remote environments. The remote host was a local isolated OpenSSH server, not a real Duo service.

Base: d91915db9e36b03450aa7d6dbd35ff27cb027ffe
Head: 8b760926d3912b59aeec80212443c21bdd6e684b

The fixture used an isolated mount namespace with copies of passwd, ssh_config, and the sshd PAM service file bind-mounted inside that namespace only. Synthetic proofuser uses a scratch home and the current user's numeric UID/GID. No real account or SSH configuration was modified. The attached fixture-pam.c requests a password and a separate one-time-code-style keyboard-interactive response. This is a deterministic simulated second factor (123456), not expiring Duo authentication. Build with gcc -shared -fPIC fixture-pam.c -o pam-proof.so -lpam.

sshd configuration:
  Port 22229
  ListenAddress 127.0.0.1
  HostKey <scratch>/hostkey
  UsePAM yes
  KbdInteractiveAuthentication yes
  PasswordAuthentication no
  PubkeyAuthentication no
  AuthenticationMethods keyboard-interactive
  AllowUsers proofuser
  AllowTcpForwarding yes
  StrictModes no
  PrintMotd no

PAM configuration (inside namespace):
  auth required <scratch>/pam-proof.so
  account required pam_permit.so
  session required pam_permit.so

SSH configuration (inside namespace):
  Host proof-otp
    HostName 127.0.0.1
    Port 22229
    User proofuser
    ControlMaster auto
    ControlPath <scratch>/master.sock
    ControlPersist 600
    StrictHostKeyChecking no
    UserKnownHostsFile <scratch>/known_hosts

Run ssh -M -N proof-otp in a terminal inside the namespace. Enter synthetic password proof-password and code 123456. Keep the master running. ssh -O check proof-otp must report it running.

The remote scratch home had a Node 26 runtime on its private .local/bin PATH. Electron's T3CODE_DEV_REMOTE_T3_SERVER_ENTRY_PATH pointed to the corresponding worktree's built apps/server/dist/bin.mjs. Thus the actual remote T3 server was launched over SSH; no fake server or mocked tunnel was used.

Both runs: Settings > Environments > Add environment > SSH; enter proof-otp, leave username/port unset so SSH config resolves them; click Add environment. evidence-driver.mjs is the portable version of the same CDP driver (set EVIDENCE_CHECKOUT and EVIDENCE_OUTPUT). Base CDP port 9332; head 9331. Videos begin at the Environments page. Preparation/navigation happened before recording.

Base: another SSH verification prompt appeared. After the driver observed this, two password submissions were made with xdotool type proof-password followed by Return. Each fresh authentication supplied the same cached response to both PAM challenges, so the code challenge failed. The final Add Environment dialog displayed Permission denied (keyboard-interactive). Head: connected directly, with no new verification prompt.

After head connected, the environment switch was turned off. A real TCP connect to its recorded local forward port succeeded before switching off and failed with ECONNREFUSED afterward. ssh -O check still reported the original master running. The disconnect video shows Connected changing to Off. The attached transcript records the socket probe.

Evidence processing: each still was accepted only after two screenshots 500 ms apart were byte-identical. Recordings are real-time 15 fps screen captures cropped to the app window. Tail waiting was trimmed (base 85 s; head 25 s; disconnect 12 s). The generated host label is covered by an explicitly labeled privacy redaction in head captures; SSH address and connection status remain visible. No outcome UI was altered.

AI-assisted; verified with the tests and tools listed above.
