fix(grasp-audit): keep signing secrets out of git

Strip both the audit identity and relay-owner secret variables at the existing hermetic git subprocess boundary. This prevents git hooks, credential helpers, remote helpers, and their descendants from inheriting signing keys.
This commit is contained in:
DanConwayDev
2026-08-05 09:11:12 +01:00
parent 633224bc81
commit 5df2d0ddfe
+22
View File
@@ -8,6 +8,11 @@
use std::process::Command;
/// Signing secrets that audit processes may legitimately hold but git never
/// needs. Removing them here also removes them from hooks, credential helpers,
/// remote helpers, and any other process git starts.
const SIGNING_SECRET_ENV_VARS: [&str; 2] = ["GRASP_AUDIT_NSEC", "NGIT_RELAY_OWNER_NSEC"];
/// Build a `git` [`Command`] that is hermetic with respect to ambient git
/// configuration.
///
@@ -44,6 +49,9 @@ pub fn git_command() -> Command {
cmd.env_remove("GIT_DIR");
cmd.env_remove("GIT_WORK_TREE");
cmd.env_remove("GIT_INDEX_FILE");
for name in SIGNING_SECRET_ENV_VARS {
cmd.env_remove(name);
}
cmd
}
@@ -57,6 +65,20 @@ mod tests {
use std::os::unix::fs::PermissionsExt;
use std::path::{Path, PathBuf};
#[test]
fn git_commands_do_not_inherit_signing_secrets() {
let command = git_command();
for secret_name in SIGNING_SECRET_ENV_VARS {
assert!(
command
.get_envs()
.any(|(name, value)| name == secret_name && value.is_none()),
"{secret_name} must be removed from git's environment"
);
}
}
/// Write a global gitconfig whose settings demonstrably break the fixture
/// recipe when they leak in: `core.hooksPath` and `init.templateDir` both
/// deliver a pre-commit hook that always fails, `init.defaultBranch`