use regex::Regex;
use std::sync::LazyLock;
use crate::facts::shell::Argv;
#[expect(
clippy::expect_used,
reason = "static pattern literal validated by tests"
)]
pub static SENSITIVE_PATH: LazyLock<Regex> = LazyLock::new(|| {
Regex::new(concat!(
r"(?ix)",
r"(?:",
r"(?:~|\$HOME|\$\{HOME\})/\.ssh(?:/|\b)",
r"|(?:~|\$HOME|\$\{HOME\})/\.aws(?:/|\b)",
r"|(?:~|\$HOME|\$\{HOME\})/\.config/gcloud(?:/|\b)",
r"|(?:~|\$HOME|\$\{HOME\})/\.kube/config\b",
r"|(?:~|\$HOME|\$\{HOME\})/\.docker/config\.json\b",
r"|\bid_(?:rsa|ed25519|ecdsa)\b",
r"|(?:^|/|\s|[*?\[\]=])\.env(?:\.[A-Za-z0-9_-]+)?\b",
r"|\b\.npmrc\b",
r"|\b\.pypirc\b",
r"|\S+\.tfstate\b",
r"|(?-i:-----BEGIN\s+[A-Z\s]+PRIVATE\s+KEY-----)",
r")",
))
.expect("SENSITIVE_PATH regex")
});
pub(super) fn argv_references_sensitive(argv: &Argv) -> bool {
if SENSITIVE_PATH.is_match(&argv.head) {
return true;
}
if argv.args.iter().any(|a| SENSITIVE_PATH.is_match(a)) {
return true;
}
argv.env_assignments
.iter()
.any(|e| SENSITIVE_PATH.is_match(&e.value))
}
#[cfg(test)]
mod tests {
use super::*;
use std::sync::LazyLock;
#[test]
fn all_regexes_compile() {
LazyLock::force(&SENSITIVE_PATH);
}
}