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

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 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, which automatically invokes during every scan to match files against threat signatures.

Core Components

The analyzer relies on three key files:

  • static_yara.py: The main analyzer node located at src/skillspector/nodes/analyzers/static_yara.py that handles rule compilation, caching, and file matching.
  • state.py: Stores the custom rules path in shared state under the key "yara_rules_dir" (line 91).
  • 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
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:

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:

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:

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 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.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →