diff --git a/hive-c0re/src/gateway_nginx.rs b/hive-c0re/src/gateway_nginx.rs index 1975d8ce..ef869cf5 100644 --- a/hive-c0re/src/gateway_nginx.rs +++ b/hive-c0re/src/gateway_nginx.rs @@ -30,12 +30,15 @@ use std::path::PathBuf; use crate::agent_sockets; use crate::lifecycle::{self, MANAGER_NAME}; -const HOST_CONF_PATH: &str = "/var/lib/hyperhive/agents.conf"; +const HOST_CONF_PATH: &str = "/var/lib/hyperhive/gateway/agents.conf"; /// Host-side path where c0re writes the generated nginx include file. -/// The gateway container bind-mounts `/var/lib/hyperhive/` at -/// `/run/hive-state/` so nginx inside can read it at -/// `/run/hive-state/agents.conf`. +/// The gateway container bind-mounts `/var/lib/hyperhive/gateway/` +/// (not the whole parent dir) at `/run/hive-state/` so nginx inside +/// can read it at `/run/hive-state/agents.conf`. Subdirectory scoping +/// avoids exposing the rest of `/var/lib/hyperhive/` (which may contain +/// forge tokens or other credentials) to the gateway container (argus 🟡 +/// on #872). #[must_use] pub fn host_conf_path() -> PathBuf { PathBuf::from(HOST_CONF_PATH) diff --git a/nix/modules/hive-gateway.nix b/nix/modules/hive-gateway.nix index 69ead4c9..ac25f6bd 100644 --- a/nix/modules/hive-gateway.nix +++ b/nix/modules/hive-gateway.nix @@ -228,7 +228,8 @@ in systemd.tmpfiles.rules = [ "d /run/hive-agent 0755 root root - -" "d /var/lib/hyperhive 0755 root root - -" - "f /var/lib/hyperhive/agents.conf 0644 root root - # Generated by hive-c0re — do not edit.\n" + "d /var/lib/hyperhive/gateway 0755 root root - -" + "f /var/lib/hyperhive/gateway/agents.conf 0644 root root - # Generated by hive-c0re — do not edit.\n" ]; containers.hive-gateway = { @@ -248,15 +249,15 @@ in hostPath = "/run/hive-agent"; isReadOnly = true; }; - # Bind-mount the hyperhive state dir so nginx can include the - # runtime-generated agents.conf. Read-only; c0re writes - # /var/lib/hyperhive/agents.conf on the host and the systemd - # path unit inside the container triggers nginx -s reload on - # each atomic rename (#869). Pre-created by a tmpfiles rule so - # nspawn always finds the source at boot (c0re also writes it - # on first startup, but the container may start before c0re). + # Bind-mount ONLY the gateway-specific subdir of the hyperhive + # state dir. Scoped to /var/lib/hyperhive/gateway/ rather than + # the whole parent so the gateway container can't read forge + # tokens or other files that may live at the parent level (argus + # 🟡 on #872). c0re writes agents.conf under this subdir; + # the systemd path unit inside the container fires nginx -s reload + # on each atomic rename. Pre-created by a tmpfiles rule. bindMounts."/run/hive-state" = { - hostPath = "/var/lib/hyperhive"; + hostPath = "/var/lib/hyperhive/gateway"; isReadOnly = true; }; config = @@ -408,7 +409,7 @@ in }; systemd.services.hive-gateway-nginx-reload = { - description = "Reload nginx after agents.conf change (#869)"; + description = "Reload nginx after agents.conf change"; # Don't block any target — fires only when the path unit # triggers it. serviceConfig = {