diff --git a/hive-priv/src/main.rs b/hive-priv/src/main.rs index 6060cffa..ae06640b 100644 --- a/hive-priv/src/main.rs +++ b/hive-priv/src/main.rs @@ -3019,7 +3019,17 @@ async fn sync_agent_tmpfiles(agents: &[AgentTmpfilesEntry]) -> Result<(String, S // Parent dirs — created with permissive mode so hive-c0re can make subdirs. // /run/hyperhive itself is also a RuntimeDirectory of hive-c0re.service; the // tmpfiles.d entry here ensures it exists before hive-c0re starts (boot race). - content.push_str("d /run/hyperhive 0750 hive-core hive-core -\n"); + // + // 0751, not 0750: must match hive-c0re.service's own `RuntimeDirectoryMode` + // and `docs/trust-boundary/boundary.md` — the extra `--x` on `other` is what + // lets a `hive-admin`-only user (no `hive-core` membership) traverse into the + // directory to reach `host.sock`; without it that user gets a permission + // denied opening the socket despite correct group membership on the socket + // itself. A mismatch here isn't just cosmetic: this line is regenerated and + // re-applied on every agent spawn/destroy via `systemd-tmpfiles --create`, + // so a stale `0750` here actively re-asserts the old, wrong mode far more + // often than a reboot does. + content.push_str("d /run/hyperhive 0751 hive-core hive-core -\n"); writeln!(content, "d {AGENT_RUNTIME_ROOT} 0755 hive-core hive-core -").ok(); // `hive-core`, not root: c0re does the `create_dir_all` for a new agent's // subdir itself, so a root-owned parent EACCESes on the first spawn of a