Agent Foskett Academy • KQL Academy • Module 13 • Lesson 159 • Cloud & SaaS Investigation

Lesson 159 — Following the User Across Entra, Exchange and SharePoint

Module 13 has now uncovered suspicious authentication, large downloads, unusual geography, OAuth consent, application activity, mailbox forwarding and external file sharing. The danger now is fragmentation.

If every workload is investigated separately, the analyst can miss the story. In this lesson we use KQL to follow the same user across Microsoft Entra, Exchange Online and SharePoint, normalise the evidence and build one cross-workload investigation timeline.

Attackers do not care which Microsoft portal recorded the event. Investigators should follow the identity across the evidence, not the product boundaries.
Agent Foskett KQL Academy cross workload Entra Exchange SharePoint investigation
Your case file

The same user now appears across identity, mailbox and file telemetry. The task is to stop treating these as separate incidents and reconstruct one cloud compromise story.

✓ Follow the identity through Entra
✓ Add Exchange mailbox evidence
✓ Add SharePoint and OneDrive activity
✓ Build one cross-workload timeline

Case briefing

CASE FILE User: alex.wilson@contoso.com ENTRA Suspicious sign-ins and geographic inconsistency ↓ EXCHANGE Inbox rule + external forwarding ↓ SHAREPOINT / ONEDRIVE Bulk downloads + external file sharing ↓ APPLICATION OAuth consent + non-interactive access ↓ THE QUESTION Are these separate security events, or one connected cloud compromise?

Investigation objective

Use Microsoft Entra and Microsoft 365 telemetry to follow one identity across authentication, mailbox and file activity, standardise the most useful fields and produce a single chronological investigation view that preserves the source evidence behind each event.

Investigator's rule

Correlation does not mean flattening everything into one table and forgetting where it came from. Keep the original workload and evidence type visible so every conclusion can still be traced back to its source.

Stage 1 — build the Entra identity stream

Start with the user's sign-ins. Standardise the fields you will later use across workloads: time, evidence type, user, source and a human-readable detail field.

01-build-entra-identity-stream.kql
12345678910111213
let TargetUser = "alex.wilson@contoso.com";
SigninLogs
| where TimeGenerated > ago(24h)
| where UserPrincipalName =~ TargetUser
| project TimeGenerated,
          EvidenceType="Entra sign-in",
          User=UserPrincipalName,
          Source=IPAddress,
          Workload=AppDisplayName,
          Detail=strcat(tostring(Location),
                        " | Client=", ClientAppUsed,
                        " | CA=", tostring(ConditionalAccessStatus))
| order by TimeGenerated asc

Why standardise?

Different tables use different column names and schemas. A common investigation shape makes chronology easier to read without pretending the underlying records are identical.

Keep the application context

The application involved in a sign-in can explain whether the user was reaching SharePoint, Exchange, Microsoft Graph or another service when the suspicious activity occurred.

Stage 2 — build the Exchange mailbox stream

Next, extract the mailbox activity that matters to this case: rule changes and mailbox access. Project it into the same general investigation shape.

02-build-exchange-mailbox-stream.kql
1234567891011121314
let TargetUser = "alex.wilson@contoso.com";
OfficeActivity
| where TimeGenerated > ago(24h)
| where UserId =~ TargetUser
| where OfficeWorkload == "Exchange"
| where Operation in ("New-InboxRule", "Set-InboxRule",
                      "UpdateInboxRules", "MailItemsAccessed")
| project TimeGenerated,
          EvidenceType="Exchange",
          User=UserId,
          Source=ClientIP,
          Workload=OfficeWorkload,
          Detail=strcat(Operation, " | ", tostring(Parameters))
| order by TimeGenerated asc

Workload context stays visible

The event may be part of the same incident, but Exchange semantics still matter. An inbox-rule change and a sign-in are not the same type of evidence.

Parameters remain important

Rule actions, forwarding destinations and other details can live in dynamic fields. Keep those values available even when building a simplified cross-workload view.

Stage 3 — build the SharePoint and OneDrive stream

Add the file activity: access, downloads, sync downloads and sharing events. Preserve the site and file so the cloud-data sequence remains understandable.

03-build-sharepoint-onedrive-stream.kql
123456789101112131415161718
let TargetUser = "alex.wilson@contoso.com";
OfficeActivity
| where TimeGenerated > ago(24h)
| where UserId =~ TargetUser
| where OfficeWorkload in ("SharePoint", "OneDrive")
| where Operation in ("FileAccessed", "FileDownloaded",
                      "FileSyncDownloadedFull", "SharingSet",
                      "SharingInvitationCreated",
                      "AnonymousLinkCreated", "SecureLinkCreated")
