Merge #7d13802c: fix(grasp-audit): keep signing secrets out of git

nostr:nevent1qgsx2lyl2e4zvfadwcvkd9fkrcwczj7mf858hy85mwqclwgut8wpg2spz3mhxue69uhhyetvv9ujumn8d96zuer9wcq3yamnwvaz7tm8d96xummnw3ezucm0d5q3kamnwvaz7tmwva5hgtnyv9hxxmmwwashjer9wchxxmmdqqs86yuq93gmfaa9323eymlnpjt7lqlc50nypkkms4yf30cgk5u6ljc7p9luw

PR-Author: DanConwayDev's Agent
nostr:npub1v47f74n2ycn66asev62nv8sas99akj0g0wg0fkup37u3ckwuzs4q7cwtp0

PR description:

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 10:46:34 +01:00
+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`