safe-chains 0.113.0

Auto-allow safe, read-only bash commands in agentic coding tools
Documentation
use crate::parse::Token;
use crate::verdict::{SafetyLevel, Verdict};

fn is_safe_nslookup(tokens: &[Token]) -> Verdict {
    if tokens.len() == 2 && (tokens[1] == "--help" || tokens[1] == "-h" || tokens[1] == "--version" || tokens[1] == "-V") {
        return Verdict::Allowed(SafetyLevel::Inert);
    }
    for t in &tokens[1..] {
        let s = t.as_str();
        if !s.starts_with('-') {
            continue;
        }
        if s == "-debug" || s == "-nodebug" || s == "-d2" {
            continue;
        }
        if s.starts_with("-type=")
            || s.starts_with("-query=")
            || s.starts_with("-port=")
            || s.starts_with("-timeout=")
            || s.starts_with("-retry=")
            || s.starts_with("-class=")
            || s.starts_with("-domain=")
            || s.starts_with("-querytype=")
        {
            continue;
        }
        return Verdict::Denied;
    }
    Verdict::Allowed(SafetyLevel::Inert)

}

pub(in crate::handlers::coreutils) fn dispatch(cmd: &str, tokens: &[Token]) -> Option<Verdict> {
    match cmd {
        "nslookup" => Some(is_safe_nslookup(tokens)),
        _ => None,
    }
}

pub(in crate::handlers::coreutils) fn command_docs() -> Vec<crate::docs::CommandDoc> {
    vec![
        crate::docs::CommandDoc::handler("nslookup", "https://man7.org/linux/man-pages/man1/nslookup.1.html",
            "Allowed: positional args, -debug, -nodebug, -d2, and valued options (-type=, -query=, -port=, -timeout=, -retry=, -class=, -domain=, -querytype=)."),
    ]
}

#[cfg(test)]
pub(in crate::handlers::coreutils) const REGISTRY: &[crate::handlers::CommandEntry] = &[
    crate::handlers::CommandEntry::Custom { cmd: "nslookup", valid_prefix: Some("nslookup example.com") },
];

#[cfg(test)]
mod tests {
    use crate::is_safe_command;
    fn check(cmd: &str) -> bool { is_safe_command(cmd) }

    safe! {
        nslookup_domain: "nslookup example.com",
        nslookup_server: "nslookup example.com 8.8.8.8",
        nslookup_type: "nslookup -type=MX example.com",
    }
}