Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
146507e
Add OCSF to ASIM mapper
mavam Jun 7, 2026
6e1707d
Fix ASIM mapping correctness in OCSF mapper
mavam Jun 7, 2026
e47c557
Add canonical Microsoft mapping entry points
mavam Jun 8, 2026
97657e0
Clean up Microsoft mapper descriptions
mavam Jun 8, 2026
d3ba466
Normalize Microsoft mapper inputs
mavam Jun 8, 2026
c4499cc
Simplify ASIM OCSF mappers
mavam Jun 8, 2026
874193f
Avoid ASIM state in AdditionalFields
mavam Jun 8, 2026
cfc22ad
Use explicit OCSF source namespace
mavam Jun 8, 2026
2230a7c
Streamline Microsoft mapper wrappers
mavam Jun 8, 2026
587c03f
Assert ASIM OCSF mapper inputs
mavam Jun 8, 2026
b2272a5
Move ASIM OCSF preconditions up
mavam Jun 8, 2026
bfa6182
Allow best-effort ASIM OCSF mapping
mavam Jun 8, 2026
ce80632
Remove redundant null fallbacks
mavam Jun 8, 2026
1c928c6
Simplify Microsoft mapper tests
mavam Jun 8, 2026
6f2b393
Remove raw mapper arguments
mavam Jun 8, 2026
d81cdcd
Align ASIM OCSF tests
mavam Jun 8, 2026
7233be9
Target Microsoft mappers by field
mavam Jun 8, 2026
99ab77f
Compose Microsoft ASIM mapping explicitly
mavam Jun 8, 2026
83c2b18
Document future ASIM map bridge
mavam Jun 8, 2026
f771842
Simplify unsupported ASIM map test
mavam Jun 11, 2026
5679aaf
Pass current events directly to mappers
mavam Jun 11, 2026
26e5db7
Move mapper intermediates into output
mavam Jun 11, 2026
005a9ae
Stop embedding OCSF events in ASIM output
mavam Jun 11, 2026
4f926ae
Trim ASIM OCSF test fixtures
mavam Jun 11, 2026
68961fd
Flatten ASIM OCSF helper namespace
mavam Jun 12, 2026
1cdbfc1
Keep mapper scratch inside event
mavam Jun 12, 2026
83054f9
Default Microsoft maps to this
mavam Jun 12, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ prs:
created: 2026-03-24T13:37:04.933237Z
---

The `microsoft::windows::ocsf::map` operator now covers five additional Windows Event Log categories:
The `microsoft::ocsf::map` operator now covers five additional Windows Event Log categories:

**PowerShell logging** (EIDs 4100/4103/4104/4105/4106) maps to OCSF Script Activity (1009). EID 4104 (Script Block Logging) sets `severity_id` to Low when AMSI flags the block; EID 4100 (engine error) marks the execution as a failure.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ created: 2026-05-27T09:17:24Z
The Microsoft package can now collect and normalize common Microsoft Graph
security and inventory data.

Use the Graph source operators and `microsoft::graph::ocsf::map` for Entra ID
Use the Graph source operators and `microsoft::ocsf::map` for Entra ID
sign-ins, directory audits, Defender alerts and incidents, Identity Protection
risk data, and Intune inventory and compliance data.

Expand Down
28 changes: 28 additions & 0 deletions microsoft/changelog/unreleased/ocsf-to-asim-mapper.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
title: OCSF to ASIM mapper
type: feature
authors:
- mavam
- codex
prs:
- 153
created: 2026-06-07T00:00:00Z
---

The Microsoft package now includes `microsoft::asim::map` to convert supported
Microsoft events into flat Microsoft Sentinel ASIM event records. The mapper
uses the new `microsoft::ocsf::map` entry point and `microsoft::asim::ocsf::map`
for validated OCSF 1.8 events.

Microsoft mapping operators now accept the source event through the named
`event` argument. For raw Windows Event Log XML, first run
`win = data.parse_winlog()`; the resulting structured event can then be
normalized through `microsoft::windows::ocsf::map event=win`. Validated OCSF
events can be converted with `microsoft::asim::map event=this` or
`microsoft::asim::ocsf::map event=this`. Mapping operators accept an optional
`raw` value when the original source payload is still available and should be
preserved in OCSF `raw_data` and `raw_data_size`.

