Skip to Content
ConceptsFleets

Fleets

A fleet is the tenant boundary in CMDOP. It owns machines, sessions, members, and API keys. Every gRPC call is tagged with a fleet ID; every credential is scoped to one.

What is a fleet?

A fleet is a logical isolation domain. Members of one fleet cannot see the machines or sessions of another. API keys are fleet-scoped. OAuth tokens carry the active fleet in their claims, so the same human identity can move between fleets by switching the active selection.

What lives inside a fleet

ResourceScope
MachinesHostname unique per fleet
SessionsOnly visible inside the owning fleet
API keysOne fleet each
MembersPer-fleet role (Owner / Admin / Member / Guest)
Audit logsSeparated by fleet
BillingPer fleet

Hostnames are unique inside one fleet; the same hostname can exist in two different fleets independently.

Fleet identity on the wire

Every gRPC call from a CMDOP client carries a workspace_id in metadata (the wire field keeps its legacy name). The daemon reads its WorkspaceID from the auth manager once at connection setup (auth.Manager.GetStatus()connection.Config.WorkspaceID). The relay uses that ID to authorise inbound calls and route between agents.

How the CLI authenticates

The CLI authenticates to a fleet through OAuth only. Running cmdop login performs a browser device flow and stores the resulting access token in the OS keyring (with an encrypted-file fallback on headless hosts). Every cmdop connect call resolves that token automatically.

There is no local API-key file (ssh_workspaces.json is gone), no --api-key flag, and no CMDOP_API_KEY environment variable. The credential resolver has a single real source — the OAuth token from cmdop login — and returns “not signed in” when none is present. See Credential resolver for the full detail.

API keys still exist as a server-side, fleet-scoped concept (issued and managed in the web cabinet, used by integrations against the REST API), but the CLI itself does not read or store them.

Switching fleets

There is no cmdop workspace verb and no cmdop connect workspace subcommand. Your fleet membership is carried in the OAuth token. To change the active fleet, re-authenticate against the account that owns it:

# OAuth tokens carry fleet membership; a fresh login refreshes the stored list cmdop login

After a fresh login the active fleet is updated automatically on the next connect.

Changing the active fleet causes the daemon to drop and re-establish its relay connection. Sessions on the old fleet are not visible from the new one.

OAuth fallback and server-side migration

When a human OAuth user switches fleets in the dashboard, the server auto-migrates their machine record from the old fleet to the new one using the live workspace_id in the token. The client keeps doing what it does — the next reconnect picks up the new ID without manual intervention.

A server-side API key (issued in the cabinet, used by REST integrations) is fixed to the fleet it was issued for. An OAuth identity, by contrast, follows the active fleet you select in the dashboard:

  • API key → fixed fleet, set when the key was issued.
  • OAuth → fleet follows the dashboard selection.

Roles and access

Per-fleet roles, managed through the web cabinet:

RoleManage billingDelete fleetManage membersManage machinesUse sessions
Owneryesyesyesyesyes
Adminnonoyesyesyes
Membernonononoyes
Guestnonononoobserver-only

Member management lives in the web cabinet today — there is no CLI to invite or revoke.

Per-fleet server override

The Workspace.Server field allows pointing one fleet at a custom relay endpoint (on-prem deployments, staging). Most users never set this; the default points at the managed relay.

Examples

# sign in (OAuth device flow); the token carries your fleet membership cmdop login # run against a machine in the active fleet cmdop connect exec prod-1 -- uptime

Your OAuth identity is scoped to one active fleet at a time. To work in fleet B, switch the active fleet in the dashboard and re-run cmdop login.

TAGS: fleets, multi-tenant, oauth, api-key DEPENDS_ON: [machine-identity, daemon, permissions]

Last updated on