Repository navigation
fix(ssh): turn a host's orca CLI control on by default and stop resetting saved choices - #29856
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Priority: ➖ Normal Merge Risk: ⚪ Minimal · up to
|
…p resetting saved choices An absent allowRemoteCliControl now means on; only an explicit false turns the desktop browser bridge and relay-era orchestration commands off. Removes the one-time reset of saved true values, the consent stamp writes and the reset notice, which would have silently turned off hosts upgraded from stable.
…bridge candidates
878fc14 to
5edb214
Compare
ELI5
Each SSH host has a switch, "Allow this host's orca CLI to control Orca". Until now it was off unless you had turned it on recently, and on the next start Orca turned off every host where it had been saved on by an older version. People upgrading from the stable release (1.4.227), where "on" meant the host's terminals could run orchestration commands, would have lost that without being told. Now the switch is on by default, a saved "on" stays on, and only an explicit "off" turns it off.
What Changed
Before: a host with no saved value was off. On load, a saved
truewithout the new consent stamp was turned off, and the settings page showed a notice saying Orca had turned it off.After:
isRemoteCliControlAllowed(src/shared/ssh-remote-cli-control.ts), is now used by both gates: the desktop browser bridge's choice of which managed hosts may attach (desktop-browser-bridge-wiring.ts), and the relay-era CLI server's admission check (legacy-relay-bridge-ipc.ts). An explicitfalseis refused at both. A host that has been removed is refused.normalizeRemoteCliControlConsent), the consent stamp written on save, and the reset notice (with its strings in every locale) are gone. A strayallowRemoteCliControlResetflag from an earlier build is dropped on load, so a host that build reset comes back on. The oldallowRemoteCliControlConsentfield is still in the type and is left on disk untouched, but nothing reads it. Leaving it means a downgrade to a build that checks it does not reset a host it already stamped.trueorfalse. The advanced section only opens on its own when the switch is off, since off is now the non-default value.ssh.listEditableTargetsnow returns the value that actually applies (absent is listed astrue).ssh.addTargetandssh.updateTargetsave a missing value asfalse. Older clients leave the field out when their switch shows off, so this keeps what they save meaning what they showed. Current clients always send a boolean.Unchanged: orchestration stays behind the same switch. The caller scope, the identity and pane binding, the per-host concurrency cap, timeouts, aborting in-flight calls when the switch turns off, and the target-scoped lookups from #29571/#29596 are all as they were. Only the default and the reset changed.
Why
This is the user's decision, made to keep the SSH upgrade smooth. It matches what VS Code Remote, paseo and superset do: a host you connect to can already run code as you in its own workspaces. The alternatives were to keep off as the default and only drop the reset (stable users would still lose relay-era orchestration, because stable never saved the stamp), or to add a separate opt-in for orchestration (more switches, and the same upgrade break).
Security note
What a compromised SSH host can now do by default, with no action from the user:
file://or the clipboard, cannot download files to this desktop, and cannot choose the profile, focus or placement of a tab. Every forwarded command is written to the audit log. These are the same limits fix(ssh): agents on a managed SSH host can drive the desktop Orca browser again, behind the per-host switch #29384 put in place for when the switch is on.It still cannot read the desktop's files, clipboard or cookies outside that host's partition. Turning the switch off detaches the bridge at once and cancels in-flight relay CLI calls. This matches the trust model of VS Code Remote, paseo and superset, where a connected host is trusted inside its own workspaces.
Linked Issue
Refs #29145, #29384, #29571, #29596
Visual Proof
N/A for screenshots: the only UI change is the switch's default value, the help text, and removing the reset notice. The live run below saved screenshots of the host driving a desktop tab with the switch at its default, and of it being refused once the switch was off.
Testing
Unit tests (each failed before this change where it covers the new default):
src/main/ipc/desktop-browser-bridge-wiring.test.ts(new): the browser bridge attaches a host with no saved value or an explicit true, and never an explicit false.legacy-relay-cli-server.test.ts: the relay CLI server admits no saved value or an explicit true, and refuses an explicit false withLEGACY_RELAY_CLI_CONTROL_OFF.legacy-relay-cli-call-limits.test.ts: turning a default-on switch off at runtime still cancels a waitingcheck --wait.ssh-normalization-remote-cli-control.test.ts(replaces the consent test): a saved true is kept on load (no reset), false stays false, absent stays absent and is allowed, and the retired reset flag is dropped.ssh-connection-store.test.ts: saves the switch as given, with no stamp.ssh-target-save-payload.test.ts,add-remote-host-ssh-actions.test.ts: settings and sidebar save explicittrue/false, and an absent value shows as on.ssh-target-management.test.ts: over RPC, an older client's missing value is saved as off, and the list shows the value that applies.tests/e2e/ssh-orcad-desktop-browser-bridge.spec.ts: now checks that the host works with no saved value and is refused, with the setting's name, after the switch is set to false.Local gates: every step of the "static analysis and typecheck" job (lint, anti-slop, code-quality plugins, type-aware lint, changed-code quality, React Doctor, typecheck, the ratchets including focus-read, the localization extraction, catalog and coverage checks, the RPC catalog). Unit folders:
src/renderer/src/components/settings,src/renderer/src/components/sidebar,src/main/runtime/rpc/methods,src/main/ssh/legacy-relay-bridge,src/main/persistence/leasing-ssh-ptys.Verified live (macOS desktop, Linux host): an isolated desktop built from this branch (e2e session with its own user data,
ORCA_BACKGROUND_LAUNCH=1, no visible window) on an M-series Mac. The host was omarchy (x86_64 Linux), reached through anssh -Ltunnel to a private user-level sshd that ran with a throwawayHOMEand XDG dirs under/tmp. The desktop deployed a real managed orcad there, built from this branch forlinux-x64-glibc. The run used a local copy of the browser-bridge e2e flow, pointed at that host instead of Docker, and did not modify the shipped spec. It confirmed:allowRemoteCliControlvalue (undefined).orcaCLI rantab create,goto,snapshot,tab listandtab closeagainst a desktop browser tab in the host's workspace.file://was refused withinvalid_argument.allowRemoteCliControl: falsewas saved, the host was refused withdesktop_browser_bridge_unavailable, and the error named the setting.All test processes and directories on both machines were removed afterwards. Only in tests: the relay-era orchestration path (relay CLI admit, refuse and runtime abort), the no-reset load, and the mixed-version RPC mapping.
Review
Codex (
gpt-6.1-sol, high effort), three rounds:Agent skill upstream boundary
Notes
Mixed versions: a new client talking to a server from before this change sees a host with no saved value as on, while that server still treats it as off. That errs in the safe direction (the host gets less access than shown), and the next save from the new client writes an explicit value. Folder workspaces and git worktrees are affected the same way. No platform-specific code.
Checklist
N/Awith reasonpnpm lint,pnpm typecheck,pnpm test, andpnpm buildpass (or CI will cover; local preferred)