From d96a924d77e2628a9a1a7db7cac0deea2a52b4c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?m=C3=BCde?= Date: Wed, 3 Jun 2026 00:52:42 +0200 Subject: [PATCH] fix(#702): set git safe.directory for cross-user repo reads MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Privsep splits repo ownership: hive-priv (root) fetches the hive-core-owned meta/applied repos via nix, and hive-c0re (hive-core) fetches the agent-owned proposed-config repos. git/libgit2's dubious-ownership guard rejects both ('repository path is not owned by current user'), failing every rebuild. Install a root-trusted gitconfig with safe.directory=* in each service's HOME; both already have read access — this only satisfies the guard. --- nix/modules/hive-c0re.nix | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/nix/modules/hive-c0re.nix b/nix/modules/hive-c0re.nix index be2a4574..3fba5127 100644 --- a/nix/modules/hive-c0re.nix +++ b/nix/modules/hive-c0re.nix @@ -15,6 +15,19 @@ }: let cfg = config.services.hyperhive.c0re; + + # Privsep splits ownership across users, so git/libgit2's dubious- + # ownership guard trips on legitimate cross-user reads: hive-priv (root) + # fetches the hive-core-owned meta/applied repos via nix, and hive-c0re + # (hive-core) fetches the agent-owned proposed-config repos. Both + # processes are trusted and can already read the files; this gitconfig + # only satisfies the ownership guard. libgit2 honours the literal `*` + # (mid-path globs aren't supported, so per-agent repos can't be listed); + # in practice these processes only ever touch hyperhive's own repos. + safeDirGitconfig = pkgs.writeText "hyperhive-safe-gitconfig" '' + [safe] + directory = * + ''; in { # The forge is part of the standard install — hive-c0re mirrors @@ -446,6 +459,11 @@ in # plus the `agents/` dir node itself (not its contents) so c0re can # still create new per-agent subdirs. ExecStartPre = [ + # Install the safe.directory gitconfig at $HOME/.gitconfig + # (HOME = /var/lib/hyperhive) so c0re's `git fetch`/`rev-parse` + # against the agent-owned proposed repos pass the ownership guard. + # Placed before the chown below so it's chowned to hive-core too. + "+-${pkgs.coreutils}/bin/cp ${safeDirGitconfig} /var/lib/hyperhive/.gitconfig" "+-${pkgs.findutils}/bin/find /var/lib/hyperhive -mindepth 1 -maxdepth 1 -not -name agents -exec ${pkgs.coreutils}/bin/chown -R hive-core:hive-core {} +" "+-${pkgs.coreutils}/bin/chown hive-core:hive-core /var/lib/hyperhive/agents" ]; @@ -557,6 +575,11 @@ in ProtectSystem = "false"; # Writable HOME for nix's caches (see environment.HOME above). StateDirectory = "hive-priv"; + # nix (run here as root for `nixos-container update --flake + # /var/lib/hyperhive/meta#`) fetches the hive-core-owned + # meta/applied repos; libgit2 refuses them without safe.directory. + # See safeDirGitconfig above. + ExecStartPre = "+-${pkgs.coreutils}/bin/cp ${safeDirGitconfig} /var/lib/hive-priv/.gitconfig"; }; }; };