โ† Back to articles Security

Microsoft Purview DLP Enhances Defender Alerts with Graph API Data Export

Microsoft Purview DLP Enhances Defender Alerts with Graph API Data Export

Microsoft continues to strengthen its security ecosystem with a significant enhancement to Microsoft Purview's Data Loss Prevention (DLP) capabilities. The new Graph API infrastructure allows organizations to seamlessly export DLP event data to enrich Microsoft Defender alerts, creating a more comprehensive security monitoring experience. This integration bridges the gap between data protection and threat detection, providing security teams with richer context when investigating potential incidents.

Understanding the Enhanced Integration Context

Microsoft Purview DLP has long been a cornerstone of data protection strategies for organizations worldwide. However, security teams often struggled with siloed information where DLP events existed separately from broader security alerts in Microsoft Defender. This separation created blind spots and required manual correlation of events across different security tools.

The enhanced Graph API infrastructure addresses this challenge by providing a standardized, programmatic way to export DLP event data and correlate it with Defender alerts. This integration is part of Microsoft's broader strategy to create a unified security operations center (SOC) experience across its security portfolio.

Currently in General Availability for Worldwide Standard Multi-Tenant environments, this enhancement represents a significant step forward in security data integration. Organizations can now leverage the wealth of DLP event data to provide additional context to security incidents, improving both detection accuracy and response times.

The Challenge: Fragmented Security Data

Before this enhancement, security teams faced several critical challenges:

  • Data Silos: DLP events were confined to the Purview compliance portal, while security alerts lived in Microsoft Defender
  • Manual Correlation: Analysts had to manually cross-reference DLP events with security incidents, consuming valuable time
  • Incomplete Context: Security investigations lacked crucial data protection context that could indicate the severity or scope of an incident
  • Limited API Access: Existing API endpoints provided limited DLP event data, making automated integration difficult
  • Inconsistent Reporting: Different data formats and structures across security tools hindered comprehensive reporting

These challenges often resulted in delayed incident response, missed correlations between data exfiltration attempts and security breaches, and an incomplete understanding of the organization's security posture.

Implementing DLP Event Data Export via Graph API

Prerequisites and Permissions

Before implementing the enhanced Graph API integration, ensure your environment meets the following requirements:

  • Microsoft 365 E5 or equivalent licensing with Purview DLP
  • Microsoft Defender for Office 365 or Microsoft 365 Defender
  • Appropriate Graph API permissions (SecurityEvents.Read.All, SecurityAlert.ReadWrite.All)
  • PowerShell 7.0 or later with Microsoft.Graph module

Step 1: Configure Graph API Application Registration

First, register an application in Azure AD with the necessary permissions to access both DLP events and Defender alerts:

# Connect to Microsoft Graph
Connect-MgGraph -Scopes "Application.ReadWrite.All", "Directory.ReadWrite.All"

# Create application registration
$appRegistration = New-MgApplication -DisplayName "DLP-Defender Integration" -SignInAudience "AzureADMyOrg"

# Add required API permissions
$requiredResourceAccess = @(
    @{
        ResourceAppId = "00000003-0000-0000-c000-000000000000" # Microsoft Graph
        ResourceAccess = @(
            @{
                Id = "7438b122-aefc-4978-80ed-43db9fcc7715" # SecurityEvents.Read.All
                Type = "Role"
            },
            @{
                Id = "ed4fca05-be46-441f-9803-1873825f8fdb" # SecurityAlert.ReadWrite.All
                Type = "Role"
            },
            @{
                Id = "45cc0394-e837-488b-a098-1918f48d186c" # SecurityIncident.ReadWrite.All
                Type = "Role"
            }
        )
    }
)

Update-MgApplication -ApplicationId $appRegistration.Id -RequiredResourceAccess $requiredResourceAccess

# Create service principal
$servicePrincipal = New-MgServicePrincipal -AppId $appRegistration.AppId

Write-Host "Application ID: $($appRegistration.AppId)"
Write-Host "Service Principal ID: $($servicePrincipal.Id)"

