Compare commits

...
Author SHA1 Message Date
atlas
467d3fa82e fix(#1845): correct ProtectSystem=strict comment (nix called directly via NIX_REMOTE=daemon) 2026-07-04 13:44:42 +02:00
atlas
7e83d906b2 fix(#1845): upgrade hive-c0re ProtectSystem full → strict
hive-c0re never writes outside its StateDirectory + RuntimeDirectory:
  - /etc writes (nixos-containers) go through hive-priv, not c0re
  - /etc/hyperhive/serve.json is read-only at startup (written by the
    NixOS activation script, not by the daemon)
  - nix builds delegate to hive-priv via the privileged Unix socket;
    hive-c0re itself never invokes nix directly

So strict is safe: systemd keeps /var/lib/hyperhive (StateDirectory)
and /run/hyperhive (RuntimeDirectory) writable; everything else is
read-only, shrinking the writable attack surface to exactly what the
service needs.
2026-07-04 13:44:42 +02:00

View file

@ -1104,13 +1104,19 @@ in
NoNewPrivileges = true; # already runs as unprivileged user
PrivateTmp = true; # uses StateDirectory for tmpfiles, not /tmp
ProtectHome = true; # HOME = /var/lib/hyperhive; no /home/* access needed
# "full" makes /usr, /etc, /boot read-only. Safe: c0re never
# writes to any of those paths directly — all /etc writes (e.g.
# /etc/nixos-containers) go through hive-priv, and reads from
# /etc/hyperhive/serve.json are read-only. "strict" (everything
# read-only) requires carefully auditing ReadWritePaths for every
# nix store path c0re touches and is deferred to a follow-up.
ProtectSystem = "full";
# "strict" makes the entire filesystem read-only except for
# StateDirectory (/var/lib/hyperhive) and RuntimeDirectory
# (/run/hyperhive), which systemd keeps writable. No
# ReadWritePaths needed beyond the managed directories because:
# - nix is invoked directly (lifecycle, meta, flake_check), but
# NIX_REMOTE=daemon routes all store writes through the host
# daemon — hive-c0re never writes to /nix itself.
# - flake.lock ops land in the meta worktree under StateDirectory
# (kept writable by systemd).
# - nix build worktrees live in PrivateTmp, not /tmp.
# - /etc writes (bind-mount edits) go through hive-priv via the
# privileged socket; /etc/hyperhive/serve.json is read-only.
ProtectSystem = "strict";
ProtectKernelTunables = true; # no sysctl writes
ProtectKernelLogs = true; # reads logs via systemd-journal group, not /dev/kmsg
ProtectControlGroups = true; # cgroup writes go through hive-priv, not c0re directly