Skip to content
Kaiov0.6.1

Upgrading to 0.6.0

0.6.0 is the release that makes Kaio safe by default, and it breaks one thing on purpose: a server listening off the loopback refuses to start until its configuration says who may reach it. Kaio still authenticates no one; it now insists on knowing whom to trust. Security has the model.

Before 0.6.0 the installer wrote KAIO_ADDR=0.0.0.0:8080 on a fresh install, and the reference Compose file published 8080:8080, so most installations are in that case. Nothing is lost when it bites: the installer checks the configuration with the new binary before replacing anything, and stops with the version you had still running:

Refusing to listen on http://0.0.0.0:8080: Kaio authenticates no one, and whoever
reaches this address would control the Docker daemon. Pick one:
...
install.sh: this release would refuse to start with /etc/kaio/kaio.env,
so nothing was replaced and the version installed keeps running.

Add one line to /etc/kaio/kaio.env, then run the installer again:

Terminal window
echo 'KAIO_ALLOWED_NETWORKS=192.168.1.0/24' | sudo tee -a /etc/kaio/kaio.env
curl -fsSL https://kaio-labs.gaidot.net/install.sh | sh

Which line depends on what was in front of the port:

You had Add
A reverse proxy on the same host KAIO_ADDR=127.0.0.1:8080 and KAIO_TRUSTED_PROXIES=127.0.0.1
A reverse proxy on another host KAIO_TRUSTED_PROXIES=<its address>
A tailnet, a WireGuard tunnel, a private LAN KAIO_ALLOWED_NETWORKS=<its range>, 100.64.0.0/10 for a tailnet
Nothing, on a network you trust KAIO_ALLOWED_NETWORKS=<that network>, or KAIO_I_UNDERSTAND_NO_AUTH=yes to keep the old behaviour
A node that joined a cluster Nothing, if it holds its control plane’s key: it then starts, and answers its control plane only. See below when it is refused anyway

kaio-server check tells you, without starting anything or touching the database, whether a configuration will start:

Terminal window
sudo sh -c 'set -a; . /etc/kaio/kaio.env; exec kaio-server check'

With a proxy in front, also give it the shared secret and, if your identity provider sends groups, map them to levels: Reverse proxy has both for Caddy, Traefik and nginx with Authelia, Authentik and oauth2-proxy.

Inside a container KAIO_ADDR has to stay 0.0.0.0, so the container refuses to start the first time it runs 0.6.0 with the old Compose file. The new one publishes the port on the loopback and names the network Kaio runs on:

ports:
- "127.0.0.1:8080:8080"
environment:
- KAIO_ADDR=0.0.0.0:8080
- KAIO_ALLOWED_NETWORKS=172.31.80.0/24
networks:
- kaio
networks:
kaio:
ipam:
config:
- subnet: 172.31.80.0/24

A connection through a published port reaches the container from that network, not from its own loopback, which is why the network is named rather than 127.0.0.1. See Deploy with Compose.

  • CORS. With KAIO_ALLOWED_ORIGINS unset, the API used to answer every origin. It now answers same-origin calls only, and refuses a cross-site request that changes something. Name the origin of any page of your own that calls the API.
  • The shell needs admin. It is arbitrary execution, so it sits above write on the ladder.
  • Behind a proxy that sends groups, once KAIO_GROUPS_* is set, a user in none of them gets off. Without a mapping, every proxied user keeps admin, as before.
  • A cluster upgrades together. The control plane now signs every call it relays, with a new signature format, and a node only accepts that format. Move every server to 0.6.0, the control plane last as usual, before driving nodes through it again.
  • /mcp gives each caller the tools of KAIO_MCP or of its own level, whichever is lower, rather than KAIO_MCP to everyone.
  • Prometheus. /metrics and /metrics/targets answer a scrape from any address only when KAIO_METRICS_TOKEN is set and the scrape carries it, which is what an install with --with-monitoring and the shipped prometheus.yml already do: nothing to change there. A /metrics left with no token now answers only the callers the server accepts anyway, so a Prometheus elsewhere is refused with 403: set a token, or name its network in KAIO_ALLOWED_NETWORKS.
  • A fresh install with --with-monitoring listens on the loopback, which the Prometheus container cannot reach, so its target reads as down until Kaio listens on an address a container reaches: see With Prometheus and Grafana. An upgrade keeps your KAIO_ADDR, so this only concerns new hosts.
  • compose.full.yml (make metrics-full-run) now publishes Kaio on 127.0.0.1 and puts it on a network of its own, 172.31.81.0/24, beside a monitoring network for Prometheus, Alertmanager and Grafana. A copy you kept from an earlier release refuses to start: take the new one.

Once it runs, kaio-cli doctor lists anything still worth fixing.

A node of the cluster is refused like a standalone server. It joined before the release that pins the control plane’s key, so it trusts no signature. Check on the node:

Terminal window
sqlite3 /var/lib/kaio/kaio.db "select control_plane_url, length(control_plane_key) from cluster"

An empty or zero length confirms it. Add KAIO_ALLOWED_NETWORKS for now and upgrade, then join it again with a fresh token from the upgraded control plane (kaio-cli cluster token), and remove the line: from then on it answers its control plane only.

The dashboard answers Requests from 192.168.1.32 are refused. The server started, and your machine is on another network than the one you named. KAIO_ALLOWED_NETWORKS takes several ranges, comma-separated:

Terminal window
KAIO_ALLOWED_NETWORKS=192.168.7.0/24,192.168.1.0/24

If that address is a reverse proxy rather than your machine, name it in KAIO_TRUSTED_PROXIES instead.

The audit log is empty. It starts with the upgrade, and records actions that change something, never the pages you read. Restart a stack and it shows.

  • How to upgrade, the back-up, upgrade and check steps every release follows
  • Security, the access model this release introduces
  • Reverse proxy, ready-made setups for the proxy in front

Kaio, built by Régis Gaidot