This guide shows you how to map events to Microsoft Sentinel Advanced Security Information Model (ASIM) records in TQL. You’ll learn how to choose an ASIM schema, populate schema and product metadata, map role-prefixed fields, normalize event results, and preserve unmapped source fields.
Use the ASIM skill
Section titled “Use the ASIM skill”Install the tenzir-asim skill when you want an agent to help with ASIM schema
decisions. See
Use agent skills for
installation and usage examples.
Ask the agent to choose the event or entity schema before it maps fields. ASIM
fields use Microsoft Sentinel column names such as EventSchema,
EventSchemaVersion, SrcIpAddr, and DstIpAddr. Prefer canonical fields
over aliases when you build reusable mappings, analytics rules, or workbooks.
Choose the ASIM schema
Section titled “Choose the ASIM schema”Start by choosing EventSchema and EventSchemaVersion for event records, or
EntitySchema and EntitySchemaVersion for entity records. These fields
identify the schema contract that the record follows.
For a firewall connection event, choose the NetworkSession schema. It
describes IP network activity from sources such as firewalls, NetFlow records,
routers, operating systems, and intrusion prevention systems.
For a NetworkSession event, start with these core fields:
EventSchema: The schema name. UseNetworkSession.EventSchemaVersion: The schema version. Use0.2.7forNetworkSession.EventType: The activity scenario, such asNetworkSession,Flow, orEndpointNetworkSession.EventVendorandEventProduct: The source product context.EventStartTimeandEventEndTime: The activity time range.EventResult: The normalized result, such asSuccessorFailure.Src*andDst*: The source and destination participants.
Write a small mapping
Section titled “Write a small mapping”The following example maps a parsed firewall connection event to an ASIM
NetworkSession record. It keeps the source data under fw, sets the ASIM
schema constants, normalizes the device action and result, maps source and
destination fields, and preserves unmapped residue in AdditionalFields.
from { ts: 2024-01-15T10:30:45Z, action: "allowed", src_ip: "10.0.0.5", src_port: 51544, dst_ip: "203.0.113.10", dst_port: 443, proto: "tcp", bytes_out: 1280, bytes_in: 8192, device: "edge-fw-01",}
this = {fw: this}
let $actions = { allow: "Allow", allowed: "Allow", block: "Deny", blocked: "Deny", deny: "Deny", denied: "Deny", drop: "Drop", dropped: "Drop",}
let $results = { allow: "Success", allowed: "Success", block: "Failure", blocked: "Failure", deny: "Failure", denied: "Failure", drop: "Failure", dropped: "Failure",}
asim.EventSchema = "NetworkSession"asim.EventSchemaVersion = "0.2.7"asim.EventType = "NetworkSession"asim.EventCount = 1asim.EventStartTime = fw.tsasim.EventEndTime = move fw.tsasim.EventVendor = "Example Networks"asim.EventProduct = "Example Firewall"asim.Dvc = fw.deviceasim.DvcHostname = move fw.deviceasim.DvcAction = $actions[fw.action.to_lower()]? else fw.actionasim.EventResult = $results[fw.action.to_lower()]? else "NA"asim.DvcOriginalAction = move fw.actionasim.SrcIpAddr = move fw.src_ipasim.SrcPortNumber = move fw.src_portasim.DstIpAddr = move fw.dst_ipasim.DstPortNumber = move fw.dst_portasim.NetworkProtocol = (move fw.proto).to_upper()asim.SrcBytes = move fw.bytes_outasim.DstBytes = move fw.bytes_inasim.NetworkBytes = asim.SrcBytes + asim.DstBytes
this = {...asim, AdditionalFields: fw}{ EventSchema: "NetworkSession", EventSchemaVersion: "0.2.7", EventType: "NetworkSession", EventCount: 1, EventStartTime: 2024-01-15T10:30:45Z, EventEndTime: 2024-01-15T10:30:45Z, EventVendor: "Example Networks", EventProduct: "Example Firewall", Dvc: "edge-fw-01", DvcHostname: "edge-fw-01", DvcAction: "Allow", EventResult: "Success", DvcOriginalAction: "allowed", SrcIpAddr: "10.0.0.5", SrcPortNumber: 51544, DstIpAddr: "203.0.113.10", DstPortNumber: 443, NetworkProtocol: "TCP", SrcBytes: 1280, DstBytes: 8192, NetworkBytes: 9472, AdditionalFields: {},}Apply the mapping pattern
Section titled “Apply the mapping pattern”Use the same structure for larger mappings:
- Keep a source namespace: Move the parsed event under a short namespace
such as
fw,dns,edr, oreventbefore you create ASIM fields. - Set the schema fields early: Let
EventSchemaandEventSchemaVersiondrive which field records, constants, and conditional requirements you apply. - Map participants with role prefixes: Use prefixes such as
Src,Dst,Actor,Target,Acting, andDvcto distinguish entities in the event. - Populate by field class: Start with
Mandatoryfields, add usefulRecommendedfields, and populateConditionalfields when their documented condition applies. - Normalize enum values explicitly: Map source strings to ASIM values such
as
Allow,Deny,Success,Failure,TCP, orUDP. - Prefer canonical fields: Resolve aliases to canonical ASIM fields before you build reusable mappings or detections.
- Preserve unmapped fields: Keep source fields that don’t have a deliberate
ASIM target in
AdditionalFieldsso reviewers can audit the mapping.