diff --git a/docs/setup.md b/docs/setup.md index 41050375..76235dbd 100644 --- a/docs/setup.md +++ b/docs/setup.md @@ -49,30 +49,51 @@ start. Skipping this step looks like a broken proxy. swarmctl user add mara --display-name Mara --email mara@example.com --group admins ``` +⚠️ **Keep `--group admins`.** It is not decoration: operator-only +surfaces (the swarm UI below) are gated on that group, and an account +without it authenticates successfully and is then refused — which reads +like a broken login rather than a missing group. + Detail, including what the password is and why this stays manual: [`swarm/sso.md`](swarm/sso.md). -### 4 · Matrix +### 4 · Swarm UI (only when `swarm.ui.enable`, on by default with the controller) + +Nothing to run — it is served on the swarm apex +(`https:///`) as soon as the host rebuilds. Two things +decide whether you can actually open it: + +- **You are in `admins`** (step 3). The gateway asks authelia whether + you have a session; the rule that makes it mean *operator* wants the + group. Without it you log in and still get bounced. +- **The name resolves to this host.** It is published to the hive's own + resolver and to `/etc/hosts` when `gateway.localHostsEntry` is on; from + anywhere else it needs a real DNS record like any other public name. + +Detail, including why reachability is deliberately not the access +control: [`swarm/ui.md`](swarm/ui.md). + +### 5 · Matrix ```bash -# 4a. Ensure the hive-internal admin account exists first +# 5a. Ensure the hive-internal admin account exists first hivectl matrix sync-admin -# 4b. Provision ruth's own matrix account +# 5b. Provision ruth's own matrix account hivectl matrix create-user ruth -# 4c. Create a human matrix account +# 5c. Create a human matrix account hivectl matrix create-user mara --password hunter2 -# 4d. Invite the operator to the hive Space (and optionally to rooms) +# 5d. Invite the operator to the hive Space (and optionally to rooms) hivectl matrix invite mara hivectl matrix invite @mara:yourserver --room '#hive-chat:yourserver' -# 4e. Promote the operator to homeserver admin if needed +# 5e. Promote the operator to homeserver admin if needed hivectl matrix promote-user mara ``` -### 5 · Spawn sub-agents +### 6 · Spawn sub-agents Sub-agent creation goes through the approval queue — ruth proposes, the operator approves, the container builds. From ruth's own turn (inside @@ -93,7 +114,7 @@ request_init_config(name: "iris") See [`approvals.md`](approvals.md) for the full flow. -### 6 · Useful host commands +### 7 · Useful host commands ```bash # Roster: all agents, status, rev, parent, pending reminders diff --git a/docs/swarm/README.md b/docs/swarm/README.md index 810d0213..0022a0c3 100644 --- a/docs/swarm/README.md +++ b/docs/swarm/README.md @@ -97,7 +97,7 @@ another container, and the three ways that one gets delivered: ## Swarm UI The operator-only web surface on the swarm apex, why reaching it needs -the `operators` group rather than just a session, and the four sites a +the `admins` group rather than just a session, and the four sites a swarm service name has to be wired into: [`ui.md`](ui.md). ## The swarm's hive directory diff --git a/docs/swarm/ui.md b/docs/swarm/ui.md index cfdc46c6..0bb73bcc 100644 --- a/docs/swarm/ui.md +++ b/docs/swarm/ui.md @@ -25,21 +25,28 @@ way `swarm.forge.domain` and `swarm.matrix.gatewayHost` can. > claiming one `server_name` do not error — nginx picks one — so this is > an assertion rather than a runtime surprise. -## 🔑 You must be in the `operators` group +## 🔑 You must be in the `admins` group **This is the step that separates "protected" from "locked out".** The vhost's `auth_request` asks authelia *"is there a session"*; the rule that makes it mean *"is this an operator"* is an `access_control` entry -requiring `group:operators`. An account without that group authenticates +requiring `group:admins`. An account without that group authenticates fine and still gets bounced. ```sh -swarmctl user add --group operators +swarmctl user add --group admins ``` -An account created before this existed has no groups. Re-add it with the -flag — `swarmctl` treats an existing entry as the canonical store, so the -group is what changes. +`admins` deliberately, not a new word: [`../setup.md`](../setup.md) has +told every operator to create exactly that group since the bootstrap step +existed, so an account made by following the guide already passes. This +is the first rule that *consumes* a group name — inventing a second one +would have meant those accounts silently failing a check they were +supposed to pass. + +An account created without any group needs re-adding with the flag — +`swarmctl` treats the existing entry as the canonical store, so the group +is what changes. Why a group and not a list of usernames: agents are getting authelia accounts of their own (matrix SSO), and *authenticated* would then diff --git a/nix/host-modules/swarm-authelia.nix b/nix/host-modules/swarm-authelia.nix index b314cd53..30d39fd5 100644 --- a/nix/host-modules/swarm-authelia.nix +++ b/nix/host-modules/swarm-authelia.nix @@ -43,7 +43,14 @@ let # here because this module writes the rule that enforces it and # `swarmctl user add --group ` is what grants it — the two must # agree, and one constant is how they stay agreeing. - operatorGroup = "operators"; + # + # ⚠️ `admins` and not a new word, because `docs/setup.md` and + # `docs/swarm/sso.md` have been telling every operator to create + # exactly that group since the bootstrap step existed. This is the + # first rule that CONSUMES a group name; picking a different one would + # have meant every account created by following the guide silently + # failing the check it was supposed to pass. + operatorGroup = "admins"; # Upstream's `services.authelia.instances.` derives the unit, # user, group and StateDirectory from the instance name