The mapper covers the Microsoft package's current OCSF authentication, process,
audit, user-management, and alert outputs, plus direct OCSF counterparts for
file, network, DNS, DHCP, and web session ASIM schemas.
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ prs:
created: 2026-06-02T08:30:07.026165Z
---

The `microsoft::windows::ocsf::map` operator now maps Windows Security Event ID 4672, "Special privileges assigned to new logon", to OCSF Authorize Session (3003) with the Assign Privileges activity.
The `microsoft::ocsf::map` operator now maps Windows Security Event ID 4672, "Special privileges assigned to new logon", to OCSF Authorize Session (3003) with the Assign Privileges activity.
2 changes: 1 addition & 1 deletion microsoft/examples/graph-defender-alerts-to-ocsf.tql
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ microsoft::graph::defender::alerts \
client_id="CLIENT_ID",
client_secret=secret("CLIENT_SECRET"),
lookback=5m
microsoft::graph::ocsf::map
microsoft::ocsf::map
ocsf::derive
ocsf::cast
2 changes: 1 addition & 1 deletion microsoft/examples/graph-defender-incidents-to-ocsf.tql
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ every 5m {
client_secret=secret("CLIENT_SECRET"),
lookback=5m
}
microsoft::graph::ocsf::map
microsoft::ocsf::map
ocsf::derive
ocsf::cast
publish "ocsf"
2 changes: 1 addition & 1 deletion microsoft/examples/graph-directory-audits-to-ocsf.tql
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ every 5m {
client_secret=secret("CLIENT_SECRET"),
lookback=5m
}
microsoft::graph::ocsf::map
microsoft::ocsf::map
ocsf::derive
ocsf::cast
publish "ocsf"
2 changes: 1 addition & 1 deletion microsoft/examples/graph-intune-compliance-to-ocsf.tql
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ every 5m {
client_id="CLIENT_ID",
client_secret=secret("CLIENT_SECRET")
}
microsoft::graph::ocsf::map
microsoft::ocsf::map
ocsf::derive
ocsf::cast
publish "ocsf"
2 changes: 1 addition & 1 deletion microsoft/examples/graph-intune-detected-apps-to-ocsf.tql
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ every 5m {
client_id="CLIENT_ID",
client_secret=secret("CLIENT_SECRET")
}
microsoft::graph::ocsf::map
microsoft::ocsf::map
ocsf::derive
ocsf::cast
publish "ocsf"
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ microsoft::graph::intune::managed_devices \
tenant_id="TENANT_ID",
client_id="CLIENT_ID",
client_secret=secret("CLIENT_SECRET")
microsoft::graph::ocsf::map
microsoft::ocsf::map
ocsf::derive
ocsf::cast
2 changes: 1 addition & 1 deletion microsoft/examples/graph-risk-detections-to-ocsf.tql
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ every 5m {
client_id="CLIENT_ID",
client_secret=secret("CLIENT_SECRET")
}
microsoft::graph::ocsf::map
microsoft::ocsf::map
ocsf::derive
ocsf::cast
publish "ocsf"
2 changes: 1 addition & 1 deletion microsoft/examples/graph-risky-users-to-ocsf.tql
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ every 5m {
client_id="CLIENT_ID",
client_secret=secret("CLIENT_SECRET")
}
microsoft::graph::ocsf::map
microsoft::ocsf::map
ocsf::derive
ocsf::cast
publish "ocsf"
15 changes: 15 additions & 0 deletions microsoft/examples/graph-sign-ins-to-asim.tql
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
name: Microsoft Graph sign-ins -> ASIM
description: Fetch recent Microsoft Entra ID sign-in logs, map them through OCSF, and convert them to Microsoft Sentinel ASIM.
---

microsoft::graph::sign_ins \
tenant_id="TENANT_ID",
client_id="CLIENT_ID",
client_secret=secret("CLIENT_SECRET"),
lookback=5m
@name = "microsoft.graph.sign_in"
microsoft::ocsf::map
ocsf::derive
ocsf::cast
microsoft::asim::map
2 changes: 1 addition & 1 deletion microsoft/examples/graph-sign-ins-to-ocsf.tql
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@ microsoft::graph::sign_ins \
client_id="CLIENT_ID",
client_secret=secret("CLIENT_SECRET"),
lookback=5m
microsoft::graph::ocsf::map
microsoft::ocsf::map
ocsf::derive
ocsf::cast
16 changes: 16 additions & 0 deletions microsoft/examples/windows-event-log-to-asim.tql
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
---
name: Windows Event Log XML -> ASIM
description: Parse Windows Event Log XML, map it through OCSF, and convert it to Microsoft Sentinel ASIM.
---

