Skip to content

SSO and Identities (Kanidm)

Kanidm 🡕 is the network’s identity provider: a single identity unlocks all services (SSO). The idm service runs on the HCS (and, optionally, as a replica in each zone).

Accounts and groups are provisioned in Kanidm from etc/config.yaml:

etc/config.yaml
users:
alice:
profile: "nix-admin"
groups: ["idm-admins", "idm-devs", "global"]
  • Groups control access to services.
  • Two special groups: idm-admins (administration), idm-devs (development).

OIDC-compatible services are linked to SSO automatically: Kanidm provisions an OAuth2 client per service, and its secret is managed by sops. Nothing to configure manually.

A service without its own authentication (homepage, static site) is protected by placing a Kanidm login screen in front of it (oauth2-proxy + Caddy). For the homepage, a setting on the gateway host (usr/machines/<gateway>/) :

darkone.service.homepage.protect = true; # requires a Kanidm session
OptionDefaultEffect
protecttrueHomepage reserved for Kanidm users (users group)

The mode is inferred from where idm is declared:

  1. idm on the HCS only → single instance, no replication.
  2. idm on a gateway without HCS → standalone instance in the zone.
  3. idm on the HCS and gateways → replication: the HCS provides, each gateway is a read-only replica.
Diagram

Administration is done via the command line on the HCS:

Fenêtre de terminal
just enter hcs
kanidm person credential create-reset-token <login> --name idm_admin

See Create a user account and Reset a password.

Kanidm only maintains a single version at a time : a version reaches its end-of-life 30 days after the release of the next one, and only an upgrade from one version to the next is supported. DNF therefore pins the package explicitly, in dnf/modules/service/idm.nix :

services.kanidm.package = pkgs.kanidm_1_11.withSecretProvisioning;

The evaluation warns as soon as the pinned version is deprecated :

kanidm 1.10 is deprecated and will reach end-of-life on 2026-08-31

After this date, nixpkgs marks the version as unmaintained and the evaluation fails. The upgrade must therefore be planned before the deadline.

  1. Compatibility check, on the HCS, before touching the version :

    Fenêtre de terminal
    just enter hcs
    sudo kanidmd domain upgrade-check -c /etc/kanidm/server.toml

    Read-only operation. Each item must come out as PASS ; a FAIL must be fixed before going any further.

  2. Cold copy of the database, the only really reliable rollback :

    Fenêtre de terminal
    sudo systemctl stop kanidm
    sudo install -d -o kanidm -g kanidm /var/lib/kanidm/pre-upgrade
    sudo cp -a /var/lib/kanidm/kanidm.db* /var/lib/kanidm/pre-upgrade/
    sudo kanidmd database backup /var/lib/kanidm/pre-upgrade/dump.json -c /etc/kanidm/server.toml
    sudo chown -R kanidm:kanidm /var/lib/kanidm
    sudo systemctl start kanidm

    Copy the journal, not just the database. SQLite does not always merge its write journal when closing : a kanidm.db-wal of several MB commonly survives the service stop. Copying kanidm.db alone would leave the latest transactions aside. The * takes the .db, .db-wal and .db-shm triplet, which is only valid taken together.

    The final chown is not optional : the two previous commands run as root and would otherwise leave files the service can no longer write.

  3. Move the pin to the next version, one at a time, then deploy the HCS.

  4. Check the service and the database consistency :

    Fenêtre de terminal
    systemctl status kanidm
    sudo kanidmd database verify -c /etc/kanidm/server.toml

    Finish with a real OIDC login on a network service.

In case of failure : put the pin back on the previous version, restore the .bak file in place of kanidm.db (service stopped), redeploy.