Data Loss Prevention (microsoft-purview) — Vendor Schema¶
Source:
schemas/vendors/microsoft-purview-dlp/microsoft-purview-dlp.yaml
Identity¶
| Field | Value |
|---|---|
| vendor | microsoft-purview |
| product | Data Loss Prevention |
| data_source | msft_graph_security_alerts_raw |
| category | DLP |
Raw Schema¶
Fields available in the raw ingest dataset.
| Field | Type | Array | Status | JSON Subfields |
|---|---|---|---|---|
id |
string |
declared | ||
title |
string |
declared | ||
description |
string |
declared | ||
category |
string |
declared | ||
severity |
string |
declared | ||
status |
string |
declared | ||
serviceSource |
string |
declared | ||
detectionSource |
string |
declared | ||
productName |
string |
declared | ||
providerAlertId |
string |
declared | ||
alertWebUrl |
string |
declared | ||
incidentId |
string |
declared | ||
tenantId |
string |
declared | ||
firstActivityDateTime |
string |
declared | ||
lastActivityDateTime |
string |
declared | ||
alertPolicyId |
string |
declared | ||
mitreTechniques |
json |
✓ | declared | |
evidence |
json |
✓ | declared | @odata.type, userAccount, fileDetails, mdeDeviceId, detectionStatus, recipien... |
Correlation Rules¶
SOC Purview DLP - Policy Alert¶
| Field | Value |
|---|---|
| global_rule_id | SOC Purview DLP - Policy Alert |
| subtype | passthrough |
| fromversion | 6.10.0 |
Creates an XSIAM alert for each Microsoft Purview Data Loss Prevention alert in the Microsoft Graph Security feed (serviceSource = dataLossPrevention). Parses the Graph evidence for the acting user, the file, the message (email DLP) and the cloud app (SharePoint / OneDrive / Exchange), canonicalizes the user email-first as the grouping pivot, and groups with Defender alerts of the same Defender incident via the synthetic causality id. Injects DS:Microsoft/Data Loss Prevention and DOM:Security so Foundation Product Classification routes to DLP.
Tags: SOCFramework, Passthrough, DLP, MicrosoftPurview
Schema Constants¶
| Field | Value |
|---|---|
| rule_id | 0 |
| alert_category | User Defined |
| alert_domain | DOMAIN_SECURITY |
| action | ALERTS |
| execution_mode | SCHEDULED |
| mapping_strategy | CUSTOM |
| user_defined_category | tactic |
| user_defined_severity | severity |
| is_enabled | ✓ |
| drilldown_query_timeframe | ALERT |
| severity | User Defined |
Suppression¶
| Field | Value |
|---|---|
| enabled | ✓ |
| duration | 1 hours |
| fields | providerAlertId |
providerAlertId is Graph's per-alert unique id. Hourly suppression absorbs back-to-back polls of the same alert.
Alert Fields¶
Issue-field assignments emitted by the correlation rule. The Description column captures intent — when present, this is what downstream playbooks rely on the field meaning.
| Issue Field | Source | Bucket | Description |
|---|---|---|---|
vendor |
vendor |
computed |
|
product |
product |
computed |
|
originalalertid |
originalalertid |
computed |
|
originalalertname |
originalalertname |
computed |
|
originalalertsource |
originalalertsource |
computed |
|
externallink |
externallink |
computed |
|
alert_description |
alert_description |
computed |
|
severity |
severity |
computed |
|
mitretacticid |
mitretacticid |
computed |
|
mitretacticname |
mitretacticname |
computed |
|
mitretechniqueid |
mitretechniqueid |
computed |
|
mitretechniquename |
mitretechniquename |
computed |
|
agent_hostname |
agent_hostname |
computed |
|
agent_id |
agent_id |
computed |
|
agent_device_domain |
agent_device_domain |
computed |
|
actor_effective_username |
actor_effective_username |
computed |
|
action_file_name |
action_file_name |
computed |
|
action_file_path |
action_file_path |
computed |
|
action_file_sha256 |
action_file_sha256 |
computed |
|
user_principal |
user_principal |
computed |
|
userid |
user_principal |
computed |
|
usersid |
evidence_user_sid |
computed |
|
samaccountname |
evidence_user_sam |
computed |
|
username |
actor_effective_username |
computed |
|
causality_actor_causality_id |
causality_synth |
computed |
|
xdmsourceprocesscausalityid |
causality_synth |
computed |
|
hostname |
agent_hostname |
computed |
|
agentid |
agent_id |
computed |
|
filename |
action_file_name |
computed |
|
filepath |
action_file_path |
computed |
|
filesha256 |
action_file_sha256 |
computed |
|
socfwidentityuserdisplayname |
idr_display_name |
cie |
|
emailmessageid |
emailmessageid |
computed |
|
fw_email_recipient |
fw_email_recipient |
computed |
|
fw_email_sender |
fw_email_sender |
computed |
|
fw_email_subject |
fw_email_subject |
computed |
|
emailsource |
fw_email_sender |
computed |
|
socfwemaildeliveryaction |
socfwemaildeliveryaction |
computed |
|
dlp_alert_policy_id |
dlp_alert_policy_id |
computed |
|
dlp_incident_id |
dlp_incident_id |
computed |
|
dlp_first_activity |
dlp_first_activity |
computed |
|
dlp_last_activity |
dlp_last_activity |
computed |
|
dlp_app_name |
dlp_app_name |
computed |
|
dlp_app_instance |
dlp_app_instance |
computed |
|
dlp_app_id |
dlp_app_id |
computed |
|
dlp_file_size |
dlp_file_size |
computed |
|
dlp_file_action |
dlp_file_action |
computed |
|
dlp_recipient |
dlp_recipient |
computed |
|
dlp_attachments |
dlp_attachments |
computed |
|
tags |
alert_tags |
computed |
|
alert_name |
alert_name |
computed |
Pre-Alter XQL¶
// Vendor / product (required for SOCProductCategoryMap routing)
| alter vendor_name = "Microsoft", product_name = productName
// ---- Scope: Purview DLP alerts only (partition with MDE / MDO rules)
| filter serviceSource = "dataLossPrevention"
| filter status != "resolved"
// Tactic alias — drives user_defined_category
| alter tactic = category
// Severity: Graph severities are lowercase
| alter severity = if(
lowercase(severity) = "high", "High",
lowercase(severity) = "medium", "Medium",
lowercase(severity) = "low", "Low",
lowercase(severity) = "informational", "Informational",
"Low"
)
// MITRE — same derivation as the Defender contracts
| alter cat_norm = replace(replace(replace(replace(lowercase(category), " ", ""), "-", ""), "_", ""), ".", "")
| alter
mitre_tactic = category,
mitre_tactic_id = if(
cat_norm contains "exfiltration", "TA0010",
cat_norm contains "collection", "TA0009",
cat_norm contains "initialaccess", "TA0001",
cat_norm contains "impact", "TA0040",
""),
mitre_technique_first = arrayindex(mitreTechniques -> [], 0),
mitre_technique_str = arraystring(mitreTechniques -> [], ",")
// ---- Evidence: first element of each type
| alter
userEvidence = arrayindex(arrayfilter(evidence -> [], "@element" -> ["@odata.type"] contains "userEvidence"), 0),
fileEvidence = arrayindex(arrayfilter(evidence -> [], "@element" -> ["@odata.type"] contains "fileEvidence"), 0),
messageEvidence = arrayindex(arrayfilter(evidence -> [], "@element" -> ["@odata.type"] contains "analyzedMessageEvidence"), 0),
appEvidence = arrayindex(arrayfilter(evidence -> [], "@element" -> ["@odata.type"] contains "cloudApplicationEvidence"), 0),
deviceEvidence = arrayindex(arrayfilter(evidence -> [], "@element" -> ["@odata.type"] contains "deviceEvidence"), 0)
| alter
evidence_user_upn = userEvidence -> userAccount.userPrincipalName,
evidence_user_sid = userEvidence -> userAccount.userSid,
evidence_user_display = userEvidence -> userAccount.displayName,
evidence_user_domain = userEvidence -> userAccount.domainName,
evidence_user_sam = userEvidence -> userAccount.accountName
| alter
dlp_file_name = fileEvidence -> fileDetails.fileName,
dlp_file_path = fileEvidence -> fileDetails.filePath,
dlp_file_sha256 = fileEvidence -> fileDetails.sha256,
dlp_file_size = fileEvidence -> fileDetails.fileSize,
dlp_file_device = fileEvidence -> mdeDeviceId,
dlp_file_action = fileEvidence -> detectionStatus
| alter
dlp_recipient = messageEvidence -> recipientEmailAddress,
dlp_sender = messageEvidence -> p1Sender.emailAddress,
dlp_subject = messageEvidence -> subject,
dlp_internet_msg = messageEvidence -> internetMessageId,
dlp_network_msg = messageEvidence -> networkMessageId,
dlp_delivery = messageEvidence -> deliveryAction,
dlp_attachments = messageEvidence -> attachmentsCount
| alter
dlp_app_name = appEvidence -> displayName,
dlp_app_instance = appEvidence -> instanceName,
dlp_app_id = appEvidence -> saasAppId,
dlp_device_host = deviceEvidence -> hostName,
dlp_device_id = deviceEvidence -> mdeDeviceId
// ---- Identity: the acting user, email-first. For email DLP the sender
// (an internal user) is the actor; the recipient is the destination.
| alter acting_user = lowercase(coalesce(evidence_user_upn, dlp_sender))
| alter user_principal = acting_user
| alter user_name = coalesce(acting_user, evidence_user_sam)
| alter display_name = evidence_user_display
| alter actor_effective_username = acting_user
// Cross-rule grouping: same synthetic causality as MDE / MDO365
| alter causality_synth = if(incidentId != null, concat("msgraph-incident-", to_string(incidentId)), null)
// Title: [DLP] {user} - {tactic}: {policy alert title}
| alter alert_name = concat(
"[DLP] ",
coalesce(acting_user, "Unknown User"),
" - ",
coalesce(category, "Policy Match"),
": ",
coalesce(title, "Purview DLP alert")
)
| alter alert_description = concat(
coalesce(description, "Microsoft Purview DLP policy alert"),
" | User: ", coalesce(acting_user, "Unknown"),
" | App: ", coalesce(dlp_app_name, dlp_app_instance, "-"),
" | File: ", coalesce(dlp_file_name, "-"),
" | Recipient: ", coalesce(dlp_recipient, "-"),
" | Subject: ", coalesce(dlp_subject, ""),
" | Severity: ", coalesce(severity, "Unknown")
)
// ============================================================
// CANONICAL CORE NORMALIZATION
// ============================================================
| alter
vendor = vendor_name,
product = product_name,
originalalertid = providerAlertId,
originalalertname = alert_name,
originalalertsource = productName,
externallink = alertWebUrl,
severity = severity,
mitretacticid = mitre_tactic_id,
mitretacticname = mitre_tactic,
mitretechniqueid = mitre_technique_first,
mitretechniquename = mitre_technique_str,
agent_hostname = dlp_device_host,
agent_id = coalesce(dlp_device_id, dlp_file_device),
agent_device_domain = evidence_user_domain,
actor_process_image_name = null,
actor_process_image_path = null,
actor_process_image_sha256 = null,
actor_process_command_line = null,
actor_process_os_pid = null,
causality_actor_process_image_name = null,
causality_actor_process_image_path = null,
causality_actor_process_image_sha256 = null,
action_file_name = dlp_file_name,
action_file_path = dlp_file_path,
action_file_sha256 = dlp_file_sha256,
action_local_ip = null,
action_remote_ip = null
// ---- DLP surface + email parity fields
| alter
dlp_alert_policy_id = alertPolicyId,
dlp_incident_id = to_string(incidentId),
dlp_first_activity = firstActivityDateTime,
dlp_last_activity = lastActivityDateTime,
emailmessageid = dlp_internet_msg,
fw_email_recipient = dlp_recipient,
fw_email_sender = dlp_sender,
fw_email_subject = dlp_subject,
socfwemaildeliveryaction = dlp_delivery
// Tag injection — DS:Microsoft/Data Loss Prevention → ds_microsoft_data_loss_prevention
| alter alert_tags = arraycreate("DS:Microsoft/Data Loss Prevention", "DOM:Security")