from_file "windows-event.xml" {
read_all
}
win = data.parse_winlog()
microsoft::windows::ocsf::map event=win
win.raw_data = move data
win.raw_data_size = win.raw_data.length_bytes()
this = win
ocsf::derive
ocsf::cast
microsoft::asim::map
15 changes: 15 additions & 0 deletions microsoft/examples/windows-event-log-to-ocsf.tql
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
---
name: Windows Event Log XML → OCSF
description: Parse Windows Event Log XML and map the structured event to OCSF.
---

from_file "windows-event.xml" {
read_all
}
win = data.parse_winlog()
microsoft::windows::ocsf::map event=win
win.raw_data = move data
win.raw_data_size = win.raw_data.length_bytes()
this = win
ocsf::derive
ocsf::cast
22 changes: 22 additions & 0 deletions microsoft/operators/asim/map.tql
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
---
description: Maps validated Microsoft OCSF events to Microsoft Sentinel ASIM.
args:
named:
- name: event
description: The field that holds the OCSF event to map.
type: field
default: this
---

// If `ocsf::derive` and `ocsf::cast` gain `event=` support, this wrapper can
// also bridge Microsoft source events to ASIM without temporarily replacing
// `this`:
//
// if $event.class_uid? == null {
// microsoft::ocsf::map event=$event
// ocsf::derive event=$event
// ocsf::cast event=$event
// }
//
// Until then, callers compose these steps explicitly before invoking this UDO.
microsoft::asim::ocsf::map event=$event
54 changes: 54 additions & 0 deletions microsoft/operators/asim/ocsf/account_change.tql
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
---
description: Maps OCSF Account Change events to Microsoft Sentinel ASIM UserManagement events.
args:
named:
- name: event
description: The field that holds the OCSF event to map.
type: field
---

$event = {...$event, ocsf: $event, asim: {}}

assert $event.ocsf.class_uid == 3001

microsoft::asim::ocsf::common event=$event

@name = "asim.user_management"
$event.asim.EventSchema = "UserManagement"
$event.asim.EventSchemaVersion = "0.1.2"
$event.asim.EventSeverity = $event.asim.EventSeverity? else "Informational"
$event.asim.ActorUsername = $event.ocsf.actor?.user?.email_addr? else $event.ocsf.actor?.user?.name? else $event.ocsf.actor?.user?.uid? else $event.ocsf.actor?.app_name? else $event.ocsf.actor?.app_uid?
if $event.ocsf.actor?.user?.domain? != null and $event.ocsf.actor?.user?.name? != null {
$event.asim.ActorUsername = f"{$event.ocsf.actor.user.domain}\\{$event.ocsf.actor.user.name}"
$event.asim.ActorUsernameType = "Windows"
}
$event.asim.ActorUserId = $event.ocsf.actor?.user?.uid?
$event.asim.ActorUserIdType = "SID" if $event.asim.ActorUserId?.starts_with("S-") == true

match $event.ocsf.activity_name {
"Create" => { $event.asim.EventType = "UserCreated"}
"Delete" => { $event.asim.EventType = "UserDeleted"}
"Update" => { $event.asim.EventType = "UserModified"}
"Lock" => { $event.asim.EventType = "UserLocked"}
"Unlock" => { $event.asim.EventType = "UserUnlocked"}
"Disable" => { $event.asim.EventType = "UserDisabled"}
"Enable" => { $event.asim.EventType = "UserEnabled"}
"Password Change" => { $event.asim.EventType = "PasswordChanged"}
"Password Reset" => { $event.asim.EventType = "PasswordReset"}
_ => { $event.asim.EventType = "UserModified"}
}

