vv-agent 0.6.0

VectorVein agent runtime, SDK, CLI, tools, and workspace backends
Documentation
pub(crate) fn is_sensitive_path(path: &str) -> bool {
    let normalized = path.replace('\\', "/");
    let parts = normalized
        .trim_matches('/')
        .split('/')
        .filter(|part| !part.is_empty())
        .collect::<Vec<_>>();
    let Some(name) = parts.last().map(|value| value.to_ascii_lowercase()) else {
        return false;
    };

    const EXACT: &[&str] = &[
        ".env",
        ".npmrc",
        ".pypirc",
        ".netrc",
        "credentials",
        "id_rsa",
        "id_dsa",
        "id_ecdsa",
        "id_ed25519",
    ];
    const SUFFIXES: &[&str] = &[".key", ".pem", ".p8", ".p12", ".pfx"];
    const TOKENS: &[&str] = &[
        "credential",
        "credentials",
        "secret",
        "secrets",
        "token",
        "private_key",
    ];
    const CONFIG_DIRS: &[&str] = &[
        ".config", "config", "configs", "keys", "secrets", ".ssh", ".aws", ".gcp",
    ];

    if EXACT.contains(&name.as_str()) {
        return true;
    }
    if name.starts_with(".env.")
        && !matches!(
            name.as_str(),
            ".env.example" | ".env.sample" | ".env.template"
        )
    {
        return true;
    }
    if ["secrets.", "secret."]
        .iter()
        .any(|prefix| name.starts_with(prefix))
    {
        return true;
    }
    if SUFFIXES.iter().any(|suffix| name.ends_with(suffix)) {
        return true;
    }
    if name.ends_with(".env") {
        return true;
    }
    if TOKENS.iter().any(|token| name.contains(token)) {
        return parts[..parts.len().saturating_sub(1)]
            .iter()
            .any(|part| CONFIG_DIRS.contains(&part.to_ascii_lowercase().as_str()));
    }
    false
}

pub(crate) fn sensitive_rg_exclude_globs() -> &'static [&'static str] {
    &[
        "!**/.env",
        "!**/.npmrc",
        "!**/.pypirc",
        "!**/.netrc",
        "!**/credentials",
        "!**/id_rsa",
        "!**/id_dsa",
        "!**/id_ecdsa",
        "!**/id_ed25519",
        "!**/*.key",
        "!**/*.pem",
        "!**/*.p8",
        "!**/*.p12",
        "!**/*.pfx",
        "!**/secret.*",
        "!**/secrets.*",
        "!**/config/**/*token*",
        "!**/config/**/*credential*",
        "!**/config/**/*secret*",
        "!**/config/**/*private_key*",
        "!**/configs/**/*token*",
        "!**/configs/**/*credential*",
        "!**/configs/**/*secret*",
        "!**/configs/**/*private_key*",
        "!**/keys/**/*token*",
        "!**/keys/**/*credential*",
        "!**/keys/**/*secret*",
        "!**/keys/**/*private_key*",
        "!**/secrets/**/*token*",
        "!**/secrets/**/*credential*",
        "!**/secrets/**/*secret*",
        "!**/secrets/**/*private_key*",
        "!**/.ssh/**/*token*",
        "!**/.ssh/**/*credential*",
        "!**/.ssh/**/*secret*",
        "!**/.ssh/**/*private_key*",
        "!**/.aws/**/*token*",
        "!**/.aws/**/*credential*",
        "!**/.aws/**/*secret*",
        "!**/.aws/**/*private_key*",
        "!**/.gcp/**/*token*",
        "!**/.gcp/**/*credential*",
        "!**/.gcp/**/*secret*",
        "!**/.gcp/**/*private_key*",
    ]
}

pub(crate) fn sensitive_path_is_covered_by_rg_excludes(path: &str) -> bool {
    let normalized = path.replace('\\', "/");
    let parts = normalized
        .trim_matches('/')
        .split('/')
        .filter(|part| !part.is_empty())
        .collect::<Vec<_>>();
    let Some(name) = parts.last() else {
        return false;
    };

    const EXACT: &[&str] = &[
        ".env",
        ".npmrc",
        ".pypirc",
        ".netrc",
        "credentials",
        "id_rsa",
        "id_dsa",
        "id_ecdsa",
        "id_ed25519",
    ];
    const SUFFIXES: &[&str] = &[".key", ".pem", ".p8", ".p12", ".pfx"];
    const TOKENS: &[&str] = &[
        "credential",
        "credentials",
        "secret",
        "secrets",
        "token",
        "private_key",
    ];
    const CONFIG_DIRS: &[&str] = &[
        "config", "configs", "keys", "secrets", ".ssh", ".aws", ".gcp",
    ];

    if EXACT.contains(name) {
        return true;
    }
    if ["secret.", "secrets."]
        .iter()
        .any(|prefix| name.starts_with(prefix))
    {
        return true;
    }
    if SUFFIXES.iter().any(|suffix| name.ends_with(suffix)) {
        return true;
    }
    if TOKENS.iter().any(|token| name.contains(token)) {
        return parts[..parts.len().saturating_sub(1)]
            .iter()
            .any(|part| CONFIG_DIRS.contains(part));
    }
    false
}

#[cfg(test)]
mod tests {
    use super::{is_sensitive_path, sensitive_path_is_covered_by_rg_excludes};

    #[test]
    fn flags_common_secret_paths() {
        for path in [
            ".env",
            ".env.local",
            "keys/AuthKey_ABC123.p8",
            "keys/private.key",
            ".ssh/id_rsa",
            "config/service_token.json",
            "secrets.production",
            ".npmrc",
        ] {
            assert!(is_sensitive_path(path), "{path}");
        }
    }

    #[test]
    fn allows_normal_project_files() {
        for path in [
            ".env.example",
            "src/tokenizer.rs",
            "docs/secrets-management.md",
            "config/example.json",
        ] {
            assert!(!is_sensitive_path(path), "{path}");
        }
    }

    #[test]
    fn rg_exclude_coverage_is_case_sensitive_like_rg_globs() {
        assert!(sensitive_path_is_covered_by_rg_excludes("private.pem"));
        assert!(sensitive_path_is_covered_by_rg_excludes(
            "keys/AuthKey_ABC123.p8"
        ));
        assert!(!sensitive_path_is_covered_by_rg_excludes(
            "keys/AuthKey_ABC123.P8"
        ));
        assert!(!sensitive_path_is_covered_by_rg_excludes(
            ".config/service_token.json"
        ));
    }
}