diff --git a/docs/gateway.md b/docs/gateway.md index e569b0fc..6bf2df77 100644 --- a/docs/gateway.md +++ b/docs/gateway.md @@ -14,9 +14,6 @@ Single nginx in front of every hyperhive web surface. Runs on the **host**, next | `matrix./_matrix/*` | `matrix.` | tuwunel (`8008`) | `matrix.gatewayHost != null` | | `matrix./` | `matrix.` | fluffychat-web static | `matrix.gui.enable` | | `matrix./config.json` | `matrix.` | inline JSON (FluffyChat boot config) | `matrix.gui.enable && domain != null` | -| `auth./` | `auth.` | authelia (`9091`) | `swarm.authelia.enable` | - -The authelia vhost is declared only by the host that **runs** authelia, not by every hive that uses it — a client hive knows the swarm's `authelia.url` but must not answer for a name it doesn't serve. Its server name is exactly `swarm.authelia.domain`: authelia validates `authelia_url ⊂ session cookie domain` at startup, so a near-miss is a container that refuses to boot. It carries no `auth_basic` — the login page must not sit behind the login mechanism it replaces — and sets the four `X-Forwarded-{Proto,Host,Uri,For}` headers, since authelia decides by the *original* request rather than the hop it sees. Per-agent UIs stay sub-path because they're hyperhive-internal and base-path-aware. External standard apps (forge / matrix) get sub-domains because their defaults work cleanly at sub-domain root + per-origin cookies / storage isolation matters. @@ -60,7 +57,6 @@ Each location carries a duplicated `auth_basic` block (separate locations don't - `` → `127.0.0.1` - `forge.` → `127.0.0.1` (when forge.behindGateway) - `matrix.` → `127.0.0.1` (when matrix.gatewayHost set) -- `auth.` → `127.0.0.1` (when swarm.authelia.enable) `lib.unique` de-dupes if any sub-domain happens to equal another entry. Operators with real DNS leave it off. diff --git a/docs/network.md b/docs/network.md index f538bf95..1d2edbd9 100644 --- a/docs/network.md +++ b/docs/network.md @@ -113,8 +113,7 @@ schemes pick their own. ## Resolver behaviour dnsmasq is **authoritative** for the hive's own zones — answers -``, `forge.`, `matrix.` and — -on the host running it — the swarm's `auth.` +``, `forge.`, `matrix.` queries with the bridge IP (where nginx is reachable). Everything else is forwarded to the host's own resolvers: dnsmasq runs on the host and reads the host's `/etc/resolv.conf` directly. Containers don't need diff --git a/docs/swarm/sso.md b/docs/swarm/sso.md index 627120c4..0c1c5b61 100644 --- a/docs/swarm/sso.md +++ b/docs/swarm/sso.md @@ -10,38 +10,6 @@ The second role is derived rather than switched: on. authelia refuses to start with a provider that has no clients, so a separate `enable` would be a second fact free to disagree with the first. -## Getting in the first time - -authelia binds loopback only. The **gateway** on the host running it -publishes it as `auth.` — vhost, dnsmasq record and TLS -name all follow `swarm.authelia.enable`, so there is nothing to turn on -separately. (Details, including why a client hive must not declare that -vhost: [`../gateway.md`](../gateway.md).) - -Reachable is not the same as usable: the provider is generated with an -empty user set, deliberately. A provider with nobody in it yet is the -correct state for a fresh swarm — it is not a half-finished install, and -seeding a default account would be a credential in a config file. - -Add the first subject on the host running authelia: - -```console -# swarmctl user add mara --display-name Mara --email mara@example.com --group admins -added mara to /var/lib/authelia-swarm/users.yml -password: -this password is stored nowhere — record it now -``` - -The password is generated, hashed, and printed once; only the hash is -kept. `swarmctl` writes its canonical `users.json`, re-renders authelia's -`users.yml` from it, and restarts authelia. Full reference: -[`../tools/swarmctl-cli.md`](../tools/swarmctl-cli.md). - -This step stays manual on purpose. Bootstrapping an identity provider -non-interactively means a secret arriving from somewhere — a file, an -env var, a nix expression — and every one of those is worse than an -operator typing one command once. - ## What secrets exist, and where each one lives | secret | generated by | rests in | read by | diff --git a/nix/host-modules/hive-gateway/default.nix b/nix/host-modules/hive-gateway/default.nix index 92d5f7c9..084937a5 100644 --- a/nix/host-modules/hive-gateway/default.nix +++ b/nix/host-modules/hive-gateway/default.nix @@ -22,7 +22,6 @@ let # same list rather than each deciding what "a swarm service" means. swarmServiceDomains = config.services.hyperhive.swarm.serviceDomains; matrixCfg = config.services.hyperhive.swarm.matrix; - autheliaCfg = config.services.hyperhive.swarm.authelia; forgeCfg = config.services.hyperhive.swarm.forge; networkCfg = config.services.hyperhive.network; @@ -71,7 +70,6 @@ let cfg forgeCfg matrixCfg - autheliaCfg hyperhiveDomain dashboardDist swaggerUiTheme @@ -311,7 +309,6 @@ in networkCfg forgeCfg matrixCfg - autheliaCfg hyperhiveDomain ; }; @@ -335,7 +332,6 @@ in ++ lib.optional (config.services.hyperhive.swarm.forge.behindGateway or false ) config.services.hyperhive.swarm.forge.domain ++ lib.optional (matrixCfg.enable && matrixCfg.gatewayHost != null) matrixCfg.gatewayHost - ++ lib.optional autheliaCfg.enable autheliaCfg.domain ); }; }; diff --git a/nix/host-modules/hive-gateway/dnsmasq.nix b/nix/host-modules/hive-gateway/dnsmasq.nix index 52eabb4d..b212309a 100644 --- a/nix/host-modules/hive-gateway/dnsmasq.nix +++ b/nix/host-modules/hive-gateway/dnsmasq.nix @@ -10,7 +10,6 @@ networkCfg, forgeCfg, matrixCfg, - autheliaCfg, hyperhiveDomain, }: { @@ -59,8 +58,7 @@ ++ lib.optional ((forgeCfg.behindGateway or false)) "/${forgeCfg.domain}/${networkCfg.bridgeIp}" ++ lib.optional ( matrixCfg.enable && matrixCfg.gatewayHost != null - ) "/${matrixCfg.gatewayHost}/${networkCfg.bridgeIp}" - ++ lib.optional autheliaCfg.enable "/${autheliaCfg.domain}/${networkCfg.bridgeIp}"; + ) "/${matrixCfg.gatewayHost}/${networkCfg.bridgeIp}"; # DHCP pool covering all usable host addresses on the bridge # subnet — bounds computed by hive-network.nix from # bridgeIp/bridgePrefixLength. All containers (agents and service diff --git a/nix/host-modules/hive-gateway/vhosts.nix b/nix/host-modules/hive-gateway/vhosts.nix index 20d9c97d..91d5f484 100644 --- a/nix/host-modules/hive-gateway/vhosts.nix +++ b/nix/host-modules/hive-gateway/vhosts.nix @@ -9,7 +9,6 @@ cfg, # services.hyperhive.gateway forgeCfg, matrixCfg, - autheliaCfg, # services.hyperhive.swarm.authelia hyperhiveDomain, dashboardDist, swaggerUiTheme, # nix/packages/swagger-ui-theme.nix: has index.html + hyperhive-theme.css @@ -124,42 +123,6 @@ let }; }; - # Authelia sub-domain vhost. `server_name = authelia.domain`, all of - # `/` → authelia. Empty attrset unless THIS host runs the container: - # every hive knows the swarm's `authelia.url`, but only the one - # serving it may claim the name — a client hive declaring this vhost - # would answer for a service it does not run. - # - # ⚠️ The server name must be exactly `autheliaCfg.domain`, not a - # near-miss: authelia validates `authelia_url ⊂ session cookie domain` - # at STARTUP, so a mismatch is a container that refuses to boot rather - # than a login that misbehaves. - # - # ⚠️ And deliberately NO `dashboardAuth` here. That block is the - # gateway's `auth_basic`; applying it to the SSO provider would put - # the login page behind the login mechanism it exists to replace. - autheliaVhost = lib.optionalAttrs autheliaCfg.enable { - "${autheliaCfg.domain}" = (vhostTlsFor autheliaCfg.domain) // { - listen = vhostListen; - extraConfig = securityHeaders; - locations."/" = { - proxyPass = "http://127.0.0.1:${toString autheliaCfg.port}/"; - proxyWebsockets = true; - extraConfig = '' - proxy_buffering off; - # authelia decides by the ORIGINAL request, not by the hop it - # sees — the login redirect and the session cookie's domain - # both derive from these. Without them every request looks - # like it arrived at 127.0.0.1 over plain http. - proxy_set_header X-Forwarded-Proto $scheme; - proxy_set_header X-Forwarded-Host $host; - proxy_set_header X-Forwarded-Uri $request_uri; - proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; - ''; - }; - }; - }; - # Matrix sub-domain vhost. `server_name = matrixCfg.gatewayHost`. # `/_matrix/*` → tuwunel (CORS *, 50M body cap, 1h long-poll # timeout). `/` serves fluffychat or 404 if GUI off. nginx @@ -446,6 +409,5 @@ in }; } // forgeVhost - // autheliaVhost // matrixVhost; }