Skip to main content

LEEF to CSL

Transform

Synopsis

Parses a LEEF message and maps it directly to Microsoft Sentinel's Common Security Log (CommonSecurityLog) schema in one fused pass, replacing the manual leef + normalize + move (+ enforce_schema) processor chain.

note

For details of LEEF, see Appendix.

Schema

- leef_to_csl:
field: <ident>
use_table: <boolean>
description: <text>
if: <script>
tag: <string>
disabled: <boolean>
ignore_failure: <boolean>
on_failure: <processor[]>
on_success: <processor[]>

Configuration

The following fields are used to define the processor:

FieldRequiredDefaultDescription
fieldYField containing the raw LEEF message to convert. Must be a string starting with LEEF:
use_tableNfalseWrite the mapped fields into the typed CommonSecurityLog virtual table instead of the event map. The table must already exist (create_table)
descriptionNExplanatory note
ifNCondition to run
tagNIdentifier
disabledNfalseSkip this processor
ignore_failureNfalseSee Handling Failures
on_failureNSee Handling Failures
on_successNSee Handling Success

Details

leef_to_csl parses the raw LEEF message and hands the resulting fields straight to the internal leefcsl mapping in one pass, without ever materializing an intermediate leef object, a separate normalize step, or a move-to-root step. The result already reflects the same CSL schema enforcement that a manual leef + normalize + move + enforce_schema chain would produce—no separate enforce_schema step is needed afterward, and ignore_rules-style schema enforcement is not configurable on this processor; it always applies.

field must resolve to a string starting with LEEF:. If the field is missing, is not a string, or does not start with LEEF:, the processor fails. There is no ignore_missing option on this processor—unlike the plain leef parsing processor, a missing field is handled the same way as any other failure, through ignore_failure/on_failure.

use_table: false (default)

The mapped CSL fields replace the entire event map. Every field that existed on the event before this processor ran—including the source field itself—is discarded, except system (_vmetric) fields and any virtual tables already created on the entry.

use_table: true

Nothing is written to the event map. Instead, the mapped fields are written directly into the typed CommonSecurityLog virtual table, and the log entry's output source switches to that table. The table is not created by this processor—it must already exist via create_table; the caller owns the table's lifecycle (creation, truncation, dropping). The event map itself is left untouched. Field-for-field, the values written are identical to the use_table: false path—only the storage target differs.

No use_kv_parser option

Unlike cef_to_csl, this processor has no use_kv_parser field. LEEF's body has no equivalent alternate parsing mode: it is always split on the message's declared delimiter (the default tab, or a custom delimiter given as a hex escape in the header, e.g. x09) into key=value attribute pairs by a single dedicated LEEF tokenizer.

Unmapped fields

LEEF attribute fields with no corresponding CSL schema column are folded into AdditionalExtensions as key=value pairs joined with ;, in the order they appear in the source message.

Distinct from the leef processor

leef_to_csl is not the LEEF parser. The leef processor parses a LEEF message into a structured object at target_field (leaving the rest of the event untouched) and supports target_field/ignore_missing; leef_to_csl skips that intermediate object entirely and converts straight to CSL, replacing the event map (or writing to a table) and supporting neither target_field nor ignore_missing. For CEF, see the sibling CEF to CSL processor.

Examples

Basic Conversion

Converting a raw LEEF message straight to CSL fields...

{
"message": "LEEF:2.0|ExtraHop|Reveal(x)|7.8|extrahop-detection|xa6|appliance_id=dd0685a93cdc3bc5bb9a88251e7a7804¦categories=sec,sec.caution¦det_id=0123456789¦det_url=https://cribl.cloud.extrahop.com/extrahop/#/detections/detail/0123456789¦update_time=Jan 24 2022 20:23:39 +0000¦end_time=Jan 24 2022 20:23:39 +0000¦risk_score=60¦start_time=Jan 24 2022 20:23:39 +0000¦title=Non-standard HTTP Port¦offender_ip=10.1.2.3¦victim_ip=192.168.1.50¦offender_id=dd0685a93cdc3bc5¦desc=Host CRIBL sent an HTTP request to an external device on a non-standard HTTP port."
}
- leef_to_csl:
field: message

replaces the entire event map with the mapped CSL fields; the xa6 header segment declares the custom ¦ attribute delimiter, and unmapped attributes fold into AdditionalExtensions...

{
"AdditionalExtensions": "appliance_id=dd0685a93cdc3bc5bb9a88251e7a7804;categories=sec,sec.caution;det_id=0123456789;det_url=https://cribl.cloud.extrahop.com/extrahop/#/detections/detail/0123456789;update_time=Jan 24 2022 20:23:39 +0000;end_time=Jan 24 2022 20:23:39 +0000;risk_score=60;start_time=Jan 24 2022 20:23:39 +0000;title=Non-standard HTTP Port;offender_ip=10.1.2.3;victim_ip=192.168.1.50;offender_id=dd0685a93cdc3bc5;desc=Host CRIBL sent an HTTP request to an external device on a non-standard HTTP port.",
"DeviceEventClassID": "extrahop-detection",
"DeviceProduct": "Reveal(x)",
"DeviceVendor": "ExtraHop",
"DeviceVersion": "7.8"
}

Writing into the CommonSecurityLog Table

Creating the typed table first, then converting with use_table: true...

{
"message": "LEEF:2.0|ExtraHop|Reveal(x)|7.8|extrahop-detection|xa6|appliance_id=dd0685a93cdc3bc5bb9a88251e7a7804¦categories=sec,sec.caution¦det_id=0123456789¦det_url=https://cribl.cloud.extrahop.com/extrahop/#/detections/detail/0123456789¦update_time=Jan 24 2022 20:23:39 +0000¦end_time=Jan 24 2022 20:23:39 +0000¦risk_score=60¦start_time=Jan 24 2022 20:23:39 +0000¦title=Non-standard HTTP Port¦offender_ip=10.1.2.3¦victim_ip=192.168.1.50¦offender_id=dd0685a93cdc3bc5¦desc=Host CRIBL sent an HTTP request to an external device on a non-standard HTTP port."
}
- create_table:
name: CommonSecurityLog
- leef_to_csl:
field: message
use_table: true

writes the same mapped fields into the CommonSecurityLog table instead of the event map; the event map is left untouched and output now marshals from the table...

{
"AdditionalExtensions": "appliance_id=dd0685a93cdc3bc5bb9a88251e7a7804;categories=sec,sec.caution;det_id=0123456789;det_url=https://cribl.cloud.extrahop.com/extrahop/#/detections/detail/0123456789;update_time=Jan 24 2022 20:23:39 +0000;end_time=Jan 24 2022 20:23:39 +0000;risk_score=60;start_time=Jan 24 2022 20:23:39 +0000;title=Non-standard HTTP Port;offender_ip=10.1.2.3;victim_ip=192.168.1.50;offender_id=dd0685a93cdc3bc5;desc=Host CRIBL sent an HTTP request to an external device on a non-standard HTTP port.",
"DeviceEventClassID": "extrahop-detection",
"DeviceProduct": "Reveal(x)",
"DeviceVendor": "ExtraHop",
"DeviceVersion": "7.8"
}

Error Handling

Handling a field that isn't a valid LEEF message...

{
"message": "Invalid LEEF message"
}
- leef_to_csl:
field: message
ignore_failure: true
on_failure:
- append:
field: tags
value: leef_to_csl_error

leaves the event map untouched and adds an error tag instead of failing the pipeline...

{
"message": "Invalid LEEF message",
"tags": ["leef_to_csl_error"]
}