Unified Audit Log Investigation: Fields That Matter for BEC
Reading the Unified Audit Log in a BEC case: the AuditData JSON, the operations to filter on, and how SessionId and UniqueTokenId link actions to sign-ins.
TL;DR. In a UAL export, the CSV columns are an index; the evidence is in the AuditData JSON. For a BEC, filter on a short list of operations (New-InboxRule, Set-InboxRule, UpdateInboxRules, Set-Mailbox, MailItemsAccessed, Send, SoftDelete/HardDelete, SearchQueryInitiatedExchange, FileDownloaded, Consent to application., User registered security info), then read the workload-specific fields. The pivot that turns suspicion into attribution is AppAccessContext.AADSessionId and UniqueTokenId, which match the Entra sign-in's Session ID and Unique token identifier.
The Unified Audit Log records user and admin activity across Exchange Online, SharePoint, OneDrive, Entra ID, Teams and more in one place. That breadth is also its difficulty: one tenant-wide export can hold hundreds of thousands of rows in which the BEC is a few dozen. This article is the field guide I wish I had the first time.
Anatomy of an export row
A Purview portal export has columns RecordId, CreationDate, RecordType, Operation, UserId, AuditData, AssociatedAdminUnits, AssociatedAdminUnitsNames. A PowerShell Search-UnifiedAuditLog | Export-Csv export has similar columns (RecordType, CreationDate, UserIds, Operations, AuditData, ResultIndex, ResultCount, Identity…). In both, AuditData is a JSON string with the full record.
Common AuditData fields:
| Field | Meaning | Notes |
|---|---|---|
CreationTime | Event time, UTC | Often without a trailing Z |
Id | Record identifier | Use it to deduplicate overlapping exports |
Operation | What happened | Case and trailing dot vary (Consent to application.) |
Workload | Exchange, SharePoint, OneDrive, AzureActiveDirectory… | |
UserId | Who did it | UPN, or a system identity |
ClientIP / ClientIPAddress / ActorIpAddress | Source IP | May include a port or brackets ([2001:db8::1]:443) |
ResultStatus | Succeeded, True, Success… | Inconsistent between workloads |
AppAccessContext | AADSessionId, UniqueTokenId, IssuedAtTime | The link to the sign-in |
The UAL has no geolocation. Country and network come from matching the IP against the Entra sign-in logs, or from an external lookup.
The operations that matter in a BEC
| Operation | Workload | Why it matters | Fields to read |
|---|---|---|---|
New-InboxRule, Set-InboxRule, Enable-InboxRule | Exchange | Rules created with PowerShell or Outlook on the web | Parameters: Name, ForwardTo, RedirectTo, DeleteMessage, MoveToFolder, SubjectOrBodyContainsWords, From |
UpdateInboxRules | Exchange | Rules created from the Outlook desktop client | OperationProperties: RuleName, RuleActions, RuleCondition |
Set-Mailbox | Exchange | Mailbox (SMTP) forwarding, audit changes | ForwardingSmtpAddress, ForwardingAddress, DeliverToMailboxAndForward, AuditEnabled |
Add-MailboxPermission, Add-RecipientPermission | Exchange | Delegation for persistence | User, AccessRights |
MailItemsAccessed | Exchange | Which messages were read or synced | OperationProperties.MailAccessType (Bind/Sync), Folders, OperationCount, ClientInfoString |
Send, SendAs, SendOnBehalf | Exchange | Mail sent from the mailbox | Item.Subject, Item.InternetMessageId |
SoftDelete, HardDelete, MoveToDeletedItems | Exchange | Cover-up | AffectedItems, Folder |
SearchQueryInitiatedExchange | Exchange | What the attacker searched for | QueryText (logging must be enabled) |
FileDownloaded, FileSyncDownloadedFull | SharePoint / OneDrive | Data theft | SourceFileName, SiteUrl, UserAgent |
UserLoggedIn, UserLoginFailed | AzureActiveDirectory | Sign-ins mirrored in the UAL | ExtendedProperties, DeviceProperties.SessionId |
Consent to application., Add delegated permission grant. | AzureActiveDirectory | Illicit consent | ModifiedProperties (ConsentAction.Permissions, ConsentContext.IsAdminConsent) |
User registered security info, Update user. | AzureActiveDirectory | Attacker's MFA method | ModifiedProperties (StrongAuthentication…) |
Set-AdminAuditLogConfig, Set-MailboxAuditBypassAssociation | Exchange | Audit tampering | UnifiedAuditLogIngestionEnabled, AuditBypassEnabled |
Microsoft's audit log activities page is the full reference. Two traps: operation names from Entra ID often end with a dot, and Parameters is an array of {Name, Value} pairs, not an object, so a naïve JSON path misses it.
Why rules show up in two different shapes
An inbox rule created in Outlook on the web or with PowerShell is logged as New-InboxRule with readable Parameters. A rule created in the Outlook desktop client is logged as UpdateInboxRules with OperationProperties such as RuleActions and RuleCondition, which are less structured. Search for both. Malicious inbox rules and forwarding covers the parameters to read.
The session pivot
Microsoft embeds a session ID (sid) and a unique token identifier (uti) in the tokens it issues, and surfaces them in the logs as linkable identifiers. According to Microsoft Learn:
| Claim | Entra sign-in log | Exchange Online audit | SharePoint / Teams audit |
|---|---|---|---|
sid | Session ID | SessionId / AppAccessContext.AADSessionId | AppAccessContext.AADSessionId |
uti | Unique token identifier | AppAccessContext.UniqueTokenId | AppAccessContext.UniqueTokenId |
iat | Date | AppAccessContext.IssuedAtTime | AppAccessContext.IssuedAtTime |
The workflow:
- In the Entra sign-in logs, identify the suspicious sign-in and copy its Session ID (for replay, the session that appears from two networks).
- In the UAL export, keep every record whose
AADSessionIdorSessionIdequals it. - Add records whose
UniqueTokenIdmatches a token issued to the attacker's IP. - Add records from the attacker's IP for anything the first two missed.
Microsoft notes that linkable identifiers are missing on some aggregated entries and records from background processes, so step 4 is not optional. One more subtlety: with AiTM phishing, the stolen session is the session the victim opened, so the ID alone does not separate attacker from victim. What separates them is the network each action comes from (AiTM and token replay).
Common pitfalls
- Truncated exports. 50,000 rows exactly means the Standard export cap, not the end of the data.
- Duplicates. Overlapping searches duplicate records; deduplicate on
Id. - Spreadsheet damage. Excel reformats dates and may split or truncate long JSON cells. Parse the CSV programmatically.
- Time zones.
CreationDateandCreationTimeare UTC; Outlook shows local time. State UTC in the report. - Delayed records. Records typically appear 60 to 90 minutes after the event; an export taken right after containment may miss the last actions.
- Missing events.
SearchQueryInitiated*is off by default;MailItemsAccesseddepends on licence and mailbox audit configuration (retention and gaps).
Doing it at scale
For a few thousand rows, PowerShell and ConvertFrom-Json work. For a tenant-wide export, parsing AuditData for every row, joining with sign-ins on IP and session, and grouping by account is exactly what M365 Forensics automates: it reads both layers of the CSV, normalises operation names (Add service principal. = Add service principal), strips ports from IPs, extracts AADSessionId/UniqueTokenId, borrows country and ASN from sign-ins of the same IP, and raises a critical "actions performed from the attacker's session" finding when UAL actions carry a suspicious sign-in's identifiers. The walkthrough shows how to read the result.
Frequently asked questions
Where is the detail of a Unified Audit Log record?
In the AuditData column of the export. It is a JSON object whose fields depend on the workload: Parameters for Exchange admin cmdlets, OperationProperties and Folders for MailItemsAccessed, ModifiedProperties for Entra ID events, SourceFileName and SiteUrl for SharePoint.
Can I link a Unified Audit Log record to an Entra ID sign-in?
Often, yes. Exchange, SharePoint and Teams records carry AppAccessContext.AADSessionId and UniqueTokenId, which match the Session ID and Unique token identifier of the Entra sign-in that issued the token. Some aggregated or background records do not carry them.
Further reading
- Microsoft Learn: Search the audit log, Linkable identifiers
- Microsoft 365 BEC investigation guide
- Glossary: MailItemsAccessed, inbox rule