From 1cc1cb804d06ab8c465f305f3c1bb02ff7c6ab2d Mon Sep 17 00:00:00 2001 From: damocles Date: Tue, 10 Nov 2026 21:45:49 +0100 Subject: [PATCH] hive-matrix: prefill the chat client with the server name, not the hive domain --- docs/2-handbook/swarm/matrix.md | 6 ++++++ nix/host-modules/hive-matrix.nix | 13 ++++--------- nix/module-eval/matrix-core.nix | 11 +++++++++++ 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/docs/2-handbook/swarm/matrix.md b/docs/2-handbook/swarm/matrix.md index 3905f5d2f..e79842269 100644 --- a/docs/2-handbook/swarm/matrix.md +++ b/docs/2-handbook/swarm/matrix.md @@ -104,6 +104,12 @@ at the server name, which names `:443` ([`gateway.md::Discovery flow`](../../4-implementation/networking/gateway.md#discovery-flow-matrix)). Port 8448 isn't used. +The web chat client at `chat.` signs in the same way: its +login dialog preselects the server name and looks the homeserver up through +that discovery answer. That's the swarm domain by default, and the hive +domain on a homeserver that pinned `serverName` to it. Typing the server name +into any other Matrix client uses the same value. + Outbound, the container sits on the hive bridge like the CI runner: it leases an address from the gateway's DHCP, resolves through its dnsmasq, and leaves through the bridge's NAT. It reaches the secret store, diff --git a/nix/host-modules/hive-matrix.nix b/nix/host-modules/hive-matrix.nix index fb39121f6..55e703e05 100644 --- a/nix/host-modules/hive-matrix.nix +++ b/nix/host-modules/hive-matrix.nix @@ -9,10 +9,6 @@ let networkCfg = config.services.hyperhive.network; tlsCfg = config.services.hyperhive.deploy.hive-controller.tls; gatewayCfg = config.services.hyperhive.gateway; - # The hive's own domain; null on a homeserver host that runs no hive, where - # the client is pointed at the server name instead. - hyperhiveDomain = config.services.hyperhive.domain; - rootfsCheck = import ./lib/container-rootfs-check.nix { inherit config; }; # Same runtime→build-time bridge hive-forge and swarm-ci-runner cross: @@ -554,14 +550,13 @@ in }; # FluffyChat boot-config pre-fill so the client's # `.well-known/matrix/client` lookup hits the right delegation - # endpoint. A hive host names its hive domain; a homeserver host - # without a hive has none and names the server name. + # endpoint. That lookup reads the server name, which the swarm apex + # (or the hive vhost a pinned server name equals) answers for, not + # the hive domain. "= /config.json" = { extraConfig = '' default_type application/json; - return 200 '{"defaultHomeserver":"${ - if hyperhiveDomain != null then hyperhiveDomain else effectiveServerName - }"}'; + return 200 '{"defaultHomeserver":"${effectiveServerName}"}'; ''; }; }; diff --git a/nix/module-eval/matrix-core.nix b/nix/module-eval/matrix-core.nix index 6a3923075..5344a92e9 100644 --- a/nix/module-eval/matrix-core.nix +++ b/nix/module-eval/matrix-core.nix @@ -63,6 +63,17 @@ let in lib.hasInfix "client_max_body_size 100048576;" c && !(lib.hasInfix "client_max_body_size 50M" c); } + { + # The chat client signs in against the server name, which for a default + # swarm is the swarm domain; the hive domain (`h1.t.local`) is a vhost + # that answers no discovery there, so a prefill of it is a dead end. + name = "the chat client's homeserver prefill is the server name, not the hive domain"; + ok = + let + c = matrixBodyCap.services.nginx.virtualHosts."chat.t.local".locations."= /config.json".extraConfig; + in + lib.hasInfix ''{"defaultHomeserver":"t.local"}'' c && !(lib.hasInfix "h1.t.local" c); + } { # Absence arm. A hive with no client identity gets no # store environment at all — the daemon reports a queue it cannot serve