nix/matrix+gateway: server_name defaults to hive domain + .well-known routes (#660)

mara on #660: "Matrix domain should default to hive domain if not
set otherwise / redirect matrix clients with .well-known"

Two coupled changes:

1. `services.hyperhive.matrix.serverName` default flipped from
   `matrix.${services.hyperhive.domain}` (subdomain) to just
   `${services.hyperhive.domain}` (bare hive domain).

   This is a "for new deploys only" change — `server_name` is
   embedded irrevocably in every user/room ID, so existing
   homeservers must set `serverName` explicitly to preserve the
   subdomain shape if that's where their identifiers were minted.
   Description updated to point at the .well-known piece below.

2. `hive-gateway` nginx now serves matrix-spec `.well-known`
   auto-discovery JSON at the canonical location when matrix is
   enabled + hive domain set:

       GET /.well-known/matrix/client
           {"m.homeserver":{"base_url":"http://<domain>:<httpPort>"}}
           + Access-Control-Allow-Origin: *  (per matrix spec)

       GET /.well-known/matrix/server
           {"m.server":"<domain>:<httpPort>"}

   tuwunel serves both client + federation on the same `httpPort`
   (see hive-matrix.nix), so both records point at the same
   endpoint. No-op when matrix isn't enabled or hive domain isn't
   set — nothing to advertise.

Combined effect: with `services.hyperhive.domain = "darkest.space"` +
matrix enabled, a matrix client pointed at `darkest.space` resolves
through `.well-known` to the actual `:8008` endpoint, no subdomain
needed. MXIDs become `@atlas:darkest.space` (was: `@atlas:matrix.darkest.space`).

Verified via `nix eval`:
- server_name = "darkest.space" (was "matrix.darkest.space")
- gateway locations include `= /.well-known/matrix/client` + `= /.well-known/matrix/server`
- well-known/matrix/client returns the spec-shaped JSON

Caveat: `m.homeserver.base_url` advertises HTTP (no TLS yet —
follow-up). matrix clients increasingly require HTTPS for new
account creation, so the v0 setup works for local-network testing
but won't satisfy public clients until the gateway TLS story lands.

Closes #660.
This commit is contained in:
atlas 2026-05-30 20:45:45 +02:00 committed by Mara
commit 3164d8cec3
2 changed files with 42 additions and 6 deletions

View file

@ -168,6 +168,39 @@ in
'';
};
}
//
# `.well-known/matrix/*` auto-discovery (#660): when
# `services.hyperhive.matrix.enable` is on and the
# operator's set a hive domain, the gateway serves
# the matrix-spec discovery JSON at the canonical
# location so clients pointed at `${hyperhive.domain}`
# resolve through to the actual tuwunel endpoint
# without needing a `matrix.` subdomain.
#
# `m.homeserver.base_url` advertises the client-server
# API. `m.server` advertises the federation
# `host:port` (tuwunel serves both client + federation
# on the same `httpPort` — see hive-matrix.nix).
#
# CORS `*` on the client endpoint per the matrix spec
# (https://spec.matrix.org/v1.15/client-server-api/#getwell-knownmatrixclient).
# No-op until the operator turns matrix on; until then
# there's no homeserver to advertise.
lib.optionalAttrs (matrixCfg.enable && hyperhiveDomain != null) {
"= /.well-known/matrix/client" = {
extraConfig = ''
default_type application/json;
add_header Access-Control-Allow-Origin *;
return 200 '{"m.homeserver":{"base_url":"http://${hyperhiveDomain}:${toString matrixCfg.httpPort}"}}';
'';
};
"= /.well-known/matrix/server" = {
extraConfig = ''
default_type application/json;
return 200 '{"m.server":"${hyperhiveDomain}:${toString matrixCfg.httpPort}"}';
'';
};
}
// {
# Everything else proxies to hive-c0re. Upgrade
# headers stay set so SSE (`/dashboard/stream`,

View file

@ -7,8 +7,7 @@
let
cfg = config.services.hyperhive.matrix;
hyperhiveDomain = config.services.hyperhive.domain;
effectiveServerName =
if cfg.serverName != null then cfg.serverName else "matrix.${hyperhiveDomain}";
effectiveServerName = if cfg.serverName != null then cfg.serverName else hyperhiveDomain;
in
{
# Private Matrix homeserver (matrix-tuwunel — the official conduwuit
@ -77,10 +76,14 @@ in
(`@argus:<server_name>`) and room ID minted on this
homeserver. CRITICAL: must be stable from day one because
it's embedded irrevocably in the identifiers. Defaults to
`matrix.''${services.hyperhive.domain}` (always a subdomain keeps
the root domain free for the dashboard or forge). Override
here only if you need a name that doesn't follow the
`matrix.<domain>` shape.
`services.hyperhive.domain` (the bare hive domain per mara
on #660). Combined with the `.well-known/matrix/{client,server}`
routes the hive-gateway serves at that domain (also #660),
clients auto-discover the actual matrix endpoint without
needing a subdomain. Override here only if you need a
different server_name shape (e.g. `matrix.<domain>` if you
want the subdomain split, or `chat.example.org` for a
bespoke hostname).
'';
};