rsigma_eval/lib.rs
1//! # rsigma-eval
2//!
3//! Evaluator for Sigma detection and correlation rules.
4//!
5//! This crate consumes the AST produced by [`rsigma_parser`] and evaluates it
6//! against events in real time using a compile-then-evaluate model.
7//!
8//! ## Architecture
9//!
10//! - **Detection rules** (stateless): compiled once into optimized matchers,
11//! each event is matched with zero allocation on the hot path.
12//! - **Correlation rules** (stateful): time-windowed aggregation over detection
13//! matches, supporting `event_count`, `value_count`, `temporal`,
14//! `temporal_ordered`, `value_sum`, `value_avg`, `value_percentile`,
15//! and `value_median`.
16//!
17//! ## Quick Start — Detection Only
18//!
19//! ```rust
20//! use rsigma_parser::parse_sigma_yaml;
21//! use rsigma_eval::Engine;
22//! use rsigma_eval::event::JsonEvent;
23//! use serde_json::json;
24//!
25//! let yaml = r#"
26//! title: Detect Whoami
27//! logsource:
28//! product: windows
29//! category: process_creation
30//! detection:
31//! selection:
32//! CommandLine|contains: 'whoami'
33//! condition: selection
34//! level: medium
35//! "#;
36//!
37//! let collection = parse_sigma_yaml(yaml).unwrap();
38//! let mut engine = Engine::new();
39//! engine.add_collection(&collection).unwrap();
40//!
41//! let event_val = json!({"CommandLine": "cmd /c whoami"});
42//! let event = JsonEvent::borrow(&event_val);
43//! let matches = engine.evaluate(&event);
44//! assert_eq!(matches.len(), 1);
45//! ```
46//!
47//! ## Quick Start — With Correlations
48//!
49//! ```rust
50//! use rsigma_parser::parse_sigma_yaml;
51//! use rsigma_eval::{CorrelationEngine, CorrelationConfig};
52//! use rsigma_eval::event::JsonEvent;
53//! use serde_json::json;
54//!
55//! let yaml = r#"
56//! title: Login
57//! id: login-rule
58//! logsource:
59//! category: auth
60//! detection:
61//! selection:
62//! EventType: login
63//! condition: selection
64//! ---
65//! title: Many Logins
66//! correlation:
67//! type: event_count
68//! rules:
69//! - login-rule
70//! group-by:
71//! - User
72//! timespan: 60s
73//! condition:
74//! gte: 3
75//! level: high
76//! "#;
77//!
78//! let collection = parse_sigma_yaml(yaml).unwrap();
79//! let mut engine = CorrelationEngine::new(CorrelationConfig::default());
80//! engine.add_collection(&collection).unwrap();
81//!
82//! for i in 0..3 {
83//! let v = json!({"EventType": "login", "User": "admin"});
84//! let event = JsonEvent::borrow(&v);
85//! let result = engine.process_event_at(&event, 1000 + i);
86//! if i == 2 {
87//! assert_eq!(result.correlations.len(), 1);
88//! }
89//! }
90//! ```
91
92pub mod compiler;
93pub mod correlation;
94pub mod correlation_engine;
95pub mod engine;
96pub mod error;
97pub mod event;
98pub mod matcher;
99pub mod pipeline;
100pub mod result;
101pub mod rule_index;
102
103// Re-export the most commonly used types and functions at crate root
104pub use compiler::{
105 CompiledDetection, CompiledDetectionItem, CompiledRule, compile_rule, evaluate_rule,
106};
107pub use correlation::{
108 CompiledCondition, CompiledCorrelation, EventBuffer, EventRef, EventRefBuffer, GroupByField,
109 GroupKey, WindowState,
110};
111pub use correlation_engine::{
112 CorrelationAction, CorrelationConfig, CorrelationEngine, CorrelationEventMode,
113 CorrelationResult, CorrelationSnapshot, ProcessResult, TimestampFallback,
114};
115pub use engine::Engine;
116pub use error::{EvalError, Result};
117pub use event::{Event, EventValue, JsonEvent, KvEvent, MapEvent, PlainEvent};
118pub use matcher::CompiledMatcher;
119pub use pipeline::{
120 Pipeline, apply_pipelines, merge_pipelines, parse_pipeline, parse_pipeline_file,
121};
122pub use result::{FieldMatch, MatchResult};