diff --git a/docs/getting-started/setup.md b/docs/getting-started/setup.md index 740d6367..1add36d6 100644 --- a/docs/getting-started/setup.md +++ b/docs/getting-started/setup.md @@ -181,7 +181,7 @@ which. A hive that does **not** deploy the store names the reader's three itself: the operator issues that leaf out of band, and it's the one credential the store can't hand you, being what opens it. ⚠️ Not the gateway's HTTPS certificates and not the hive CA — this is **mTLS between services and the store**, a separate trust domain, because a -store that took its identity from an authority it will itself distribute could +store that took its identity from an authority it itself distributes could never come up before that authority. ### 4 · Swarm SSO (only when `deploy.authelia`) @@ -203,8 +203,8 @@ surfaces (the swarm UI below) gate 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. -If an account already exists without it, `user add` will refuse rather -than amend — adding the group afterwards is `swarmctl user update mara +If an account already exists without it, `user add` refuses rather +than amends — adding the group afterwards is `swarmctl user update mara --add-group admins`. Detail, including what the password is and why this stays manual: diff --git a/docs/integrations/matrix.md b/docs/integrations/matrix.md index 8847a098..6be59be0 100644 --- a/docs/integrations/matrix.md +++ b/docs/integrations/matrix.md @@ -147,20 +147,20 @@ a token. (`hive-matrix-daemon.path` watching for `matrix-token` appearance) brings the daemon up on the same boot cycle anyway. -### The `@hive:` account, and why it is not an admin +### The `@hive:` account, and why it isn't an admin `@hive:` is the appservice's own `sender_localpart`, which the homeserver creates itself when it loads the registration — on a zero-user database, inside startup, before the HTTP listener accepts -anything. It is an **ordinary account**: nothing promotes it, and the +anything. It's an **ordinary account**: nothing promotes it, and the homeserver runs no `admin_execute` for it. It needs no promotion for what the hive does with it. Creating the hive Space and the chat room, writing their hierarchy and join rules, and inviting agents into them are all ordinary client calls that ride on being the rooms' own creator at power level 100 — there is no homeserver -admin in any of it. (There is no Synapse admin API here either; tuwunel -has none.) +admin in any of it, and no Synapse admin API to reach for either, since +tuwunel has none. Two operations do need an admin **sender**, and neither works today: `hivectl matrix promote-user` and `hivectl matrix reset-password`. Both @@ -169,8 +169,8 @@ treats a message as a command when its sender is already an admin. They are swarm-level operations and are being rehomed as such; until then they fail with the admin room's refusal rather than being served by an over-privileged credential that every other call site would also carry. -The one hive-side path that depends on them is the password-reset -auto-recovery for an agent whose stored password is gone — the ordinary +The one hive-side path that depends on them is the automatic password +recovery for an agent whose stored password is gone — the ordinary appservice re-login above is unaffected.
Upgrading a hive that used the registration token @@ -189,7 +189,7 @@ restarts, so the first boot after the switch already has both halves. and displaces no session. - **`@hive:` may already be an admin** on such a hive (it won the first-user grant when the hive was new). Nothing here demotes it; the - homeserver simply no longer promotes it, so a hive built fresh has an + homeserver no longer promotes it, so a hive built fresh has an ordinary account and an older one keeps whatever standing it acquired. - **`/var/lib/hyperhive/matrix-register-token` stays on disk**, read by nothing. Delete it or leave it; neither does any harm. @@ -278,7 +278,7 @@ services.hyperhive.swarm.matrix = { ``` **`trustedServers`** (default `[]`) — list of peer homeserver names -whose signing keys tuwunel will fetch and trust. tuwunel enables federation +whose signing keys tuwunel fetches and trusts. Federation is enabled at the protocol level from first boot (`allow_federation = true`) but trusts no remote homeserver until you list it here. For a closed single-hive deployment the default empty list is correct — add peer diff --git a/docs/tools/hivectl.md b/docs/tools/hivectl.md index ce7d4864..8b5c407e 100644 --- a/docs/tools/hivectl.md +++ b/docs/tools/hivectl.md @@ -79,11 +79,11 @@ hivectl matrix invite @mara:server --room '#hive-chat:server' # ...or to a spec access token path. Safe to run again — idempotent. - `promote-user`: promotes an already-registered user to homeserver admin by an `!admin` command in `#admins`. ⚠️ Needs an admin **sender**, - which `@hive:` is not — this operation is being rehomed at swarm level - and does not work from the hive today. + which `@hive:` isn't — this operation is being rehomed at swarm level + and doesn't work from the hive today. - `reset-password`: asks the admin room to set a new random password and prints it to stdout. ⚠️ Needs an admin **sender** too, so - it does not work from the hive today either. Useful if an agent or human lost + it doesn't work from the hive today either. Useful if an agent or human lost credentials. - `invite`: invites a matrix user (full `@user:server` or a bare localpart, qualified with the homeserver's `server_name`) to the hive @@ -227,7 +227,7 @@ granting that group the one action `machinectl shell` needs); `choom` checks this itself and refuses up front with a message naming the requirement rather than letting systemd reject the exec later with an opaque polkit prompt. Same caveat as the socket grant: a shell opened -before the operator added you to `hive-admin` won't see it until you log +before the operator added you to `hive-admin` doesn't see it until you log back in — secondary group membership applies at login. It also needs the daemon socket, unlike the other exec-into-a-container diff --git a/hive-c0re/src/matrix.rs b/hive-c0re/src/matrix.rs index e3cd205d..1c2b16fa 100644 --- a/hive-c0re/src/matrix.rs +++ b/hive-c0re/src/matrix.rs @@ -1103,8 +1103,12 @@ mod is_make_admin_success_tests { /// /// ⚠️ Requires the **sender** to be an admin already — tuwunel only /// treats a message as a command when its sender is in the admin room. -/// So this promotes a *second* user; it cannot bootstrap the first one. -/// That is what the `admin_execute` entry in `hive-matrix.nix` is for. +/// `@hive:` is an ordinary account (`hive-matrix.nix` grants it no +/// `admin_execute` promotion), so this call has no working sender from +/// the hive and fails with the admin room's refusal. Promotion is a +/// swarm-level operation and is being rehomed as such; this stays here, +/// failing loudly, rather than justifying an over-privileged token that +/// all 13 ordinary call sites would also carry. /// /// Goes through the admin room rather than a direct HTTP call because /// tuwunel implements parts of the Synapse admin API but not user @@ -1144,6 +1148,10 @@ pub async fn promote_user_to_admin( /// it to the non-purgeable creds path so [`ensure_user_for`] can re-login /// on the next provisioning sweep. /// +/// ⚠️ Same admin-**sender** requirement as [`promote_user_to_admin`], and +/// the same consequence: `@hive:` is an ordinary account, so this fails +/// from the hive until the operation is rehomed at swarm level. +/// /// Returns the new password for use in subsequent `login_user` calls. pub async fn reset_user_password( client: &reqwest::Client, diff --git a/nix/packages/default.nix b/nix/packages/default.nix index 296a53a3..714307bd 100644 --- a/nix/packages/default.nix +++ b/nix/packages/default.nix @@ -163,12 +163,12 @@ in # rather than every hive's. swarm-nats-auth = mkBinPackage "swarm-nats-auth" "hyperhive swarm queue auth-callout responder"; - # The matrix admin credential's minter. Out of `daemonBins` for the same + # The `@hive:` access token's minter. Out of `daemonBins` for the same # "runs *inside* a container, not on the host" reason as the responder # above, and with a second one: putting it in the core bundle would place # the binary that reads the appservice token on every hive's filesystem, # which is the arrangement it exists to end. - swarm-matrix-minter = mkBinPackage "swarm-matrix-minter" "hyperhive matrix admin-credential minter"; + swarm-matrix-minter = mkBinPackage "swarm-matrix-minter" "hyperhive matrix @hive: access-token minter"; # The only process allowed to write swarm-authelia's users database — # same "runs *inside* a container, not on the host" placement as