Cloud App Security Alerts Join the Office 365 Audit Data
Office 365 keeps on changing. The recent announcement that Microsoft is surfacing Office 365 Cloud App Security alerts through extra interfaces is an example of a change that might be considered small, unless you work in the area of security and compliance.
One thing that attracted my attention is the fact that Office 365 Cloud App Security (bundled with E5 licenses) now sends its alerts to the Office 365 audit log. This makes sense because Office 365 alerts and alert policies are powered by the events captured in the audit log.
Analyzing Cloud App Security Audit Records
In any case, events in the audit log show up with RecordType SecurityComplianceAlerts. Like all events in the audit log, some work is needed to unpack and interpret the information stored in the AuditData property. I used some code from Chapter 21 of the Office 365 for IT Pros eBook to examine what useful material is included by running the Search-UnifiedAuditLog cmdlet to retrieve the records.
Office 365 audit log records are normalized, but only to a point. Normalization means that a set of the same basic fields are included in all records, no matter what workload generates a record. The devil in the detail is that the contents of the AuditData property is open to interpretation and each workload can do its own thing in terms of what is output. And in the case of Cloud App Security, the contents of AuditData vary depending on an alert.
The upshot is that more work than should be necessary is needed to parse the data to make it useful for reporting and analysis. I only found two types of alerts generated by Cloud App Security, so that’s what the code below deals with. You might find others and need to update the code to handle whatever Microsoft decided to stuff into AuditData for the alert.
$Records = (Search-UnifiedAuditLog -RecordType SecurityComplianceAlerts -StartDate 1-Jan-2019 -EndDate 30-Jan-2019 -Formatted -ResultSize 3000) If ($Records.Count -eq 0) { Write-Host "No alert audit records found." } Else { Write-Host "Processing" $Records.Count "audit records..." $Report = @() ForEach ($Rec in $Records) { $AuditData = ConvertFrom-Json $Rec.Auditdata $Data = ConvertFrom-Json $Auditdata.data If ($Rec.Operations -eq "AlertTriggered") { $ReportLine = [PSCustomObject]@{ TimeStamp; = $Rec.CreationDate User = $Data.f3u Action = $Data.an Status = $AuditData.ResultStatus Severity = $AuditData.Severity Workload = $AuditData.Source Operation = $Rec.Operations Category = $AuditData.Category } $Report += $ReportLine} Else { $ReportLine = [PSCustomObject]@{ TimeStamp = $Rec.CreationDate User = $Data.eid Action = $Data.lon Status = $AuditData.ResultStatus Severity = $AuditData.Severity Workload = $AuditData.Source Operation = $Rec.Operations Category = $AuditData.Category } $Report += $ReportLine} }} $Report | Select Timestamp, Operation, User, Action Processing 42 audit records... TimeStamp Operation User Action --------- --------- ---- ------ 21 Jan 2019 16:58:00 AlertEntityGenerated Tony.Redmond@ eDiscoverySearchStartedOrExported 21 Jan 2019 16:58:00 AlertTriggered Tony.Redmond@ eDiscovery search started or exported 2 Jan 2019 19:54:00 AlertTriggered Tony.Redmond@ eDiscovery search started or exported …
It’s worth pointing out that some of the alerts that flow into the audit log duplicate events already logged by a workload, which is certainly the case for the eDiscovery searches featured above.
Always Tracking New Developments
We’ll continue to track what happens as Microsoft releases the other updates mentioned in their post and update whatever we need to in the Office 365 for IT Pros eBook. Keeping up-to-date with developments inside Office 365 is what we do!