Tutorial For: administrators

Install from an offline depot

Install a Kyvernon controller and a first host from a verified offline depot on servers without internet access.

This guide installs a Kyvernon controller and a first host on Debian 13 or Ubuntu 26.04 servers that have no internet access. Everything comes from one directory, the depot, that you receive on a USB stick, a DVD or a file share. The guide to the first sign-in (First sign-in) continues where this one ends.

Before you start

  • Two Debian or Ubuntu servers (or one for a first try): one for the controller, one host with virtualisation support (/dev/kvm present). The host needs the distribution packages qemu-utils, ovmf and swtpm; a depot may carry them in deps/.
  • The depot directory kyvernon-<version>/ and, separately, the release public key of Kyvernon, which you obtain from Kyvernon and not from the depot. The installer does not accept the key from the depot itself (the copy under keys/ is only there for comparison): the point of the signature is that the depot cannot vouch for itself.
  • Root access on both servers.

1. Verify the depot

Copy the depot onto the server, then verify it as a normal user:

Shell
cd kyvernon-0.1.0
./kyvernon-install --verify-only --pubkey /path/to/release-signing.minisign.pub

The script checks the signature over the index (depot.json), then the checksum of every file, and refuses a directory with files that the index does not list or with symbolic links. When it installs, it hands dpkg its own verified copies of the packages, not the files in the depot directory. It prints depot ok on success; on any other output, stop and contact your supplier. If you prefer the standard tool: minisign -Vm depot.json -p release-signing.minisign.pub verifies the same signature.

2. Install the controller

Shell
sudo ./kyvernon-install --role controller --pubkey /path/to/release-signing.minisign.pub

This installs kyvernon-controller and the command-line client kyvernon-cli. No service is started yet. Then:

  1. Write the configuration from the skeleton and edit it. The skeleton documents every key; at least check [http] listen, [grpc] listen and [tls] san (the names clients will use):

    Shell
    sudo cp /usr/share/kyvernon/controller.toml.example /etc/kyvernon/controller.toml
    sudo chown root:kyvernon /etc/kyvernon/controller.toml
    sudo chmod 0640 /etc/kyvernon/controller.toml
    sudo editor /etc/kyvernon/controller.toml
  2. Write the initial administrator password (12 to 256 characters). It is read once at the first start and must be changed at the first sign-in:

    Shell
    (umask 077; sudo sh -c 'printf "%s\n" "a-long-initial-password" > /etc/kyvernon/admin-password')
  3. Check the configuration and start the service:

    Shell
    sudo kyvernon-controller --config /etc/kyvernon/controller.toml check-config
    sudo systemctl enable --now kyvernon-controller.service
    sudo systemctl status kyvernon-controller.service

The settings of controller.toml are listed in Configuration.

The installation created /etc/kyvernon/join-token (root only). Hosts present it when they join; copy it to each host in step 3. The controller's TLS bootstrap certificate is /var/lib/kyvernon/controller/tls/bootstrap-cert.pem; hosts need it as well.

Open https://<controller>:8443/ in a browser and sign in as admin with the initial password (First sign-in, section 1).

3. Install a host

On the host server:

Shell
sudo ./kyvernon-install --role agent --pubkey /path/to/release-signing.minisign.pub

This installs kyvernon-vmm and kyvernon-agent (and the packages in deps/ when the depot carries them). If dpkg reports missing packages such as ovmf or swtpm, install them from your distribution mirror and run the command again. No service is started yet. Then:

  1. Copy the join token and the controller's bootstrap certificate from the controller:

    Shell
    sudo install -m 0600 -o root -g root join-token /etc/kyvernon/join-token
    sudo install -m 0644 -o root -g kyvernon bootstrap-cert.pem /etc/kyvernon/controller-ca.pem
  2. Write the agent configuration from the skeleton. Set [control_plane] endpoint to the controller's gRPC address (https://<controller>:8444), server_name to a name in the controller's [tls] san, and management_address to this host's address:

    Shell
    sudo cp /usr/share/kyvernon/agent.toml.example /etc/kyvernon/agent.toml
    sudo chown root:kyvernon /etc/kyvernon/agent.toml
    sudo chmod 0640 /etc/kyvernon/agent.toml
    sudo editor /etc/kyvernon/agent.toml
  3. Start the agent:

    Shell
    sudo systemctl enable --now kyvernon-agent.service
    sudo journalctl -u kyvernon-agent.service -f

The journal shows the host registering with the controller; the host then appears in the web console under Hosts. The one-time join token is not needed after that: the host has its own certificate (/var/lib/kyvernon/agent/identity). You may empty the token file (sudo truncate -s0 /etc/kyvernon/join-token) but keep it: the unit loads it at every start.

The join token does not replace the identity of a registered host: a host that lost its certificate (reinstalled, or /var/lib/kyvernon/agent/identity deleted) is refused when it registers again under the same name. Release it first, as an administrator, with a forced add of the host to its cluster (POST /v1/clusters/{id}/hosts with "force": true), or remove the host; then the agent joins again with the join token and keeps its host id.

Version 0.1. Last changed: 2026-11-13