rsigma-ir
Shared intermediate representation (HIR) for Sigma rules. Sits between the parser AST and the eval/convert consumers so modifier resolution happens once.
When to use
- Lower a parsed
SigmaRuleinto a modifier-resolved form before custom analysis. - Share one canonical rule shape between evaluation and query conversion.
- Inspect detections, conditions, correlation, or filter shapes without compiling regex/
IpNetmatchers.
Most embedders never depend on rsigma-ir directly: rsigma-eval routes compile_rule through lower_rule → compile_to_compiled already.
Install
[dependencies]
rsigma-parser = "0.19.0"
rsigma-ir = "0.19.0"
The crate is sync-only (no tokio/reqwest).
Public surface
| Type / function | Purpose |
|---|---|
IrRule / IrDetection / IrMatcher / IrCondition |
Detection-rule HIR. IrCondition::Selector keeps the quantifier and name pattern. |
IrMatcher::Str + IrPattern |
Faithful, wildcard-aware, original-case string match. |
IrMatcher::Encoded + IrEncoding |
Explicit encoding transforms (base64, wide, windash, …). |
IrCorrelation / IrFilter |
Correlation and filter HIR. |
IrRuleMetadata |
Metadata superset used when projecting eval RuleHeader. |
lower_rule / lower_detection / lower_condition |
AST → HIR. |
lower_correlation / lower_filter |
Parallel walkers for those shapes. |
LowerOptions |
Strict (default) vs placeholder-preserving lowering. |
optimize_rule / flatten_condition / eliminate_dead_detections |
Opt-in, semantics-preserving HIR passes. |
common_subexpressions / CseReport |
Non-mutating analysis of repeated detection items. |
Optimization passes
optimize::* provides opt-in, total functions on the HIR for offline tooling (pack building, analysis). They are not run by the default eval or convert paths, so compiled-matcher behavior and byte-identical backend output are unchanged.
flatten_conditionmerges nested same-kind boolean groups, collapsesNot(Not(x)), unwraps single-childAnd/Or, and drops idempotent duplicate siblings.eliminate_dead_detectionsremoves detections no condition can reference (honoringthem/glob selector patterns) and recurses intoConditionalbodies.common_subexpressionsreports detection items that occur more than once, the candidates a consumer could evaluate once and share.optimize_ruleapplies the two structural passes in order.
Each pass preserves the match decision and the set of matched selections and fields. Reported order and multiplicity of matched selections are not part of the contract: dropping a duplicate reference reports a selection once, and pruning changes a selector’s HashMap-ordered reporting.
Lowering notes
- Lowering is purely structural: it resolves which comparison applies but never lowercases, compiles regexes, or expands encodings. Eval does that at compile time; convert renders wildcards to backend tokens. This keeps the HIR lossless.
- Selectors such as
1 of selection_*andall of themare preserved asIrCondition::Selector, so evaluation stays count-based and reports every matching detection.themskips_-prefixed detection names; glob/prefix patterns that explicitly match them still include them. Vacuousall of <pattern>over zero matching names is true, matching native evaluation. - Modifier contradictions (
|cidr|contains,|base64|base64offset, …) fail at lower time with the same error kinds eval previously surfaced fromcompile_rule.
Related
rsigma-eval—compile_rule(IR path) andcompile_rule_legacy(dual-path differential).rsigma-parser— source AST.