| project TimeGenerated,
          EvidenceType="SharePoint/OneDrive",
          User=UserId,
          Source=ClientIP,
          Workload=OfficeWorkload,
          Detail=strcat(Operation, " | ", Site_Url,
                        " | ", SourceFileName,
                        " | Recipient=", tostring(TargetUserOrGroupName))
| order by TimeGenerated asc

Data activity tells a different part of the story

Identity telemetry tells us who authenticated. SharePoint and OneDrive telemetry tell us what the account did with organisational data afterwards.

Recipients are new entities

When a sharing event introduces an external recipient, that address becomes a pivot of its own. Cross-workload timelines should help reveal new entities, not bury them.

Stage 4 — combine the workloads chronologically

Now union the three evidence streams into one ordered view for the incident window. The source field helps compare whether different workload events came from the same or different network origins.

04-combine-cloud-workloads.kql
12345678910111213141516171819202122232425262728293031323334353637383940414243444546
let TargetUser = "alex.wilson@contoso.com";
let StartTime = datetime(2026-08-18 13:30:00);
let EndTime = datetime(2026-08-18 16:30:00);
union
(
    SigninLogs
    | where TimeGenerated between (StartTime .. EndTime)
    | where UserPrincipalName =~ TargetUser
    | project TimeGenerated,
              EvidenceType="Entra sign-in",
              User=UserPrincipalName,
              Source=IPAddress,
              Detail=strcat(AppDisplayName, " | ",
                            tostring(Location),
                            " | CA=", tostring(ConditionalAccessStatus))
),
(
    OfficeActivity
    | where TimeGenerated between (StartTime .. EndTime)
    | where UserId =~ TargetUser
    | where OfficeWorkload == "Exchange"
    | where Operation in ("New-InboxRule", "Set-InboxRule",
                          "UpdateInboxRules", "MailItemsAccessed")
    | project TimeGenerated,
              EvidenceType="Exchange",
              User=UserId,
              Source=ClientIP,
              Detail=strcat(Operation, " | ", tostring(Parameters))
),
(
    OfficeActivity
    | where TimeGenerated between (StartTime .. EndTime)
    | where UserId =~ TargetUser
    | where OfficeWorkload in ("SharePoint", "OneDrive")
    | where Operation in ("FileAccessed", "FileDownloaded",
                          "FileSyncDownloadedFull", "SharingSet",
                          "SharingInvitationCreated",
                          "AnonymousLinkCreated", "SecureLinkCreated")
    | project TimeGenerated,
              EvidenceType="SharePoint/OneDrive",
              User=UserId,
              Source=ClientIP,
              Detail=strcat(Operation, " | ", SourceFileName,
                            " | ", Site_Url)
)
| order by TimeGenerated asc

Time proximity is useful, not magical

Events occurring seconds apart may be related, but chronology alone does not prove causation. Strengthen the relationship with source IP, user, application, recipient, correlation IDs or other available identifiers.

Expect gaps

Cloud telemetry rarely creates a perfect movie of user behaviour. Missing records should be documented as limitations rather than filled with assumptions.

Stage 5 — create the analyst's cross-workload timeline

Finally, label each record by investigation stage — identity, mailbox or files — and produce the timeline an analyst can review from top to bottom.

05-build-cross-workload-investigation-timeline.kql
12345678910111213141516171819202122232425262728293031323334353637383940414243444546
let TargetUser = "alex.wilson@contoso.com";
let StartTime = datetime(2026-08-18 13:30:00);
let EndTime = datetime(2026-08-18 16:30:00);
union
(
    SigninLogs
    | where TimeGenerated between (StartTime .. EndTime)
    | where UserPrincipalName =~ TargetUser
    | project TimeGenerated,
              Stage="Identity",
              Entity=UserPrincipalName,
              Source=IPAddress,
              Evidence=strcat(AppDisplayName, " | ",
                              tostring(Location),
                              " | CA=", tostring(ConditionalAccessStatus))
),
(
    OfficeActivity
    | where TimeGenerated between (StartTime .. EndTime)
    | where UserId =~ TargetUser
    | where OfficeWorkload == "Exchange"
    | where Operation in ("New-InboxRule", "Set-InboxRule",
                          "UpdateInboxRules", "MailItemsAccessed")
    | project TimeGenerated,
              Stage="Mailbox",
              Entity=UserId,
              Source=ClientIP,
              Evidence=strcat(Operation, " | ", tostring(Parameters))
),
(
    OfficeActivity
    | where TimeGenerated between (StartTime .. EndTime)
    | where UserId =~ TargetUser
    | where OfficeWorkload in ("SharePoint", "OneDrive")
    | where Operation in ("FileAccessed", "FileDownloaded",
                          "FileSyncDownloadedFull", "SharingSet",
                          "SharingInvitationCreated",
                          "AnonymousLinkCreated", "SecureLinkCreated")
    | project TimeGenerated,
              Stage="Files",
              Entity=UserId,
              Source=ClientIP,
              Evidence=strcat(Operation, " | ", SourceFileName,
                              " | ", Site_Url)
)
| order by TimeGenerated asc

