A complete Rust toolkit for the Sigma detection standard — parser, evaluation engine, linter, CLI, and LSP. rsigma parses Sigma YAML rules into a strongly-typed AST, compiles them into optimized matchers, and evaluates them directly against JSON log events in real time. It runs detection and stateful correlation logic in-process with memory-efficient compressed event storage, supports pySigma-compatible processing pipelines for field mapping and backend configuration, and streams results from NDJSON input — no external SIEM required. A built-in linter validates rules against 65 checks derived from the Sigma v2.1.0 specification with four severity levels, a full suppression system, and auto-fix support (--fix) for 13 safe rules. An LSP server provides real-time diagnostics, completions, hover documentation, and quick-fix code actions in any editor.
| Crate | Description |
|---|---|
rsigma-parser |
Parse Sigma YAML into a strongly-typed AST |
rsigma-eval |
Compile and evaluate rules against JSON events |
rsigma |
CLI for parsing, validating, linting, and evaluating rules |
rsigma-lsp |
Language Server Protocol (LSP) server for IDE support |
# Build all crates
cargo build --release
# Install the CLI
cargo install rsigma
# Install the LSP server
cargo install --path crates/rsigma-lspEvaluate events against Sigma rules from the command line:
# Single event (inline JSON)
rsigma eval -r path/to/rules/ -e '{"CommandLine": "cmd /c whoami"}'
# Read events from a file (@file syntax)
rsigma eval -r path/to/rules/ -e @events.ndjson
# Stream NDJSON from stdin
cat events.ndjson | rsigma eval -r path/to/rules/
# With a processing pipeline for field mapping
rsigma eval -r rules/ -p pipelines/ecs.yml -e '{"process.command_line": "whoami"}'Or use the library directly:
use rsigma_parser::parse_sigma_yaml;
use rsigma_eval::{Engine, Event};
use serde_json::json;
let yaml = r#"
title: Detect Whoami
logsource:
product: windows
category: process_creation
detection:
selection:
CommandLine|contains: 'whoami'
condition: selection
level: medium
"#;
let collection = parse_sigma_yaml(yaml).unwrap();
let mut engine = Engine::new();
engine.add_collection(&collection).unwrap();
let event = Event::from_value(&json!({"CommandLine": "cmd /c whoami"}));
let matches = engine.evaluate(&event);
assert_eq!(matches[0].rule_title, "Detect Whoami"); ┌──────────────────┐
YAML input ───> │ serde_yaml │──> Raw YAML Value
└──────────────────┘
│
▼
┌──────────────────┐
│ parser.rs │──> Typed AST
│ (YAML → AST) │ (SigmaRule, CorrelationRule,
└──────────────────┘ FilterRule, SigmaCollection)
│
┌────────────────┼──────────────┐
▼ ▼ ▼
┌────────────┐ ┌────────────┐ ┌────────────┐
│ sigma.pest │ │ value.rs │ │ ast.rs │
│ (PEG │ │ (SigmaStr, │ │ (AST types │
│ grammar) │ │ wildcards,│ │ modifiers,│
│ + │ │ timespan) │ │ enums) │
│condition.rs│ └────────────┘ └────────────┘
│ (Pratt │
│ parser) │
└────────────┘
│
┌─────┴───────────────────────────────────────────────┐
│ │
▼ ▼
┌──────────────────────────────────────────┐ ┌────────────────────┐
│ rsigma-eval │ │ rsigma-lsp │
│ │ │ │
│ pipeline/ ──> Pipeline (YAML parsing, │ │ LSP server over │
│ conditions, transformations, state) │ │ stdio (tower-lsp) │
│ ↓ transforms SigmaRule AST │ │ │
│ │ │ • diagnostics │
│ compiler.rs ──> CompiledRule │ │ (lint + parse │
│ matcher.rs ──> CompiledMatcher │ │ + compile) │
│ engine.rs ──> Engine (stateless) │ │ • completions │
│ │ │ • hover │
│ correlation.rs ──> CompiledCorrelation │ │ • document │
│ + EventBuffer (deflate-compressed) │ │ symbols │
│ correlation_engine.rs ──> (stateful) │ │ │
│ sliding windows, group-by, chaining, │ │ Editors: │
│ alert suppression, action-on-fire, │ │ VSCode, Neovim, │
│ memory management, event inclusion │ │ Helix, Zed, ... │
│ │ └────────────────────┘
│ rsigma.* custom attributes ─────────> │
│ engine config from pipelines │
└──────────────────────────────────────────┘
│
▼
┌────────────────────┐
│ MatchResult │──> rule title, id, level, tags,
│ CorrelationResult │ matched selections, field matches,
└────────────────────┘ aggregated values, optional events
- pySigma — reference Python implementation
- Sigma Specification V2.0.0 — formal specification
- sigma-rust — Pratt parsing approach
- sigmars — correlation support patterns
All four crates share a single version (set in the workspace Cargo.toml) and are published together.
- Bump the version in the root
Cargo.toml. - Commit, push to
main. - Create a GitHub Release (e.g. tag
v0.2.0). Thepublish.ymlworkflow triggers automatically and publishes all crates in dependency order.
Trigger the workflow manually via Actions → Publish to crates.io → Run workflow.
Manual runs automatically pass --dry-run to every cargo publish invocation.
If the workflow fails midway (e.g. rsigma-parser was published but rsigma-eval
failed), re-running the workflow will fail at the already-published crate.
To recover, publish the remaining crates manually in order:
# Skip crates that were already published successfully
cargo publish -p rsigma-eval && sleep 30
cargo publish -p rsigma
cargo publish -p rsigma-lspMIT