c0re: chown per-agent state writes to agent uid:gid (#673)

This commit is contained in:
damocles 2026-05-31 00:23:19 +02:00 committed by Mara
commit 0cf703a939
3 changed files with 70 additions and 0 deletions

View file

@ -162,6 +162,24 @@ fn extract_token(output: &str) -> Option<String> {
.map(str::to_owned)
}
/// Best-effort chown `path` to the agent's container-local uid/gid.
/// Closes the gap where c0re (running as root on the host) writes
/// per-agent state files that the agent's non-root unix user then
/// can't read until the next container activation runs the chown
/// fixup in `harness-base.nix` (#673).
///
/// Silently no-ops when the container hasn't been built yet (passwd
/// file absent) or when the chown syscall fails — the activation
/// script remains the safety net.
fn chown_to_agent(name: &str, path: &Path) {
let Some((uid, gid)) = crate::lifecycle::agent_uid_gid(name) else {
return;
};
if let Err(e) = std::os::unix::fs::chown(path, Some(uid), Some(gid)) {
tracing::debug!(%name, path = %path.display(), error = %e, "forge: chown to agent failed");
}
}
/// Canonical email address for a hive agent's Forgejo account.
/// Must match the `user.email` set by `meta::render_flake` so commits
/// by the agent link back to their Forgejo profile page.
@ -335,6 +353,7 @@ async fn mint_and_persist_token(name: &str, path: &Path, scopes: &str) -> Result
std::fs::write(path, format!("{token}\n"))
.with_context(|| format!("write token to {}", path.display()))?;
let _ = std::fs::set_permissions(path, std::fs::Permissions::from_mode(0o600));
chown_to_agent(name, path);
tracing::info!(%name, path = %path.display(), "forge: persisted access token");
Ok(())
}