What a Node Is
A node is any machine that runs agents on the control plane's behalf, and what enrolling one actually delegates.
A node is a machine that runs agents for you. It is a machine running the subshell node daemon and nothing else: no UI, no database, no opinions. The control plane keeps the web interface, the database, the decision logic, and the terminal transport; the node just executes. Your control-plane host runs agents too if you let it, but then it is also a node, and this documentation says so.
The point of a node is that a subshell can live anywhere you own and look the same from anywhere you are. The browser cannot tell a remote pane from a local one: the control plane relays the same replay, resize, and keystroke frames either way, so xterm.js cannot tell whether the bytes came from tmux on the plane's host or on a machine in another room.
What enrolling one actually delegates
Read this before you add your first node. Registering a machine hands this control plane the right to run arbitrary commands on it, under the OS user the node runs as. That delegation is the feature (the plane launches tmux, writes files the launch needs, and reads back what the harnesses report), but it means:
- Whoever owns that OS user owns every pane launched there: its files, and the subshell's bearer token, which rides in the launch command's arguments and is visible to any local process that can read
psoutput. - The control plane's command-signing keypair rules every enrolled node. A control-plane compromise is a compromise of all of them at once.
- A node's own bearer key is narrow on purpose: it can do nothing on the REST API. Its entire reach is impersonating that one node on its WebSocket.
The wire, in one paragraph
The link is dialed out by the node: the control plane never connects to a node, which is why nodes work behind NAT and on laptops. Commands travel plane → node as signed envelopes; the node verifies every one before executing anything, so a compromised relay cannot forge work for it. Events travel back unsigned, because the node key on the socket already authenticates them. Signing proves who sent a command, when, and which node it is for, never confidentiality. Node traffic is authenticated, not encrypted: keep it on the same VPN or tailnet as everything else, or terminate TLS in front. (The protocol reference is the full contract; the security consequences are documented in the repository's threat model.)
An offline node is never treated as crashed: launches onto it are refused while its row keeps its history, and the UI says "node unreachable", not "failed".
The machine that hosts the control plane
Your control-plane host appears in the Nodes list as a node of its own: the row an admin names, defaulting to Server. It is definitionally always online, never runs a node daemon, and is managed through the server's own settings pages rather than the per-node controls, which refuse it by design because it is the same machine as the plane.
This section
- Adding a Node: mint a setup key, run the one-liner, go online.
- Subshell Client as a Node: the same thing without a terminal, from the desktop app.
- Sharing a Node: who may launch on your machine, and what each grant really confers.
- Directory Allowlist: restrict where subshells may start on a node.
- Maintenance Mode: take a machine out of service without unenrolling it.
- Managing a Node: restarts, logs, debug logging, and repointing from the browser.
- Updating a Node: move a node to a newer binary, and what rollback means there.
See also
- How It Works: where the node fits in the whole system.
- Security Model: the trust posture this section assumes.
- Supported Platforms: which machines have published node binaries.
Last updated on
