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.
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
- One machine generates a short pairing code. The other machine enters it.
- 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.
- 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.
- 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.
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
501with{ "error": "peering not installed" }. - The one exception is the machine roster (
GET /api/fleet/machines/ thelist_machinesMCP 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
- Grants & consent — decide what a paired machine can actually do once it's trusted.
- Fleet commands — route agent commands to a paired machine.