From 47d53f5c235c798895c19ee0581d195a7292165e Mon Sep 17 00:00:00 2001 From: atlas Date: Fri, 11 Sep 2026 19:09:02 +0200 Subject: [PATCH] hive-c0re: one binding for /run/hyperhive's mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The mode was declared twice in this file — the service unit's RuntimeDirectoryMode and the socket unit's DirectoryMode — with only a prose "must match" note tying them. Whichever unit activates first creates the directory, so they cannot be allowed to disagree. Both literals are in one file, so they become a `let`. Deleting a copy beats checking it, and unlike rendering the mode into hive-priv it costs no config knob for a value nobody should ever set. hive-priv's tmpfiles.d entry for the same path is a third declaration that cannot read this binding, and is left in step by hand. An earlier revision of this branch added a CI check for exactly that pair; mara pointed out it was keyed to one path rather than to the class, and looking for the general case found two more paths declared by more than one mechanism — including /run/hive-agent, where hive-gateway's tmpfiles rule and hive-priv's generated one disagreed on the owner and the winner depended on systemd's read order. That check is being reworked as a general one, tracked separately, so nothing about it rides in here. Verified: nix fmt (713 traversed, 5 formatted, 0 changed); the three scripts/check-*.sh lints all exit 0 with the tree staged; .forgejo/ is now byte-identical to main and the diff is this one file. checks.module-eval reported 91 module properties hold on the previous revision of this branch — the only nix change since is comment text inside the same let block, which cannot affect evaluation. --- nix/host-modules/hive-c0re/default.nix | 30 +++++++++++++++----------- 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/nix/host-modules/hive-c0re/default.nix b/nix/host-modules/hive-c0re/default.nix index 83c753f4..ddcb674f 100644 --- a/nix/host-modules/hive-c0re/default.nix +++ b/nix/host-modules/hive-c0re/default.nix @@ -13,6 +13,20 @@ let cfg = config.services.hyperhive.c0re; + # `/run/hyperhive`'s mode. Held in one place because whichever of the two + # units below activates first creates the directory, so they cannot be + # allowed to disagree about what it should be. `0751` is traverse-only, no + # listing: `hive-admin` members reach `host.sock` without root, while the + # socket's own `0660 hive-admin` gates the connection and the per-agent + # subdirs keep their own perms. + # + # hive-priv writes a tmpfiles.d entry for this same path and cannot read + # this binding, so the two are kept in step by hand. Divergence is not + # cosmetic: tmpfiles then tries to fchmod a directory hive-priv has no + # write access to, the whole `--create` run fails, and a single WARN per + # sync is the only symptom. + runtimeDirMode = "0751"; + baoDeploy = config.services.hyperhive.deploy.bao; # Held in one place because the LoadCredential below and the `BAO_*` # environment in ./environment.nix have to agree on when they exist: a @@ -313,12 +327,7 @@ in Group = "hive-core"; SupplementaryGroups = [ "systemd-journal" ]; RuntimeDirectory = "hyperhive"; - # 0751 (traverse-only, no listing) so `hive-admin` operators can reach - # the host admin socket (`SocketGroup = "hive-admin"`, 0660) without - # root. Others can traverse but not list; the socket + per-agent - # subdirs gate access by their own perms. Matches the socket unit's - # DirectoryMode. - RuntimeDirectoryMode = "0751"; + RuntimeDirectoryMode = runtimeDirMode; RuntimeDirectoryPreserve = "yes"; StateDirectory = "hyperhive"; StateDirectoryMode = "0750"; @@ -416,12 +425,9 @@ in # so it stays effectively root-only. See docs/trust-boundary/boundary.md. SocketMode = "0660"; SocketGroup = "hive-admin"; - # `0751` (traverse-only, no listing) so hive-admin can reach the socket - # path — the socket's own `0660 hive-admin` gates the connection, and - # the per-agent subdirs under here keep their own restrictive perms. - # Must match the service unit's RuntimeDirectoryMode. DirectoryMode is - # only consulted when the dir is absent at socket-unit activation. - DirectoryMode = "0751"; + # Only consulted when the directory is absent at socket-unit + # activation — i.e. when this unit wins the race with the service. + DirectoryMode = runtimeDirMode; }; }; };