$event.asim.TargetUsername = $event.ocsf.user?.email_addr? else $event.ocsf.user?.name? else $event.ocsf.user?.uid?
if $event.ocsf.user?.domain? != null and $event.ocsf.user?.name? != null {
$event.asim.TargetUsername = f"{$event.ocsf.user.domain}\\{$event.ocsf.user.name}"
$event.asim.TargetUsernameType = "Windows"
}
$event.asim.TargetUserId = $event.ocsf.user?.uid?
$event.asim.TargetUserIdType = "SID" if $event.asim.TargetUserId?.starts_with("S-") == true
$event.asim.GroupName = $event.ocsf.group?.name?
$event.asim.GroupId = $event.ocsf.group?.uid?
$event.asim.GroupIdType = "SID" if $event.asim.GroupId?.starts_with("S-") == true
$event.asim.SrcIpAddr = $event.ocsf.src_endpoint?.ip?
$event.asim.SrcHostname = $event.ocsf.src_endpoint?.hostname?

$event = move $event.asim
67 changes: 67 additions & 0 deletions microsoft/operators/asim/ocsf/authentication.tql
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
---
description: Maps OCSF Authentication events to Microsoft Sentinel ASIM Authentication events.
args:
named:
- name: event
description: The field that holds the OCSF event to map.
type: field
---

$event = {...$event, ocsf: $event, asim: {}}

assert $event.ocsf.class_uid == 3002

microsoft::asim::ocsf::common event=$event

@name = "asim.authentication"
$event.asim.EventSchema = "Authentication"
$event.asim.EventSchemaVersion = "0.1.4"
match $event.ocsf.activity_name {
"Logoff" => { $event.asim.EventType = "Logoff"}
_ => { $event.asim.EventType = "Logon"}
}
match $event.ocsf.logon_type? {
"System" => { $event.asim.EventSubType = "System"}
"Interactive" | "Cached Interactive" | "Unlock" | "Cached Unlock" => {
$event.asim.EventSubType = "Interactive"
}
"Network" | "Network Cleartext" => { $event.asim.EventSubType = "Remote"}
"Remote Interactive" | "Cached Remote Interactive" => {
$event.asim.EventSubType = "RemoteInteractive"
}
"OS Service" => { $event.asim.EventSubType = "Service"}
_ => {}
}
if $event.ocsf.logon_type? != null {
$event.asim.EventOriginalSubType = $event.ocsf.logon_type
}
$event.asim.ActorUsername = $event.ocsf.actor?.user?.email_addr? else $event.ocsf.actor?.user?.name? else $event.ocsf.actor?.user?.uid?
if $event.ocsf.actor?.user?.domain? != null and $event.ocsf.actor?.user?.name? != null {
$event.asim.ActorUsername = f"{$event.ocsf.actor.user.domain}\\{$event.ocsf.actor.user.name}"
$event.asim.ActorUsernameType = "Windows"
}
$event.asim.ActorUserId = $event.ocsf.actor?.user?.uid?
$event.asim.ActorUserIdType = "SID" if $event.asim.ActorUserId?.starts_with("S-") == true
$event.asim.ActorSessionId = $event.ocsf.actor?.session?.uid? else $event.ocsf.actor?.session?.uid_alt?
$event.asim.TargetUsername = $event.ocsf.user?.email_addr? else $event.ocsf.user?.name? else $event.ocsf.user?.uid?
if $event.ocsf.user?.domain? != null and $event.ocsf.user?.name? != null {
$event.asim.TargetUsername = f"{$event.ocsf.user.domain}\\{$event.ocsf.user.name}"
$event.asim.TargetUsernameType = "Windows"
$event.asim.TargetDomain = $event.ocsf.user.domain
$event.asim.TargetDomainType = "Windows"
}
$event.asim.TargetUserId = $event.ocsf.user?.uid?
$event.asim.TargetUserIdType = "SID" if $event.asim.TargetUserId?.starts_with("S-") == true
$event.asim.TargetSessionId = $event.ocsf.session?.uid? else $event.ocsf.session?.uid_alt?
$event.asim.SrcIpAddr = $event.ocsf.src_endpoint?.ip?
$event.asim.SrcHostname = $event.ocsf.src_endpoint?.hostname?
$event.asim.SrcPortNumber = $event.ocsf.src_endpoint?.port?
$event.asim.TargetHostname = $event.ocsf.dst_endpoint?.hostname? else $event.ocsf.device?.hostname?
$event.asim.TargetAppId = $event.ocsf.service?.uid? else $event.ocsf.dst_endpoint?.uid?
$event.asim.TargetAppName = $event.ocsf.service?.name? else $event.ocsf.dst_endpoint?.svc_name?
$event.asim.LogonProtocol = $event.ocsf.auth_protocol?
if $event.ocsf.auth_factors? != null {
$event.asim.LogonMethod = $event.ocsf.auth_factors[0]?.factor_type?
}

