feat(desktop,cli): switch to let your cloud workspaces reach a host
Merged
HA
2d ago+662+662+012345678901234567890123456789-1-1-0123456789
Stack: 3 of 3 — #9407 (DB) → #9408 (API + relay) → this PR. Merge after #9408, once the API is live.
Summary
- Desktop: Settings → Hosts → [host] → Cloud workspaces switch, shown to the host's owner on every host they own. It sits behind a confirm dialog that spells out the risk. Nothing restarts.
- CLI: from a cloud workspace,
--hostcalls go to the relay with no bearer, so the firewall-added workspace credential is what gets checked. Before, it sent an emptyBearer, which the relay rejected and the CLI showed as "Session expired".
How It Works
- The switch reads
allowCloudWorkspacesfromhost.roster(defaults tofalseif the API is older) and writes it withhost.setCloudWorkspaceAccess, then invalidates the roster. - It's owner-only, so the owner can open a machine they aren't sitting at. Non-owners don't see it.
- The CLI only drops the
Authorizationheader when the bearer is empty. That happens only in a cloud workspace.
Manual QA (dev desktop over CDP, real clicks)
- Settings → Hosts → this host shows the "Cloud workspaces" section, switch off, for the owner
- Toggle on → dialog → Allow → "Setting saved"; a box call now returns 200
- Toggle off → dialog → Turn off → the next box call is refused (403)
- Host-service processes kept running through both toggles (same pids, uptime kept counting)
- Not verified: the desktop
typecheck(killed by the sandbox memory guard; CI is the first run)
Testing
bun testinpackages/cli(482, including a test that a cloud workspace's relay call carries noAuthorization)bun testfor desktop settings routes (107)bun run typecheckinpackages/clibun run check:i18n(7 new strings, translated in all locales)
Compatibility
- Reads a new output field and calls a new procedure, so it needs #9408 live first (
packages/trpc/AGENTS.mdrule 9). - The CLI change is safe against any relay: an older relay still answers 401.
- Boxes on CLI 2.0.3 already work against the new relay, because an empty bearer is treated like none.
Rollback
Revert this PR. The switch disappears; hosts already opened stay open until the column is set back.
Summary by cubic
Lets host owners allow their cloud workspaces to reach a host they own, and fixes the CLI so those calls succeed instead of failing with "Session expired". The switch needs the merged #9408 API and relay live; older relays still answer 401, so the CLI change is safe on its own.
New Features
- Settings → Hosts → [host] shows a "Cloud workspaces" switch for the host's owner, guarded by a confirm dialog that spells out the risk. It's discoverable via Settings search, surfaces the server's localized errors, keeps a steady dialog text while closing, and drops a pending confirmation when switching hosts or organizations.
- The switch reads
allowCloudWorkspacesfrom the roster and writes it viahost.setCloudWorkspaceAccess; no host services restart.
Bug Fixes
- When the bearer is empty (cloud workspaces carry no user token),
--hostcalls no longer send an emptyBearerheader, so the relay checks the firewall-added workspace credential instead of rejecting the request.
Summary by CodeRabbit
- New Features
- Host owners can manage whether cloud workspaces may access their host through the relay. Changes require confirmation, with loading, success, and error feedback.
- Confirmation prompts explain that access can allow cloud workspaces to create workspaces, start agents, and run commands on the host.
- Added searchable settings and localized interface text for this access control.
- Bug Fixes
- Remote host requests no longer send an empty authorization header.