From 9fa75a7f2f4d79076ab204bcc7921ee14f96b096 Mon Sep 17 00:00:00 2001 From: atlas Date: Fri, 14 Aug 2026 10:19:50 +0200 Subject: [PATCH] =?UTF-8?q?feat(3150):=20matrix=20SSO=20options=20?= =?UTF-8?q?=E2=80=94=20opt-in=20OIDC=20relying=20party?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Stage 1 of the staged rollout mara laid out on the issue: the options and nothing that changes a running hive. `enable` defaults false, so this commit is inert until someone opts in. Three rules taken from hive-forge/default.nix rather than re-derived, since it is the same pattern already merged and reviewed: - `enable` ADDS a login path and leaves password login alone. An identity provider that can take the homeserver offline when it hiccups is worse than two ways in. Making authelia the only path is tuwunel's `login_with_password`, a separate and reversible switch, deliberately not folded in here. - the client secret is a PATH, never a value: it has two holders in two containers (authelia keeps a hash, the homeserver needs plaintext), and a literal would be rendered into the world-readable store. - required when enabled, no fallback. Worse here than for the forge: tuwunel reads OIDC from its config file rather than a database row, so a malformed block can stop the server outright instead of merely hiding a button. Also records the constraint that shapes the whole issue — matrix SSO lives inside the homeserver, never behind a forward-auth proxy, because the client-server API is spoken by non-browser clients holding matrix access tokens plus federation. --- nix/host-modules/hive-matrix.nix | 56 ++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/nix/host-modules/hive-matrix.nix b/nix/host-modules/hive-matrix.nix index 4a7e9d5c..2ac05277 100644 --- a/nix/host-modules/hive-matrix.nix +++ b/nix/host-modules/hive-matrix.nix @@ -394,6 +394,62 @@ in ''; }; }; + + sso = { + enable = lib.mkOption { + type = lib.types.bool; + default = false; + description = '' + Let this homeserver delegate login to the swarm's authelia, + as an OIDC relying party ("matrix next-gen auth"). + + This **adds** a way in. Password login keeps working: an + identity provider that can take the homeserver offline when + it hiccups is a worse homeserver than one with two ways in. + Making authelia the only path is a separate, reversible + switch (tuwunel's `login_with_password`), deliberately not + folded in here. + + ⚠️ Matrix SSO lives **inside** the homeserver, never behind a + forward-auth proxy: the client-server API is spoken by + non-browser clients holding matrix access tokens — every + agent's own `hive-matrix-daemon` — plus federation, and a + proxy in front of `/_matrix/` breaks all of it. + ''; + }; + + clientId = lib.mkOption { + type = lib.types.str; + default = "tuwunel"; + description = '' + OAuth2 client id this homeserver identifies itself with. Must + match the `id` of the corresponding entry in + `services.hyperhive.swarm.authelia.oidc.clients`. + ''; + }; + + clientSecretFile = lib.mkOption { + type = lib.types.nullOr lib.types.str; + default = null; + example = "/var/lib/tuwunel-oidc/tuwunel.secret"; + description = '' + Path **inside the matrix container** holding the client + secret's plaintext. + + A path, never a value: an OIDC client secret has two holders + in two containers (authelia keeps a hash, this homeserver + needs the plaintext), and a literal written here would be + rendered into the world-readable nix store. + + Required when `enable` is set — deliberately no fallback. A + homeserver that boots with SSO half-configured is worse than + one that fails to evaluate: tuwunel reads OIDC from its + config file rather than a database row, so a malformed block + can stop the server outright instead of merely hiding a + button. + ''; + }; + }; }; config = lib.mkIf cfg.enable {