$event = move $event.asim
64 changes: 64 additions & 0 deletions microsoft/operators/asim/ocsf/authorize_session.tql
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
description: Maps OCSF Authorize Session events to Microsoft Sentinel ASIM Authentication events.
args:
named:
- name: event
description: The field that holds the OCSF event to map.
type: field
---

$event = {...$event, ocsf: $event, asim: {}}

assert $event.ocsf.class_uid == 3003

microsoft::asim::ocsf::common event=$event

@name = "asim.authentication"
$event.asim.EventSchema = "Authentication"
$event.asim.EventSchemaVersion = "0.1.4"
$event.asim.EventType = "Elevate"
match $event.ocsf.logon_type? {
"System" => { $event.asim.EventSubType = "System"}
"Interactive" | "Cached Interactive" | "Unlock" | "Cached Unlock" => {
$event.asim.EventSubType = "Interactive"
}
"Network" | "Network Cleartext" => { $event.asim.EventSubType = "Remote"}
"Remote Interactive" | "Cached Remote Interactive" => {
$event.asim.EventSubType = "RemoteInteractive"
}
"OS Service" => { $event.asim.EventSubType = "Service"}
_ => {}
}
if $event.ocsf.logon_type? != null {
$event.asim.EventOriginalSubType = $event.ocsf.logon_type
}
$event.asim.ActorUsername = $event.ocsf.actor?.user?.email_addr? else $event.ocsf.actor?.user?.name? else $event.ocsf.actor?.user?.uid?
if $event.ocsf.actor?.user?.domain? != null and $event.ocsf.actor?.user?.name? != null {
$event.asim.ActorUsername = f"{$event.ocsf.actor.user.domain}\\{$event.ocsf.actor.user.name}"
$event.asim.ActorUsernameType = "Windows"
}
$event.asim.ActorUserId = $event.ocsf.actor?.user?.uid?
$event.asim.ActorUserIdType = "SID" if $event.asim.ActorUserId?.starts_with("S-") == true
$event.asim.ActorSessionId = $event.ocsf.actor?.session?.uid? else $event.ocsf.actor?.session?.uid_alt?
$event.asim.TargetUsername = $event.ocsf.user?.email_addr? else $event.ocsf.user?.name? else $event.ocsf.user?.uid?
if $event.ocsf.user?.domain? != null and $event.ocsf.user?.name? != null {
$event.asim.TargetUsername = f"{$event.ocsf.user.domain}\\{$event.ocsf.user.name}"
$event.asim.TargetUsernameType = "Windows"
$event.asim.TargetDomain = $event.ocsf.user.domain
$event.asim.TargetDomainType = "Windows"
}
$event.asim.TargetUserId = $event.ocsf.user?.uid?
$event.asim.TargetUserIdType = "SID" if $event.asim.TargetUserId?.starts_with("S-") == true
$event.asim.TargetSessionId = $event.ocsf.session?.uid? else $event.ocsf.session?.uid_alt?
$event.asim.SrcIpAddr = $event.ocsf.src_endpoint?.ip?
$event.asim.SrcHostname = $event.ocsf.src_endpoint?.hostname?
$event.asim.SrcPortNumber = $event.ocsf.src_endpoint?.port?
$event.asim.TargetHostname = $event.ocsf.dst_endpoint?.hostname? else $event.ocsf.device?.hostname?
$event.asim.TargetAppId = $event.ocsf.service?.uid? else $event.ocsf.dst_endpoint?.uid?
$event.asim.TargetAppName = $event.ocsf.service?.name? else $event.ocsf.dst_endpoint?.svc_name?
$event.asim.LogonProtocol = $event.ocsf.auth_protocol?
if $event.ocsf.auth_factors? != null {
$event.asim.LogonMethod = $event.ocsf.auth_factors[0]?.factor_type?
}

$event = move $event.asim
Loading
Loading