From 9451ebfb24cacce4755c4318848e76d491722a36 Mon Sep 17 00:00:00 2001 From: atlas Date: Fri, 10 Jul 2026 13:07:44 +0200 Subject: [PATCH] fix(#2308): overlay --tmpfs on /knowledge/.git to hide host git credentials The knowledge repo is cloned with credentials embedded in .git/config; those credentials survive on disk and the entire LOCAL_DIR (including .git/) is bind-mounted read-only into every agent container. Any agent (or prompt-injected PR build) can read the site-admin token via cat /knowledge/.git/config. Defense-in-depth layer: in write_nspawn_flags, append --tmpfs=/knowledge/.git after the --bind-ro=.../knowledge flag whenever the /knowledge bind mount is present. systemd-nspawn processes the tmpfs after the bind, overlaying an empty in-memory directory over .git/ inside the container. Agents see the working-tree documents but not the repo metadata or stored credentials. This is independent of the complementary fix in workers/knowledge.rs (stop embedding credentials in .git/config in the first place). Both layers together provide defense-in-depth: even if a future credential accidentally reaches .git/config, it stays off the container floor. Closes part of issue 2308 (bind-mount isolation layer). --- hive-priv/src/main.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/hive-priv/src/main.rs b/hive-priv/src/main.rs index 9c4adcd2..615e0794 100644 --- a/hive-priv/src/main.rs +++ b/hive-priv/src/main.rs @@ -1502,6 +1502,19 @@ fn write_nspawn_flags( format!("{flag}={}:{}", b.host_path, b.container_path) }) .collect(); + // Defense-in-depth for the knowledge bind-mount: overlay an empty tmpfs + // on /knowledge/.git so the repo metadata (including any credentials the + // host-side git worker embedded in .git/config) is invisible inside agent + // containers. Agents only need the working-tree documents; .git/ has no + // legitimate use in-container. The --tmpfs must come after the --bind-ro + // so nspawn processes it as an overlay on top of the already-mounted tree. + // `crate::knowledge::CONTAINER_MOUNT` is "/knowledge" (hive-c0re const). + if binds + .iter() + .any(|b| b.container_path.as_str() == "/knowledge") + { + flags.push("--tmpfs=/knowledge/.git".to_owned()); + } // Credential forwarding: nspawn loads each host secret into the // container's credential store under ``; inner units inherit it // via `LoadCredential=`. Validated (name charset + bind-path