Step 2: Create Client Secret and Grant Admin Consent

# Create client secret
$passwordCredential = @{
    DisplayName = "DLP-Defender-Secret"
    EndDateTime = (Get-Date).AddYears(1)
}

$clientSecret = Add-MgApplicationPassword -ApplicationId $appRegistration.Id -PasswordCredential $passwordCredential

Write-Host "Client Secret: $($clientSecret.SecretText)" -ForegroundColor Yellow
Write-Host "Store this secret securely - it won't be shown again!" -ForegroundColor Red

# Note: Admin consent must be granted through Azure Portal or via PowerShell with appropriate permissions

Step 3: Retrieve DLP Events Using Enhanced Graph API

With the enhanced API infrastructure, retrieving DLP events becomes more streamlined:

# Authenticate using service principal
$tenantId = "your-tenant-id"
$clientId = $appRegistration.AppId
$clientSecret = "your-client-secret"

$body = @{
    grant_type = "client_credentials"
    scope = "https://graph.microsoft.com/.default"
    client_id = $clientId
    client_secret = $clientSecret
}

$authResponse = Invoke-RestMethod -Uri "https://login.microsoftonline.com/$tenantId/oauth2/v2.0/token" -Method POST -Body $body
$accessToken = $authResponse.access_token

# Set headers for Graph API calls
$headers = @{
    "Authorization" = "Bearer $accessToken"
    "Content-Type" = "application/json"
}

# Retrieve DLP events with enhanced data
$dlpEventsUri = "https://graph.microsoft.com/v1.0/security/alerts_v2?`$filter=classification eq 'dataLossPrevention' and createdDateTime ge $((Get-Date).AddDays(-7).ToString('yyyy-MM-ddTHH:mm:ss.fffZ'))"

$dlpEvents = Invoke-RestMethod -Uri $dlpEventsUri -Headers $headers -Method GET

# Display enhanced DLP event data
foreach ($event in $dlpEvents.value) {
    Write-Host "Alert ID: $($event.id)"
    Write-Host "Title: $($event.title)"
    Write-Host "Severity: $($event.severity)"
    Write-Host "Classification: $($event.classification)"
    Write-Host "DLP Policy: $($event.additionalData.dlpPolicyName)"
    Write-Host "Sensitive Info Types: $($event.additionalData.sensitiveInfoTypes -join ', ')"
    Write-Host "---"
}

Step 4: Enrich Defender Alerts with DLP Context

Now implement the correlation logic to enrich Defender alerts with DLP event data:

# Function to correlate DLP events with Defender alerts
function Add-DlpContextToDefenderAlerts {
    param(
        [string]$AccessToken,
        [int]$DaysBack = 7
    )
    
    $headers = @{
        "Authorization" = "Bearer $AccessToken"
        "Content-Type" = "application/json"
    }
    
    # Get Defender alerts
    $defenderAlertsUri = "https://graph.microsoft.com/v1.0/security/alerts_v2?`$filter=createdDateTime ge $((Get-Date).AddDays(-$DaysBack).ToString('yyyy-MM-ddTHH:mm:ss.fffZ'))"
    $defenderAlerts = Invoke-RestMethod -Uri $defenderAlertsUri -Headers $headers -Method GET
    
    # Get DLP events
    $dlpEventsUri = "https://graph.microsoft.com/v1.0/security/alerts_v2?`$filter=classification eq 'dataLossPrevention' and createdDateTime ge $((Get-Date).AddDays(-$DaysBack).ToString('yyyy-MM-ddTHH:mm:ss.fffZ'))"
    $dlpEvents = Invoke-RestMethod -Uri $dlpEventsUri -Headers $headers -Method GET
    
    foreach ($defenderAlert in $defenderAlerts.value) {
        # Correlation logic based on user, time, and affected resources
        $correlatedDlpEvents = $dlpEvents.value | Where-Object {
            ($_.additionalData.userPrincipalName -eq $defenderAlert.additionalData.userPrincipalName) -and
            ([DateTime]$_.createdDateTime -ge [DateTime]$defenderAlert.createdDateTime.AddMinutes(-30)) -and
            ([DateTime]$_.createdDateTime -le [DateTime]$defenderAlert.createdDateTime.AddMinutes(30))
        }
        
        if ($correlatedDlpEvents.Count -gt 0) {
            # Prepare enrichment data
            $enrichmentData = @{
                dlpEventsCount = $correlatedDlpEvents.Count
                dlpPolicies = ($correlatedDlpEvents.additionalData.dlpPolicyName | Select-Object -Unique) -join ", "
                sensitiveInfoTypes = ($correlatedDlpEvents.additionalData.sensitiveInfoTypes | Select-Object -Unique) -join ", "
                dataClassifications = ($correlatedDlpEvents.additionalData.dataClassifications | Select-Object -Unique) -join ", "
            }
            
            # Update Defender alert with DLP context
            $updateBody = @{
                comments = @(
                    @{
                        comment = "Enriched with DLP context: $($enrichmentData.dlpEventsCount) related DLP events found. Policies: $($enrichmentData.dlpPolicies). Sensitive data types: $($enrichmentData.sensitiveInfoTypes)"
                        createdBy = "DLP-Defender Integration"
                        createdDateTime = (Get-Date).ToString('yyyy-MM-ddTHH:mm:ss.fffZ')
                    }
                )
                customProperties = $enrichmentData
            } | ConvertTo-Json -Depth 3
            
            $updateUri = "https://graph.microsoft.com/v1.0/security/alerts_v2/$($defenderAlert.id)"
            
            try {
                Invoke-RestMethod -Uri $updateUri -Headers $headers -Method PATCH -Body $updateBody
                Write-Host "Successfully enriched alert $($defenderAlert.id) with DLP context" -ForegroundColor Green
            }
            catch {
                Write-Warning "Failed to enrich alert $($defenderAlert.id): $($_.Exception.Message)"
            }
        }
    }
}

# Execute the enrichment process
Add-DlpContextToDefenderAlerts -AccessToken $accessToken -DaysBack 7

Step 5: Automate with Azure Logic Apps Integration

For continuous monitoring, create an Azure Logic App to automate this process:

{
    "definition": {
        "$schema": "https://schema.management.azure.com/providers/Microsoft.Logic/schemas/2016-06-01/workflowdefinition.json#",
        "actions": {
            "Get_DLP_Events": {
                "type": "Http",
                "inputs": {
                    "method": "GET",
                    "uri": "https://graph.microsoft.com/v1.0/security/alerts_v2?$filter=classification eq 'dataLossPrevention' and createdDateTime ge @{addMinutes(utcNow(), -60)}",
                    "headers": {
                        "Authorization": "Bearer @{body('Get_Access_Token')['access_token']}"
                    }
                }
            },
            "Get_Defender_Alerts": {
                "type": "Http",
                "inputs": {
                    "method": "GET",
                    "uri": "https://graph.microsoft.com/v1.0/security/alerts_v2?$filter=createdDateTime ge @{addMinutes(utcNow(), -60)}",
                    "headers": {
                        "Authorization": "Bearer @{body('Get_Access_Token')['access_token']}"
                    }
                }
            },
            "Correlate_and_Enrich": {
                "type": "Foreach",
                "foreach": "@body('Get_Defender_Alerts')['value']",
                "actions": {
                    "Update_Alert_with_DLP_Context": {
                        "type": "Http",
                        "inputs": {
                            "method": "PATCH",
                            "uri": "https://graph.microsoft.com/v1.0/security/alerts_v2/@{items('Correlate_and_Enrich')['id']}",
                            "headers": {
                                "Authorization": "Bearer @{body('Get_Access_Token')['access_token']}",
                                "Content-Type": "application/json"
                            },
                            "body": {
                                "customProperties": {
                                    "dlpCorrelationProcessed": true,
                                    "dlpEventsFound": "@{length(variables('CorrelatedDlpEvents'))}"
                                }
                            }
                        }
                    }
                }
            }
        },
        "triggers": {
            "Recurrence": {
                "type": "Recurrence",
                "recurrence": {
                    "frequency": "Hour",
                    "interval": 1
                }
            }
        }
    }
}

