Skip to main content

1. Install the daemon

The installer is the normal path. It resolves the latest release, downloads the right Linux/architecture tarball, installs /usr/local/bin/custosd, creates the custos system user, creates /var/lib/custos, writes the systemd unit, and wires sshd’s AuthorizedKeysCommand.
Pin a version:

Self-hosted release artifacts

For a private source repo, publish only the daemon release artifacts to a public static base and point both the installer and the control plane at it:
The base must contain latest.txt plus versioned files such as v1.2.3/custosd_v1.2.3_linux_amd64.tar.gz and v1.2.3/custosd_v1.2.3_checksums.txt. The daemon release workflow bakes this base into dist/install.sh when the CUSTOS_RELEASE_BASE Actions variable is set.

Manual binary download

Downloading the binary alone is for manual testing and debugging. It is enough to run enroll, but it configures neither sshd nor systemd.
If you already have a custosd binary on the host, run the installer step from it directly:
sshd refuses an AuthorizedKeysCommand unless the binary and every parent directory are root-owned and not group- or world-writable. That is why the binary must live in /usr/local/bin and not, say, ~/bin. The installer handles this; a hand-rolled layout has to respect it.

2. Create an enrollment token

As an admin, on the control plane, create a token carrying the Unix accounts this host will manage:
Save the returned token. It is single-use, consumed in the same transaction that creates the host. The accounts you declare here are copied to the host on enroll and stamped into every snapshot it receives.

3. Enroll

This generates the host’s Ed25519 identity key and X25519 encryption key and registers their public halves with the control plane. The private halves never leave the machine.
Do not run this as plain sudo custosd enroll. That writes root-owned state under /var/lib/custos, and the service runs as custos. Always pass an absolute --dir: under sudo, ~ expands to the wrong home and the state ends up unreadable by the run user.
Custos enforces one active host per machine, keyed on a hash of /etc/machine-id. A second enroll from the same machine is rejected with 409 until the existing host is revoked.

4. Start

If sshd was not wired automatically, the installer prints the drop-in config to create manually. After adding it:
Custos writes its drop-in to /etc/ssh/sshd_config.d/70-custos.conf and never edits the main sshd config.

Next