Skip to content

Adding machines

A node package installs the node and asks nothing. Joining it to your fleet is a separate step, the same on every operating system: give the node a join code. You never create files by hand, and the code is never typed on a command line where other programs could read it.

In the console, open Fleet and choose Add machine…. The console shows the code once, with Copy, and under it the installer and commands for each operating system with the code filled in, plus an MDM tab. It then shows the machines that use the code as they arrive.

On the coordinator’s command line:

Terminal window
oarbank join-code --label build-07 # one machine
oarbank join-code --uses 50 --ttl 604800 # up to 50 machines, for a week
oarbank join-codes # outstanding codes and the machines that used them
oarbank join-code revoke <id> # machines that already joined stay
One machine Many machines
For a computer you set up by hand or over SSH MDM, Intune, Ansible, disk images
Uses 1 2 to 10,000
Lifetime 4 hours by default; 10 minutes to 7 days up to 30 days
Approval at once each machine waits on the Fleet page, unless you tick Approve automatically (--approve)
Name the label names the node each node keeps its own name (or the one it asks for with --name)

A code names your coordinator’s addresses and pins its identity key and certificate authority. The node checks both before it sends the code’s secret, so a code cannot be used to join it to anyone else’s coordinator, and a TLS proxy in the way is caught rather than trusted. Expiring or revoking a code never removes a machine that already joined.

By hand: open the .pkg. When Installer finishes, Oarbank Node opens in the menu bar at its join window. Paste the code, choose how the node runs (System service, always on even when no one is logged in, or Only while I’m logged in) and choose Join. The window checks the network and the coordinator and follows the machine until it is connected. Joining as the system service asks for an administrator with the system’s own prompt, which names the app: “Oarbank Node wants to join this Mac to an Oarbank fleet.” (leaving asks the same way). Oarbank Node stays in the menu bar with the node’s status (below).

Over SSH:

Terminal window
sudo installer -pkg oarbank-agent-2.11.1-macos-arm64.pkg -target /
sudo oarbank-node join # prompts for the code, hidden
printf '%s' 'OB2-…' | sudo oarbank-node join --code-stdin # from a script

sudo oarbank-node join sets up the system service; without sudo (or with --scope personal) the node runs for you while you are logged in.

In one line. The installer script picks this release’s package for the computer, checks its SHA-256 against the release’s checksum file and installs it. With the console’s command, which fills in OARBANK_JOIN_CODE, it also joins; otherwise run sudo oarbank-node join afterwards:

Terminal window
curl -fsSL https://github.com/roeehrl/oarbank/releases/latest/download/oarbank-install.sh | sudo sh
curl -fsSL https://github.com/roeehrl/oarbank/releases/latest/download/oarbank-install.sh | sudo sh -s -- --name build-07 --no-join

Piped into sudo sh, the script never asks for the code itself: recent sudo versions run it on a terminal of their own and leave yours echoing, so a pasted code would show on screen. sudo oarbank-node join on its own hides it.

Terminal window
irm https://github.com/roeehrl/oarbank/releases/latest/download/oarbank-install.ps1 | iex

From a link. On a machine that already has the node, the console’s Open in Oarbank Node opens the join window with the code filled in. A code that arrives this way, rather than one you pasted, is always shown with its coordinator first: only continue if it came from your own console.

Without a code. Where you cannot paste, join by the coordinator’s address:

Terminal window
sudo oarbank-node join --coordinator https://coordinator.example.net:7443

The node prints the coordinator’s certificate authority fingerprint (the console shows yours under Approve a machine by its code; they must match), then an 8-letter code such as WDJB-MJHT. Enter it on the Fleet page under Approve a machine by its code, or run oarbank node approve-code WDJB-MJHT.

A machine joined with a code for many machines, or by the coordinator’s address, waits on the Fleet page until you approve it (oarbank status lists it with its enrollment id). Approve… makes it a node that is active with the fleet’s settings. When a machine must start otherwise, choose it in the approval itself (from Oarbank 2.11): open Approve with options… on its card, or give the options on the command line.