Verification and Results

After implementing the enhanced Graph API integration, you should observe the following improvements:

Verify DLP Event Data Export

# Verification script to confirm enhanced data availability
$verificationUri = "https://graph.microsoft.com/v1.0/security/alerts_v2?`$filter=classification eq 'dataLossPrevention'&`$select=id,title,classification,additionalData&`$top=5"

$verificationResult = Invoke-RestMethod -Uri $verificationUri -Headers $headers -Method GET

foreach ($event in $verificationResult.value) {
    Write-Host "Verifying enhanced DLP data for event: $($event.id)"
    Write-Host "Additional Data Keys: $($event.additionalData.PSObject.Properties.Name -join ', ')"
    
    # Check for enhanced properties
    $enhancedProperties = @('dlpPolicyName', 'sensitiveInfoTypes', 'dataClassifications', 'userPrincipalName')
    $missingProperties = $enhancedProperties | Where-Object { $_ -notin $event.additionalData.PSObject.Properties.Name }
    
    if ($missingProperties.Count -eq 0) {
        Write-Host "โœ… All enhanced properties present" -ForegroundColor Green
    } else {
        Write-Host "โŒ Missing properties: $($missingProperties -join ', ')" -ForegroundColor Red
    }
}

Monitor Enriched Defender Alerts

Check that Defender alerts are being enriched with DLP context:

# Query enriched alerts
$enrichedAlertsUri = "https://graph.microsoft.com/v1.0/security/alerts_v2?`$filter=customProperties/any(cp: cp/name eq 'dlpEventsCount')"
$enrichedAlerts = Invoke-RestMethod -Uri $enrichedAlertsUri -Headers $headers -Method GET

Write-Host "Found $($enrichedAlerts.value.Count) alerts enriched with DLP context"

foreach ($alert in $enrichedAlerts.value) {
    Write-Host "Alert: $($alert.title)"
    Write-Host "DLP Events: $($alert.customProperties.dlpEventsCount)"
    Write-Host "DLP Policies: $($alert.customProperties.dlpPolicies)"
    Write-Host "---"
}

Key Takeaways

  • Enhanced API Infrastructure: The new Graph API endpoints provide comprehensive DLP event data with additional context fields for better integration
  • Improved Security Visibility: Correlating DLP events with Defender alerts creates a more complete security picture and enables faster incident response
  • Automated Enrichment: PowerShell scripts and Logic Apps can automate the correlation process, reducing manual effort for security teams
  • Standardized Data Export: The enhanced API provides consistent data formats that integrate seamlessly with existing security workflows
  • Real-time Context: Security analysts now have immediate access to data protection context when investigating security incidents
  • Scalable Implementation: The solution can be implemented across large environments with proper automation and monitoring
  • Compliance Integration: This enhancement bridges the gap between compliance and security operations, supporting both regulatory requirements and threat detection

This enhancement represents a significant step forward in Microsoft's unified security strategy, providing organizations with the tools needed to create comprehensive, context-aware security operations. By implementing these capabilities, security teams can achieve better threat detection, faster incident response, and more effective data protection across their Microsoft 365 environment.

๐ŸŽ“ Ready to go deeper?

Practice real MD-102 exam questions, get AI feedback on your weak areas, and fast-track your Intune certification.

Start Free Practice โ†’ Book a Session
Souhaiel Morhag
Souhaiel Morhag
Microsoft Endpoint & Modern Workplace Engineer

Souhaiel is a Microsoft Intune and endpoint management specialist with hands-on experience deploying and securing enterprise environments across Microsoft 365. He founded MSEndpoint.com to share practical, real-world guides for IT admins navigating Microsoft technologies โ€” and built the MSEndpoint Academy at app.msendpoint.com/academy, a dedicated learning platform for professionals preparing for the MD-102 (Microsoft 365 Endpoint Administrator) certification. Through in-depth articles and AI-powered practice exams, Souhaiel helps IT teams move faster and certify with confidence.

Related Articles