# How to Add Custom YARA Rules for Specific Threat Detection in SkillSpector

> Learn to add custom YARA rules to NVIDIA SkillSpector for precise threat detection. Enhance your security analysis by integrating your own signatures using the --yara-rules-dir flag.

- Repository: [NVIDIA Corporation/SkillSpector](https://github.com/NVIDIA/SkillSpector)
- Tags: how-to-guide
- Published: 2026-07-09

---

**NVIDIA/SkillSpector supports custom YARA rules by accepting a directory of `.yar` or `.yara` files through the `--yara-rules-dir` CLI flag, merging them with built-in signatures via the [`static_yara.py`](https://github.com/NVIDIA/SkillSpector/blob/main/static_yara.py) analyzer.**

NVIDIA/SkillSpector ships with a static analyzer that applies YARA signatures to skill files, detecting threats like webshells and crypto-miners. Adding custom YARA rules for specific threat detection in SkillSpector allows security teams to extend coverage for proprietary indicators of compromise without modifying the core codebase.

## Understanding the YARA Analyzer Architecture

The YARA integration resides in **[`static_yara.py`](https://github.com/NVIDIA/SkillSpector/blob/main/static_yara.py)**, which automatically invokes during every scan to match files against threat signatures.

### Core Components

The analyzer relies on three key files:

- **[`static_yara.py`](https://github.com/NVIDIA/SkillSpector/blob/main/static_yara.py)**: The main analyzer node located at [`src/skillspector/nodes/analyzers/static_yara.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/nodes/analyzers/static_yara.py) that handles rule compilation, caching, and file matching.
- **[`state.py`](https://github.com/NVIDIA/SkillSpector/blob/main/state.py)**: Stores the custom rules path in shared state under the key `"yara_rules_dir"` (line 91).
- **[`cli.py`](https://github.com/NVIDIA/SkillSpector/blob/main/cli.py)**: Registers the `--yara-rules-dir` command-line option and injects its value into the analysis state (lines 202-208).

### Rule Loading and Caching Pipeline

When processing custom rules, the `_load_rules(extra_dir)` method executes a five-stage pipeline:

1. **Collection**: `_collect_rule_files` gathers all `.yar` and `.yara` files from both the built-in directory (`src/skillspector/yara_rules/`) and the user-supplied directory.
2. **Fingerprinting**: `_content_hash` computes a hash of all rule file contents to enable module-level caching.
3. **Namespacing**: `_build_namespace_map` assigns unique namespaces to prevent rule name collisions between built-in and custom signatures.
4. **Compilation**: The system attempts bulk compilation via `yara.compile(filepaths=...)`. If bulk compilation fails, it falls back to per-file compilation, skipping any syntactically invalid rules.
5. **Caching**: Stores the compiled `yara.Rules` object and content hash for subsequent scans.

During the actual scan, the `_match_file` method reads each source file and applies the compiled rules. For every match, `_parse_meta` extracts YARA metadata (category, severity, confidence, description) and maps it to SkillSpector's internal `Severity` enum, producing an `AnalyzerFinding`.

## Creating Custom YARA Rules for SkillSpector

Custom rules must follow specific conventions to integrate with SkillSpector's finding system.

### Required File Structure

Create a directory containing one or more files with `.yar` or `.yara` extensions. The analyzer recursively collects all matching files from the specified path.

### Metadata Schema Requirements

Each rule must include specific meta fields that map to SkillSpector's finding structure:

- **`category`**: Threat classification (e.g., "malware", "suspicious", "backdoor")
- **`severity`**: Maps to the internal `Severity` enum (CRITICAL, HIGH, MEDIUM, LOW)
- **`confidence`**: Float value between 0 and 1 indicating detection reliability
- **`description`**: Human-readable explanation of the threat

```bash
mkdir my_yara_rules
cat > my_yara_rules/malicious_download.yar <<'EOF'
rule malicious_download {
    meta:
        category = "malware"
        severity = "CRITICAL"
        confidence = "0.9"
        description = "Detects suspicious downloader binaries"
    strings:
        $a = "wget" nocase
        $b = "curl" nocase
    condition:
        any of them
}
EOF

```

## Loading Custom Rules via CLI and Python API

SkillSpector exposes custom rule loading through both command-line and programmatic interfaces.

### Command-Line Interface Method

Pass the `--yara-rules-dir` flag when invoking the scan command:

```bash
skillspector scan path/to/skill \
    --yara-rules-dir ./my_yara_rules \
    --format json \
    --output report.json

```

The system automatically merges your custom rules with the built-in set located in `src/skillspector/yara_rules/`.

### Programmatic API Integration

Import `_scan_state` and `_scan_multi_skill` from the CLI module to configure scans programmatically:

```python
from skillspector.cli import _scan_state, _scan_multi_skill
from pathlib import Path

state = _scan_state(
    skill_path="path/to/skill",
    format="json",
    no_llm=True,
    yara_rules_dir=str(Path("./my_yara_rules").resolve()),
    verbose=False,
)
report = _scan_multi_skill(*state)   # returns a dict with findings

print(report["findings"])

```

## Debugging and Verifying Rule Compilation

To verify that SkillSpector correctly loaded and compiled your custom signatures, use the `_load_rules` helper directly:

```python
from skillspector.nodes.analyzers import static_yara
from pathlib import Path

# Force reload with a temporary directory

rules = static_yara._load_rules(Path("./my_yara_rules"))
print(f"Compiled {len(rules)} rule(s)" if rules else "No rules compiled")

```

This bypasses the cache and returns the compiled `yara.Rules` object, allowing you to confirm that syntax errors or namespace conflicts did not prevent loading.

## Summary

- Place custom YARA rules in a directory with `.yar` or `.yara` extensions and pass the path via `--yara-rules-dir` to extend SkillSpector's detection capabilities.
- The **[`static_yara.py`](https://github.com/NVIDIA/SkillSpector/blob/main/static_yara.py)** analyzer merges custom rules with built-in signatures, computes content hashes for caching, and handles namespace deduplication automatically.
- Each rule must include **`category`**, **`severity`**, **`confidence`**, and **`description`** metadata fields to generate proper `AnalyzerFinding` objects.
- The system falls back to per-file compilation if bulk compilation fails, skipping invalid rules rather than failing the entire scan.
- Use the **`_load_rules`** helper for debugging compilation issues without running a full scan.

## Frequently Asked Questions

### What file extensions does SkillSpector recognize for YARA rules?

SkillSpector recognizes `.yar` and `.yara` extensions. The `_collect_rule_files` method recursively scans the provided directory and ignores files with other extensions.

### How does SkillSpector handle duplicate rule names between built-in and custom rules?

The **`_build_namespace_map`** function assigns unique namespaces to each rule file, preventing name collisions between built-in rules in `src/skillspector/yara_rules/` and your custom signatures.

### Can I override built-in rules with custom signatures?

Yes. When you specify `--yara-rules-dir`, SkillSpector loads both built-in and custom rules, with the custom directory taking precedence in the namespace map if identical rule names exist.

### What happens if a custom YARA rule contains syntax errors?

The compiler attempts bulk compilation first. If that fails, it falls back to per-file compilation and skips individual files with syntax errors while continuing to load valid rules. This ensures one malformed rule does not break the entire analysis pipeline.