One timeline, many sources

The purpose is not to erase product boundaries. It is to make the attack sequence visible while retaining enough source context to validate every important event.

Now the sequence becomes defensible

When suspicious authentication is followed by mailbox persistence, external forwarding, data collection and file sharing, the cloud compromise hypothesis is no longer based on one alert or one workload.

Agent Foskett's cross-workload timeline

13:21 ENTRA Unusual sign-in context ↓ 14:00–14:11 SHAREPOINT / ONEDRIVE High-velocity downloads ↓ 14:34 ENTRA OAuth consent recorded ↓ 14:47 APPLICATION Non-interactive access ↓ 15:22 EXCHANGE Inbox rule created ↓ 15:28–16:02 EXCHANGE Mail forwarded externally ↓ 16:08 SHAREPOINT Sensitive file shared externally ↓ CROSS-WORKLOAD ASSESSMENT One identity connects the evidence across multiple Microsoft 365 services
The portals were different. The user, timing and behaviour tied the investigation together.

Your evidence board

EvidenceWhat it supportsWeight
Suspicious Entra sign-in activityEstablishes unusual authentication context.Strong identity evidence
Exchange rule and forwarding activitySupports mailbox manipulation and external message exposure.Strong mailbox evidence
Bulk downloads and external file sharingSupports abnormal data collection and external exposure.Strong data evidence
Same user and close chronology across workloadsSupports a connected cloud compromise hypothesis.Strong context
Matching source IP or session contextCan strengthen relationships between workload events.Very strong when available
Chronology aloneDoes not prove every event had the same cause.Insufficient alone

Write the finding like an investigator

Example: Microsoft Entra and Microsoft 365 telemetry associated with alex.wilson@contoso.com was correlated across identity, Exchange Online and SharePoint/OneDrive workloads. The combined timeline recorded unusual authentication context, high-velocity file downloads, OAuth consent and application activity, inbox-rule creation, external message forwarding and external file sharing during the same investigation window. Each event was retained with its originating workload, timestamp and available source context. The sequence supports a connected cloud compromise hypothesis affecting identity, mailbox and organisational data. Individual conclusions remain dependent on their underlying evidence: successful authentication does not prove legitimate user activity, forwarding configuration does not alone prove delivery, and sharing does not alone prove external access. The combined timeline provides the foundation for the final Module 13 compromise assessment.

Lesson 159 key takeaways

  • Follow the identity across workloads rather than investigating each Microsoft portal in isolation.
  • Standardise common investigation fields without losing source context.
  • Use Entra sign-ins to explain authentication and application access.
  • Use Exchange audit events to explain mailbox changes and access.
  • Use SharePoint and OneDrive audit events to explain data collection and sharing.
  • Keep evidence type and workload visible in combined timelines.
  • Chronology helps reveal sequence but does not prove causation by itself.
  • Strengthen correlations with IP, session, app, recipient and other entity pivots.
  • Document telemetry gaps instead of filling them with assumptions.
  • A cross-workload timeline turns fragmented cloud events into a defensible investigation story.

Module 13 — one investigation remains

Lesson 159 has brought Entra, Exchange and SharePoint evidence into one cross-workload timeline. In the final Module 13 lesson, we use that timeline to write the complete cloud compromise assessment and separate confirmed findings from suspected outcomes.

Next: Lesson 160 — Building the Complete Cloud Compromise Timeline.

Continue your KQL investigation training

Module 13 follows users, sessions, applications and data through Microsoft 365 and cloud services.

🔎 KQL Academy — Module 13: Advanced Cloud & SaaS Investigation

Following users, sessions, applications and data through Microsoft 365 and cloud services.

Correlate Entra, Exchange and SharePoint with KQL

Lesson 159 of the Agent Foskett KQL Academy uses Microsoft Sentinel and Microsoft 365 telemetry to follow one user across Microsoft Entra, Exchange Online and SharePoint.

Build a cross-workload Microsoft 365 investigation timeline

Learn how to standardise identity, mailbox and file evidence, preserve source context and combine multiple Microsoft cloud workloads into one chronological investigation view.