Updates
Sirio can update itself from Settings → Updates. Releases come from a private update server you run: static files over HTTPS, behind HTTP basic auth, with one credential per installation. The repository is private, so GitHub’s release links need authentication, and a GitHub token on every server would let each of them read the whole source. An installation key can only download releases, and it can be revoked for one machine without touching the others.
What makes a release installable is its signature, not the server it came from. Every
release’s checksums.txt is signed with an ed25519 key that never leaves the maintainer’s
machine, and the public half is compiled into Sirio. Someone who takes over the update server, or
gets hold of an installation key, can hold updates back but can’t push a binary.
Connecting an installation
Section titled “Connecting an installation”Open Settings → Updates and enter the update server’s address (e.g.
https://updates.example.com) and the installation key, <name>:<secret>, issued by whoever
runs the server. The key is stored encrypted and never shown again; the card only shows its name.
Revoking it on the server cuts off that installation alone.
How an update runs
Section titled “How an update runs”- Sirio reads the server’s
index.jsonevery 6 hours (or when you press Check now) and lists the releases newer than the one running. - When you install one (or the automatic policy does), Sirio downloads it into
/var/lib/sirio/update/staging, verifies the signature and the checksums, and drops a request naming the version. That’s all it can do on its own: it runs as an unprivileged user underProtectSystem=strict, where/usr/local/binis read-only. - The
sirio-update.pathunit startssirio-updateas root. The helper copies the release out of Sirio’s directory and verifies it again, with the release keys of the binary already installed (root-owned, so it’s the one to trust). It also refuses a release that isn’t newer, so an old, genuinely signed release can’t be used to downgrade. - It stops Sirio, backs up the binary (
/usr/local/lib/sirio/sirio-sysadmin.prev) and the database (/usr/local/lib/sirio/rollback/), then runs the release’s owninstall.shwith the downloaded binary. That’s the same script as a manual installation, so units and helpers are updated too, and settings in the drop-in are kept. - It waits for the new version to reach “active” and stay there for 15 seconds without systemd
restarting it, on the expected version. If that doesn’t happen, or
install.shfails, it puts the previous binary and database back and starts Sirio again: the update shows as rolled back, with the reason.
The panel is unreachable for about half a minute. The Settings page keeps polling through the restart and reloads itself on the new version.
An update restarts Sirio, which interrupts pipeline runs and backups, so it waits for them. A manual update is refused while any are queued or running, and an automatic one is postponed until none are.
Only administrators see the Updates card and its endpoints. Updating replaces the binary that the root helpers trust, so it isn’t a permission that can be handed out.
Automatic updates
Section titled “Automatic updates”Settings → Updates → Automatic updates sets how big a step Sirio takes on its own:
| Setting | Installs on its own |
|---|---|
| Off (default) | nothing: it only checks and shows what’s available |
| Patch | v1.4.2 → v1.4.3 |
| Minor | also v1.4.2 → v1.5.0 |
| Major | every release, v2.0.0 included |
The levels are read literally from the tags: v0.14.0 → v0.15.0 is a minor step, even though
semver allows a 0.x minor to break things. The newest release the policy allows is installed as
soon as nothing is running. A release that failed or rolled back isn’t retried automatically:
install it by hand, or wait for the next one. Development builds (not exactly a tagged commit)
never update on their own.
The protocol
Section titled “The protocol”What Sirio asks the update server, for whoever wants to serve it another way:
GET <server>/index.json→{"releases": [{"version": "v0.15.0", "date": "2026-10-20T10:00:00Z", "notes": "…"}]}. Entries that aren’tvX.Y.Zare ignored.GET <server>/releases/<version>/<file>forchecksums.txt,checksums.txt.sig(base64 ed25519 signature of the exact bytes ofchecksums.txt),install.shandsirio-sysadmin-<version>-linux-<arch>.- Every request carries basic auth (installation name and secret) and a
User-Agent: sirio-sysadmin/<version> (linux/<arch>). 401 or 403 means the key was refused. Redirects are followed, without the credentials if they point to another host. - The address has to be
https. Plainhttpis only accepted towards loopback, for testing.
Where things are
Section titled “Where things are”/var/lib/sirio/update/:staging/(the downloaded release, removed after a successful update),request,result,update.log(the download) andinstall.log(the installation). The helper reads and writes them as Sirio’s user, never as root (see security.md)./usr/local/lib/sirio/sirio-sysadmin.prevand/usr/local/lib/sirio/rollback/: the previous binary and database, kept until the next update.journalctl -u sirio-update: the helper’s own output.SIRIO_UPDATES_ENABLED=falseremoves the section;SIRIO_UPDATE_HELPERpoints to a helper installed elsewhere.
A rollback restores the binary and the database, not the units and helpers: the new release’s
stay. install.sh keeps those compatible with the previous release, and an older install.sh
can’t be rerun without its release.
The installation key is decryptable by anything running as Sirio’s user, pipeline shell steps included. That’s acceptable because all it opens is the release downloads, and it’s why each machine gets its own key.