feat(#972): tighten hive-priv systemd sandbox — ProtectSystem=strict + ReadWritePaths

Replace ProtectSystem=false with ProtectSystem=strict now that privsep
is complete (issue #702 closed) and hive-c0re runs as the non-root
hive-core user.

ReadWritePaths carves out the six paths hive-priv must write to at
runtime; everything else is read-only:

  /etc/nixos-containers   — writes <container>.conf (bind-mounts,
                            network isolation, nspawn flags)
  /run/hive               — fallback socket bind when LISTEN_FDS absent
  /run/hive-agent         — chown/chmod per-agent socket directories
  /run/systemd            — container@ drop-ins (resource limits) and
                            machinectl/systemd-machined machine state
  /var/lib/nixos-containers — container rootfs (nixos-container script)
  /nix                    — nix store + profile updates during
                            container create/update

PrivateTmp=true (already set) keeps /tmp private.
StateDirectory=hive-priv (already set) keeps /var/lib/hive-priv writable
for nix's fetch/eval cache (HOME points there).

nix flake check --no-build passes.
This commit is contained in:
atlas 2026-06-03 14:17:25 +02:00 committed by mara
commit 0e3df82504

View file

@ -745,9 +745,30 @@ in
User = "root";
PrivateTmp = true;
ProtectHome = true;
# hive-priv needs to write to /etc/nixos-containers/ and
# /run/systemd/system/ — "strict" would block both.
ProtectSystem = "false";
# Harden the file system view: strict makes the entire hierarchy
# read-only by default; ReadWritePaths carves out exactly the
# paths hive-priv must write to at runtime.
#
# Why each entry is needed:
# /etc/nixos-containers — writes <container>.conf (bind mounts,
# network isolation, nspawn flags)
# /run/hive — fallback socket bind if LISTEN_FDS is
# absent (normal path: socket-activated)
# /run/hive-agent — chown/chmod per-agent socket directories
# /run/systemd — container@ unit drop-ins (resource limits)
# + machinectl / systemd-machined state
# /var/lib/nixos-containers — container rootfs written by nixos-container
# /nix — nix store + profile updates during
# container create/update
ProtectSystem = "strict";
ReadWritePaths = [
"/etc/nixos-containers"
"/run/hive"
"/run/hive-agent"
"/run/systemd"
"/var/lib/nixos-containers"
"/nix"
];
# Writable HOME for nix's caches (see environment.HOME above).
StateDirectory = "hive-priv";
# nix (run here as root for `nixos-container update --flake