# Static Patterns Analyzers vs Semantic Security Discovery in NVIDIA SkillSpector

> Understand the difference between static patterns analyzers and semantic security discovery in NVIDIA SkillSpector. Learn how LLM reasoning differs from rule-based scanning for security.

- Repository: [NVIDIA Corporation/SkillSpector](https://github.com/NVIDIA/SkillSpector)
- Tags: deep-dive
- Published: 2026-06-18

---

**Static patterns analyzers perform deterministic, rule-based code scanning for concrete vulnerabilities, while semantic_security_discovery uses LLM reasoning to infer higher-level security concerns from skill intent.**

The NVIDIA SkillSpector repository provides two fundamentally different security analysis families within its graph-based meta-analyzer pipeline. Understanding the distinction between **static_patterns analyzers** and **semantic_security_discovery** is essential for configuring effective security scanning of AI agent skills.

## Core Architectural Differences

### Static Patterns: Deterministic Rule-Based Detection

Static patterns analyzers operate through pure static code inspection without external AI services. In [`src/skillspector/nodes/analyzers/static_runner.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/nodes/analyzers/static_runner.py), the `StaticRunner` class loads collections of regular-expression and YARA-style rules from modules like [`src/skillspector/nodes/analyzers/pattern_defaults.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/nodes/analyzers/pattern_defaults.py). These analyzers scan the abstract syntax tree (AST) or raw source files for exact pattern matches.

The detection logic is entirely deterministic. For example, [`src/skillspector/nodes/analyzers/static_patterns_privilege_escalation.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/nodes/analyzers/static_patterns_privilege_escalation.py) defines YARA-compatible strings that match against specific code signatures like hard-coded secrets or supply-chain misuse. Each analyzer targets a specific vulnerability class—prompt injection, tool misuse, memory poisoning, or privilege escalation—by iterating over rule registries and applying them to the AST constructed by the `resolve_input` node.

### Semantic Security Discovery: LLM-Powered Inference

The `SemanticSecurityDiscovery` node in [`src/skillspector/nodes/analyzers/semantic_security_discovery.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/nodes/analyzers/semantic_security_discovery.py) takes a fundamentally different approach by reasoning over the *semantics* of skill code using a Large Language Model (LLM). This analyzer first calls `build_context` to gather a concise description of the skill—including its entry-point, imports, doc-strings, and inferred intent—then forwards that context to an LLM provider via `llm_utils.call_llm`.

The LLM provider implementation (found in [`providers/openai/provider.py`](https://github.com/NVIDIA/SkillSpector/blob/main/providers/openai/provider.py) or [`providers/anthropic/provider.py`](https://github.com/NVIDIA/SkillSpector/blob/main/providers/anthropic/provider.py)) processes the request and returns a JSON response that is parsed into `Issue` objects. These issues represent higher-level security concerns such as unintentional data exfiltration, intent clashes with least-privilege principles, or privilege escalation via indirect API calls.

## Performance and Reliability Trade-offs

**Static patterns analyzers** deliver fast, predictable performance that scales linearly with file size and rule count. Results remain reproducible across runs, offering high precision for well-defined patterns but limited recall for issues not covered by the rule set.

**Semantic security discovery** requires network calls to LLM endpoints (such as OpenAI's `gpt-4-turbo`), making execution slower and results potentially variable with model updates or temperature settings. This approach achieves higher recall for subtle, context-dependent threats but exhibits lower precision due to the risk of LLM hallucination or over-generalization.

## Configuration and Customization

### Modifying Static Pattern Rules

Rules for static analysis live in individual `static_patterns_*.py` modules under `src/skillspector/nodes/analyzers/`. Adding new detection capabilities requires editing the corresponding Python list or YARA file without modifying the core engine. The `MetaAnalyzer` in [`src/skillspector/nodes/meta_analyzer.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/nodes/meta_analyzer.py) automatically discovers and loads these patterns through the registry system.

### Customizing Semantic Discovery

The discovery prompt template is embedded directly in [`src/skillspector/nodes/analyzers/semantic_security_discovery.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/nodes/analyzers/semantic_security_discovery.py). Customization occurs by changing the system prompt or swapping the LLM provider in the provider configuration files. The base class `LLMAnalyzerBase` in [`src/skillspector/llm_analyzer_base.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/llm_analyzer_base.py) handles the request/response plumbing, allowing subclasses to focus on context preparation and result parsing.

## Code Examples

### Running Static Pattern Analysis

Execute a privilege-escalation scan from the command line interface:

```bash
skill-spector run \
    --skill-path path/to/skill \
    --analyzer static_patterns_privilege_escalation

```

The CLI ([`src/skillspector/cli.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/cli.py)) forwards this request to `MetaAnalyzer`, which loads the specific analyzer module and prints any matching issues found in the skill's AST.

### Invoking Semantic Security Discovery

Programmatically run the LLM-based analyzer:

```python
from skillspector.graph import SkillGraph
from skillspector.nodes.analyzers.semantic_security_discovery import SemanticSecurityDiscovery

# Build the graph for a local skill

graph = SkillGraph.from_path("path/to/skill")

# Run only the semantic discovery node

discovery = SemanticSecurityDiscovery(graph)
issues = discovery.run()
for issue in issues:
    print(issue.title, "→", issue.description)

```

This call internally performs the LLM request and returns a list of `Issue` objects representing discovered security concerns.

### Adding Custom Static Rules

Extend detection capabilities by editing [`src/skillspector/nodes/analyzers/static_patterns_privilege_escalation.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/nodes/analyzers/static_patterns_privilege_escalation.py):

```python

# New pattern that catches usage of `os.system` with elevated privileges

NEW_PATTERN = r'os\.system\(["\'].*sudo.*["\']\)'

PATTERNS.append(NEW_PATTERN)

```

Re-run the analyzer; the new rule matches immediately without requiring changes to the runner infrastructure.

## Summary

- **Static patterns analyzers** use deterministic, rule-based AST scanning in `src/skillspector/nodes/analyzers/` to detect concrete vulnerabilities like secret leakage and supply-chain poisoning.
- **Semantic security discovery** leverages LLM reasoning through [`src/skillspector/nodes/analyzers/semantic_security_discovery.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/nodes/analyzers/semantic_security_discovery.py) to identify subtle, context-dependent security concerns.
- Static analysis offers high precision and reproducibility with linear performance scaling, while semantic discovery provides broader coverage with variable latency dependent on network calls.
- Both analyzer families ultimately produce `Issue` objects consumed by the `Report` node ([`src/skillspector/nodes/report.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/nodes/report.py)) and exportable as SARIF format.

## Frequently Asked Questions

### What is the main difference between static_patterns analyzers and semantic_security_discovery?

Static patterns analyzers perform deterministic scans using regex and YARA-style rules against the AST to find concrete code patterns, while semantic_security_discovery sends skill context to an LLM to infer higher-level security concerns. The former operates entirely offline with predictable results, whereas the latter requires external AI services and interprets code intent rather than matching literal patterns.

### When should I use static_patterns analyzers instead of semantic_security_discovery?

Use static patterns analyzers when you need fast, reproducible detection of known vulnerability signatures such as hard-coded credentials, unsafe imports, or prompt injection vectors. Choose semantic security discovery when assessing complex skills where context-dependent risks—like implicit data exfiltration or privilege escalation through indirect API calls—require understanding the skill's intended behavior beyond literal code patterns.

### How do I configure the LLM provider for semantic_security_discovery?

Configure the LLM provider by modifying [`providers/openai/provider.py`](https://github.com/NVIDIA/SkillSpector/blob/main/providers/openai/provider.py) or [`providers/anthropic/provider.py`](https://github.com/NVIDIA/SkillSpector/blob/main/providers/anthropic/provider.py) and adjusting the system prompt in [`src/skillspector/nodes/analyzers/semantic_security_discovery.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/nodes/analyzers/semantic_security_discovery.py). The `LLMAnalyzerBase` class handles the underlying request plumbing, allowing you to swap models or providers without changing the core discovery logic.

### Can I extend static_patterns analyzers with custom rules?

Yes, custom rules are added by editing the specific pattern module files such as [`src/skillspector/nodes/analyzers/static_patterns_privilege_escalation.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/nodes/analyzers/static_patterns_privilege_escalation.py). Append new regex patterns to the module's pattern list; the `StaticRunner` automatically picks up these changes through the pattern registry ([`src/skillspector/nodes/analyzers/pattern_defaults.py`](https://github.com/NVIDIA/SkillSpector/blob/main/src/skillspector/nodes/analyzers/pattern_defaults.py)) without requiring code modifications to the execution engine.