Terminal window
oarbank node approve enr_3f2a9c --state paused # joins paused: no jobs at all
oarbank node approve enr_3f2a9c --module-off bench --set max_slots=4 --labels lab --groups "Build machines"
oarbank node approve-code WDJB-MJHT --state paused --module-off bench
Option Console What the node starts with
--state active|paused|draining It starts Paused takes no jobs, certification golden jobs included, and runs no workloads until you resume it
--module-off <m>, --module-on <m> Modules on this node Whether each module runs on this node (its own value of enabled)
--set key=value, --set <module>:key=value Its own settings, one key=value per line Any setting a node may have, checked as oarbank settings set --node checks it
--labels a,b, --groups g1,g2 Labels, Groups that list it Labels and owner groups, so group values apply from the start

The options are written in the same step that creates the node and issues its certificate. The machine cannot fetch its certificate before that step completes, so it never runs with the fleet’s defaults, not even for a moment. A machine that must run nothing can be approved paused, with its modules off, and certifies nothing until you resume it or turn a module on. Review… (and the command’s preview) shows what the node will start as before anything changes. If an option is refused (an unknown setting, a value out of range, a lock, a group that does not exist), the approval is refused too, and the machine keeps waiting.

To make this the default for every new machine, set what new nodes start as for the whole fleet. Join codes that approve automatically follow it too:

Terminal window
oarbank settings set new_node_state paused # active (the default) or paused
oarbank settings set new_node_modules none # all (the default) or none: every installed module off on the node

An approval’s own options take precedence over these settings. A machine that proves it is a node you already have (re-added to the tailnet, with its own key) keeps that node’s settings.

A reinstalled machine has a new key, so it cannot prove it is the node it was. Its card says “new node looks like build-07 … approving makes a NEW node, and that node’s settings do not apply to it”. If you know it is the same machine, tick This is the same machine: carry over its settings and retire the old record in Approve with options…, or:

Terminal window
oarbank node approve enr_3f2a9c --adopt-settings-from build-07

The new node gets the old node’s own settings (module switches, caps, protection, update hold and pin), its state, labels, groups, module version pins and site. The old record is retired, in one step that the audit log records. You type the old node’s name to confirm. Nothing of the old node’s credentials or secrets is carried over: set its secrets again. Oarbank never does this by itself. It refuses while the old node is still online, and for a machine that proves another node’s key, which keeps that node or is rejected.

Deploy the package unchanged and hand the code out through managed policy. A node that has not joined reads the policy and joins as the system service. Use a code for many machines; its machines wait for your approval on the Fleet page unless you ticked Approve automatically.

Key Type Meaning
JoinCode string The join code
Coordinator string Join by address instead; approve each machine on the Fleet page
Name string The node’s name
Containers boolean (Windows: DWORD 1) Install the container prerequisites (Windows)
AllowUserJoin boolean (DWORD 0) false hides Join and Leave in Oarbank Node
ManagedByOrganizationName string Shown in Oarbank Node and oarbank-node status
ShowStatusIcon boolean (Windows: DWORD) false hides Oarbank Node’s menu bar (macOS) or notification-area (Windows) icon on every account and keeps it from opening at login; true keeps it shown. Set either way, the app’s own setting is greyed out (“Managed by …”). No effect on Linux or on the node itself. 2.9 and later
Settings dictionary (Windows: the Settings subkey) Settings that may only be made stricter on this machine, never looser: see Managed on this machine. 2.9 and later

A managed node is always the system service, and policy values are never logged. On the node, oarbank-agent policy prints what the machine’s policy sets; a join code shows as (set), never its value.

Deploy the .pkg and a configuration profile with these keys for the preference domain dev.codonic.oarbank.agent. Add machine… offers a ready .mobileconfig: it holds the code and also pre-approves the node’s background items, so the person at the Mac sees no “Background Items Added” prompt. The profile can arrive before or after the package. Managed preferences are readable by every account on the Mac, so use a code for many machines with approval, not one that approves automatically.

Re-running a join on a machine that has joined the same coordinator does nothing and succeeds, so configuration management can apply it on every run.

The node itself is a service that starts with the computer, before anyone signs in. Oarbank Node only shows it, and never stops it: there is no “Quit” that would read as stopping the node.

macOS Windows
The one setting Show Oarbank Node in the menu bar Show Oarbank Node in the notification area
On (the default after the app first opens) the item is shown, and the app opens at login the icon is shown, and the app starts at sign-in
Turned off by Hide from Menu Bar (⌘Q; the menu says “This Mac’s node keeps running” and asks first), or the setting Hide from notification area (“This PC’s node keeps running”; asks first), or the setting
Back on open Oarbank Node from Applications or Spotlight: its window has the setting start Oarbank Node from the Start menu
Managed ShowStatusIcon decides, and the setting is greyed out ShowStatusIcon: 0 never shows the icon (a Start menu start only opens the join window); 1 keeps it

The window (Settings… in the menu) shows how the node runs (“Running as a system service — starts with the Mac, before anyone signs in, and keeps running when this app quits”), its state (connected, not joined, waiting for approval) and the menu bar setting. The node’s glyph is one oar; the coordinator’s is three.

  • One item per Mac. On a Mac that also runs Oarbank Coordinator, the coordinator’s menu shows This Mac’s Node and Oarbank Node shows no item of its own (The coordinator service).
  • Allow in the Background. In System Settings, General → Login Items, the node’s background items are listed under Oarbank Node. If they are switched off there, nothing of the node starts; the window says “The node is turned off in Login Items → Allow in the Background” and offers Open Login Items… to switch it back on. The console’s .mobileconfig pre-approves these items.
  • Linux has no node tray: Oarbank Node in the applications menu opens the join window and never starts at login.

oarbank-node status (with --follow to watch, --json for scripts) and Oarbank Node read the node’s status document: /Library/Application Support/Oarbank/status/node.json (macOS system service; the personal node keeps its own under ~/Library/Application Support/Oarbank/status/), /var/lib/oarbank/status/node.json (Linux), C:\ProgramData\Oarbank\status\node.json (Windows). It holds no secrets.

State Meaning
unjoined Installed; waiting for a code (or managed policy)
joining Checking and joining
pending Waiting for approval on the Fleet page
joined, connected Joined; connected to the coordinator
offline Joined, but the coordinator cannot be reached now
error Joining failed; the error says why

oarbank-node check runs the checks without joining, and oarbank-node leave makes the node forget its coordinator.

Every failure names its check and a code. The join window shows the same message with Retry and Copy diagnostics (a report without the code).

Code What happened What to do
E_CODE_FORMAT The text is not a complete join code Copy it again from the console
E_CODE_EXPIRED The code expired Make a new one
E_CODE_USED Already used, or no uses left Make a new one
E_CODE_REVOKED Revoked in the console Make a new one
E_CODE_UNKNOWN The coordinator does not know the code Check it came from this coordinator
E_DNS The coordinator’s name does not resolve Check the machine’s network and DNS
E_TCP No answer on the coordinator’s port Check the coordinator is running and a firewall allows outgoing 7443/tcp; the node keeps trying until the code expires
E_TLS_PIN_MISMATCH The certificate authority is not the one the code pins A TLS-inspecting proxy is in the way, or the code is for another coordinator; there is no way to skip this check
E_IDENTITY The server is not the coordinator that made the code As above
E_CLOCK_SKEW This computer’s clock is more than 5 minutes off Turn on automatic time and retry
E_NOT_ACTIVE The address answers with a standby coordinator Retry in a few minutes
E_APPROVAL_DENIED You declined the machine Make a new code if that was a mistake
E_ALREADY_JOINED The machine belongs to another coordinator oarbank-node leave first, or join --force

oarbank-node join exits with 0 joined (or already joined to this coordinator), 2 malformed code, 3 still waiting for approval, 4 code expired, used, revoked or unknown, 5 identity or certificate authority mismatch, 6 network (worth retrying), 7 joined to another coordinator, 8 needs root or an administrator.