swarm-controller: revoke matrix admin from former operators
The operator admin sync now also takes homeserver admin away. It records each user id it sends `make-user-admin` for in `operator-matrix-admins.json` under the controller's state directory (written to a temporary file and renamed over it; a missing file is an empty set). On each pass, a recorded account that is no longer in authelia's `admins` group but is still joined to `#admins:<server>` is sent `!admin users force-leave-room <user> <admin room id>` as `@swarm`, over the same `/_matrix` path the grant uses. Leaving that room is what ends tuwunel admin. It never revokes an admin it didn't grant, `@swarm`, tuwunel's server user (`@conduit:<server>`), an agent's account (the store's `hive-agent-*` cert roles, the same roster the agent account mint uses), or anyone in the new `services.hyperhive.swarm.matrix.adminSync.ignoreUsers` list. That list reaches the daemon as `SWARM_CONTROLLER_MATRIX_ADMIN_SYNC_IGNORE_USERS`. It also never sends a revoke that would leave `#admins` with no member besides `@swarm` and the server user. A revoke is sent at most once per account per controller process, like a grant. A recorded account that is out of both the group and the room is dropped from the file. Closes #4799
This commit is contained in:
parent
40d6f30834
commit
962c1548eb
8 changed files with 515 additions and 41 deletions
|
|
@ -147,6 +147,18 @@ in
|
|||
'';
|
||||
};
|
||||
|
||||
adminSync.ignoreUsers = lib.mkOption {
|
||||
type = lib.types.listOf (lib.types.strMatching "@[^:[:space:]]+:[^[:space:]]+");
|
||||
default = [ ];
|
||||
example = [ "@mara:example.org" ];
|
||||
description = ''
|
||||
Full matrix user ids `swarm-controller`'s operator admin sync never
|
||||
revokes homeserver admin from. The sync revokes admin only from
|
||||
accounts it made admin itself, once their owner leaves authelia's
|
||||
`admins` group; an account listed here keeps admin regardless.
|
||||
'';
|
||||
};
|
||||
|
||||
# This homeserver always delegates login to the swarm's authelia, as
|
||||
# an OIDC relying party — matrix SSO (`m.login.sso`), offered
|
||||
# alongside password login. No toggle: a homeserver in a swarm is a
|
||||
|
|
|
|||
|
|
@ -877,6 +877,10 @@ in
|
|||
# nothing about it is unsafe to define on a host whose queue is
|
||||
# off (the daemon just has nothing to apply it to).
|
||||
SWARM_CONTROLLER_STALE_AFTER_SECS = toString cfg.staleAfterSeconds;
|
||||
# The accounts the operator admin sync never revokes. Whitespace-
|
||||
# separated: a matrix user id cannot contain a space. Consumed by
|
||||
# swarm-controller/src/matrix_account/operator_admin.rs.
|
||||
SWARM_CONTROLLER_MATRIX_ADMIN_SYNC_IGNORE_USERS = lib.concatStringsSep " " matrixCfg.adminSync.ignoreUsers;
|
||||
}
|
||||
// queueEnv
|
||||
// forgeEnv
|
||||
|
|
|
|||
|
|
@ -63,6 +63,16 @@ let
|
|||
swarm.matrix.gatewayHost = null;
|
||||
};
|
||||
|
||||
# An ignore list no default could supply, with two entries so the case below
|
||||
# also pins the separator the daemon splits on.
|
||||
controllerIgnoresAdmins = hive {
|
||||
deploy.swarm-controller.enable = true;
|
||||
swarm.matrix.adminSync.ignoreUsers = [
|
||||
"@keep-a:t.local"
|
||||
"@keep-b:t.local"
|
||||
];
|
||||
};
|
||||
|
||||
# The two authorities told apart. A deployment that self-signs both ends
|
||||
# points `clientCaFile` and `serverCaFile` at one file, so on the fixture
|
||||
# above the CA a hive is issued from and the CA the store is verified by are
|
||||
|
|
@ -127,6 +137,14 @@ let
|
|||
? SWARM_CONTROLLER_MATRIX_HOMESERVER_URL
|
||||
);
|
||||
}
|
||||
{
|
||||
# operator_admin.rs splits this on whitespace; an entry missing here is
|
||||
# an account the sync would revoke.
|
||||
name = "the controller is told the operator admin sync's ignore list";
|
||||
ok =
|
||||
controllerIgnoresAdmins.systemd.services.swarm-controller.environment.SWARM_CONTROLLER_MATRIX_ADMIN_SYNC_IGNORE_USERS
|
||||
or null == "@keep-a:t.local @keep-b:t.local";
|
||||
}
|
||||
{
|
||||
# Nothing asserted the PKI script before this, so a third leaf could be
|
||||
# added to it and every case still passed — measured, not assumed: the
|
||||
|
|
|
|||
Loading…
Reference in a new issue