Skip to Content
GuidesFleetsMulti-fleet setup

Multi-Fleet Setup

Many CMDOP users belong to two or more fleets — personal plus employer, or staging plus production. CMDOP keeps them fully isolated and lets you switch context per call or globally.

Why two fleets

Common patterns:

  • Personal + employer — keep personal experiments off the work bill.
  • Staging + production — separate machines, separate API keys, separate audit.
  • Client A + client B — agency / consulting setups.

Fleets are the strongest isolation boundary in CMDOP — machines, members, sessions, API keys, and audit do not bleed across.

Listing what you have

cmdop connect --list

--list shows the machines in the active fleet. The fleets you belong to (and their masked API keys) are stored locally in ssh_workspaces.json.

Adding a fleet via API key

Provide the fleet’s API key per call with the --api-key / -k flag, or process-wide via the CMDOP_API_KEY environment variable:

export CMDOP_API_KEY=cmd_acme_xxx cmdop connect --list

Once resolved, the key is cached in ~/.cmdop/ssh_workspaces.json (mode 0600).

Adding fleets via OAuth

cmdop login # device flow

OAuth tokens carry your fleet membership. After login, every fleet you belong to lands in ssh_workspaces.json with a RemoteID and a LastSyncedAt timestamp on the next connect.

Switching the active fleet

There is no cmdop connect workspace verb. The active fleet lives in ssh_workspaces.json under "active"; to change it, re-authenticate against the account that owns the fleet you want, or pin a fleet per call with the --workspace flag (the flag keeps its legacy name):

cmdop --workspace=acme-prod connect prod-1 exec 'uptime'

Do not mutate the fleet ID manually — the auth manager owns the WorkspaceID field. See Concepts: daemon for the connection flow.

Per-call override

Override mechanisms, in resolver order:

  1. --api-key=<key> flag.
  2. CMDOP_API_KEY environment variable.
  3. --workspace=<name> flag (uses the named fleet’s stored key).
  4. (no flag) — active fleet from ssh_workspaces.json.
  5. Legacy cfg.Chat.GrpcAPIKey — one-shot migration.
  6. OAuth access token — fallback.

Useful in scripts that target multiple fleets from one host.

Server-side fleet migration

When an OAuth user switches fleets in the cabinet, the server auto-migrates the machine record using the live workspace_id in the token. Your client keeps doing what it does — reconnects pick up the new ID. This is invisible to scripts; it just works.

Per-fleet gRPC server override

Fleets can pin to custom gRPC endpoints (on-prem, staging). The Workspace.Server field overrides the default endpoint just for that fleet; set it when issuing the fleet’s API key entry.

OAuth-managed fleets and API-key fleets coexist. The resolver prefers explicit (--api-key / env / named) over implicit (active / OAuth).

Sessions on fleet A are not visible from fleet B. Switching mid-task closes your current view — finish your work before switching, or open a second terminal with --workspace=other.

Worked example

# One-off command on a staging machine without changing the active fleet cmdop --workspace=acme-staging connect prod-1 exec 'uptime' # List the machines in the active fleet cmdop connect --list # prod-1, prod-2, db-1, edge-{us,eu,ap}

Sample ssh_workspaces.json

{ "active": "acme-prod", "workspaces": { "personal": { "name": "personal", "api_key": "**REDACTED**", "remote_id": "wks_01HABCDEF", "added_at": "2026-01-12T08:00:00Z", "last_synced_at": "2026-04-25T09:14:22Z" }, "acme-prod": { "name": "acme-prod", "api_key": "**REDACTED**", "server": "grpc.cmdop.com:443", "remote_id": "wks_01HZZZZZZ", "added_at": "2026-02-03T11:22:00Z", "last_synced_at": "2026-04-25T09:14:22Z" } } }
Last updated on