Skip to main content

Pairing Machines

Pairing is how two TermFlow instances agree to trust each other. It's managed entirely from Settings → Peers — there's no separate account, server, or relay to set up.

Pro feature

The Peers panel carries a Pro badge. If the peering component isn't installed, the panel reads "Peering is not installed" instead of showing pairing controls — see What "not installed" means below.

The pairing flow

  1. One machine generates a short pairing code. The other machine enters it.
  2. The two instances run a SPAKE2 password-authenticated key exchange using that code — the code itself is never sent over the wire, only proven knowledge of it.
  3. A successful exchange pins a per-device identity for each side. From then on, the two instances recognize each other and communicate over mTLS — the pairing code is not needed again.
  4. Each peer's OS (windows | macos | linux) is captured at pairing time and stored as part of its identity. It is immutable — if a peer's OS ever needs to change, that peer has to be re-paired.

Because the exchange is password-authenticated, the pairing code only needs to be exchanged once, briefly, and doesn't need to stay secret afterward — the mTLS identity pinned in step 3 is what secures every later connection.

The Peers panel

┌─ Peers ──────────────────────────────────────────────────── Pro   [Refresh] ┐
│ Pair this TermFlow instance with others on your local network. │
│ │
│ ┌ Pair a new machine ──────────────────────────────────────────────────┐ │
│ │ Enter a pairing code from another machine: │ │
│ │ [ ______ ] [ Pair ] │ │
│ │ Or generate a code here for another machine to enter: │ │
│ │ [ Generate pairing code ] │ │
│ └────────────────────────────────────────────────────────────────────┘ │
│ │
│ ┌ Paired machines ─────────────────────────────────────────────────────┐ │
│ │ ● online mac-mini-studio macos [Grants] [Allow fleet: ⬜] │ │
│ │ ○ offline win-dev-box windows [Grants] [Allow fleet: ✅] │ │
│ └────────────────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘

Each row in Paired machines shows the peer's online/offline status, its device name, its OS (fixed at pairing), a Grants control for per-terminal View/Control access (see Grants & consent), and the per-peer Allow fleet commands toggle.

Adding and approving a peer

  • On the machine that will receive the connection, click Generate pairing code and share the code with whoever is pairing the other machine (verbally, over chat — it's short-lived and single-use by design).
  • On the other machine, enter that code under Pair a new machine and submit.
  • Once the SPAKE2 exchange succeeds, the peer appears in Paired machines on both sides immediately — pairing is mutual, there's no separate "approve" step after the code exchange completes.
  • A paired machine stays listed (as online or offline) until it is explicitly unpaired.
Same LAN required

Pairing and all subsequent peer traffic happen over your local network. There's no cloud relay — if a paired machine isn't reachable on the LAN, it shows as offline and any Fleet request targeting it fails to find it.

What "Peering is not installed" means

Peering ships as a separate, source-available component on top of the open-core app — it is not compiled into every build. If that component isn't present:

  • The Peers panel shows "Peering is not installed" instead of pairing controls.
  • Every remote Fleet operation (routing a command to a peer, reading a peer's screen, closing a peer's terminal) returns HTTP 501 with { "error": "peering not installed" }.
  • The one exception is the machine roster (GET /api/fleet/machines / the list_machines MCP tool) — it still succeeds and returns just self, so tooling built against the fleet roster doesn't have to special-case an unlicensed install.

See Fleet API & MCP for the full error-code reference.

Next steps