Sentinel
Synopsis
Evaluates Microsoft Sentinel analytics rules against each event. The rule's KQL is compiled once, then run per event; a match annotates the event with the rule's name, severity, tactics, techniques, and resolved MITRE ATT&CK enrichment.
The rules are Sentinel analytics rules used unchanged. To convert a Sentinel ASIM parser into a pipeline instead, see From KQL; to use detection rules to reduce what reaches the SIEM, see Smart Engine.
Schema
- sentinel:
library: <string[]>
rules: <string[]>
rule_files: <string[]>
rule_dirs: <string[]>
select: <object>
mode: <enum>
mark_field: <ident>
min_severity: <enum>
mitre_enrich: <boolean>
include_query: <boolean>
table_field: <ident>
strict_table: <boolean>
enrich_on_unresolved: <boolean>
description: <text>
if: <script>
tag: <string>
disabled: <boolean>
ignore_failure: <boolean>
on_failure: <processor[]>
on_success: <processor[]>
Configuration
At least one rule source is required. With none, the processor fails.
| Field | Required | Default | Description |
|---|---|---|---|
library | Y* | Names of Sentinel rule packs assigned through the Library. | |
rules | Y* | Rules given inline, as rule YAML. | |
rule_files | Y* | Paths to rule files (.yml, .yaml). | |
rule_dirs | Y* | Directories searched recursively for rule files. | |
select | N | all rules | Narrows which of the loaded rules are registered. See below. |
mode | N | annotate | annotate marks matches and forwards every event. filter drops every event that matches no rule. |
mark_field | N | _sentinel | Root field the match markers are written under. |
min_severity | N | Ignore rules below this severity: informational, low, medium, or high. | |
mitre_enrich | N | true | Resolve MITRE ATT&CK tactics and techniques onto each match. |
include_query | N | false | Include the rule's KQL in the match. |
table_field | N | _vmetric.table | The event field holding the table name a rule is scoped against. |
strict_table | N | false | Require an event to declare a matching table before a table-scoped rule applies. See below. |
enrich_on_unresolved | N | false | Make a rule whose KQL cannot be compiled match every event it is scoped to, rather than nothing. |
description | N | Explanatory note. | |
if | N | Condition that must be true for the processor to run. | |
tag | N | Identifier for this processor instance. | |
disabled | N | false | When true, the processor is skipped. |
ignore_failure | N | false | Continue pipeline processing if the processor fails. |
on_failure | N | See Handling Failures. | |
on_success | N | See Handling Success. |
* = At least one of library, rules, rule_files, or rule_dirs is required. Sources are combined, in that order.
Select
All criteria are combined with AND; the values within one criterion are combined with OR. Matching is case-insensitive.
| Field | Description |
|---|---|
tables | Rules whose declared data types include any of these, such as SecurityEvent or CommonSecurityLog. |
connectors | Rules by required data connector id. |
severities | informational, low, medium, or high. |
kinds | Scheduled or NRT. |
tactics | MITRE tactic. Separator-insensitive, so CommandAndControl and command-and-control are equivalent. |
techniques | MITRE technique id. A parent id also selects its sub-techniques, so T1059 selects T1059.001. |
ids | Rule id, matched exactly. |
name_prefix, name_contains, name_regex | Rule title matching. |
desc_contains | Rule description matching. |
tags | Rule tags. |
A select that matches no rules is an error, raised when the first event reaches the processor.
Details
Annotating and Filtering
In the default annotate mode, every event is forwarded. A matching event gains its markers; a non-matching event passes through untouched.
Setting mode: filter turns the processor into an allowlist: an event that matches no rule is dropped. Use it deliberately — it discards telemetry.
Table Scoping
A rule that declares no table applies to every event. A rule scoped to a table applies to events whose table_field names that table, compared case-insensitively.
An event carrying no table at all is, by default, still evaluated against every table-scoped rule — the rule's own field predicates decide whether it fires. This favors never missing a detection, at the cost of occasional cross-table matches. Set strict_table: true to require a positive table match instead, which skips table-scoped rules for any event that does not declare a table.
This differs from Smart Engine, where an untabled event has no applicable detections at all. The two processors read the same rules but scope them differently, so do not carry an assumption from one to the other.
Rules That Cannot Be Compiled
Some Sentinel rules use KQL that has no per-event form. Such a rule is marked unmatchable and enriches nothing — it fails closed. Setting enrich_on_unresolved: true reverses that: the rule instead matches every event whose table it positively declares, which annotates far more events but never misses one.
Markers
| Field | Description |
|---|---|
_sentinel.matched | true on a matching event. |
_sentinel.rules | One entry per matched rule. |
_sentinel.count | The number of matched rules. |
Each entry in _sentinel.rules carries name, and — when the rule defines them — id, severity (lower-cased), tactics, techniques, tables, fields, and mitre. The rule's query is included only under include_query.
Examples
Annotating a Match
Registering an assigned rule pack, narrowed to the rules for one table... | |
A matching event is annotated with the rule and its ATT&CK enrichment. The event itself is unchanged... | |
Filtering to Rule Matches Only
Forwarding only events that some high-severity rule matched... | |
An event matching no high-severity rule is dropped. Nothing is forwarded for it... | |
Requiring a Declared Table
Scoping strictly, so a rule fires only for events that positively declare its table... | |
An event without | |