Lesson 160 — Building the Complete Cloud Compromise Timeline
This is the final investigation in Module 13. We have followed one account through suspicious authentication, unusual data access, OAuth consent, application activity, mailbox manipulation, external forwarding and SharePoint sharing. Now the evidence has to become a conclusion.
In this lesson we use KQL to reconstruct the complete cloud compromise chronologically, preserve the source behind every event, distinguish what the telemetry proves from what it merely suggests, and write a final assessment that another analyst can defend.

Your final case file
The evidence now spans Microsoft Entra, Exchange Online, SharePoint and OneDrive. Your job is to reconstruct what happened without claiming more than the telemetry can prove.
Case briefing
Investigation objective
Reconstruct the incident across Microsoft cloud workloads, preserve timestamps and entities, identify confirmed security-relevant actions, document evidentiary limitations and produce a final cloud compromise assessment that can be reviewed by responders, management and other investigators.
Investigator's rule
The final report is not where uncertainty disappears. It is where uncertainty becomes explicit. Separate observed facts, supported interpretations and unanswered questions.
Stage 1 — reconstruct the identity evidence
Begin again with the authentication evidence. The final timeline should be reproducible, so rebuild the relevant Entra stream for the defined incident window rather than relying only on notes taken earlier.
let TargetUser = "alex.wilson@contoso.com";
let StartTime = datetime(2026-08-18 13:00:00);
let EndTime = datetime(2026-08-18 17:00:00);
SigninLogs
| where TimeGenerated between (StartTime .. EndTime)
| where UserPrincipalName =~ TargetUser
| project TimeGenerated,
Stage="Identity",
EvidenceType="Entra sign-in",
Entity=UserPrincipalName,
Source=IPAddress,
Activity=AppDisplayName,
Detail=strcat(tostring(Location),
" | Client=", ClientAppUsed,
" | CA=", tostring(ConditionalAccessStatus))Observed is not attributed
A successful sign-in is an observed authentication event. It does not by itself establish whether the legitimate user or an attacker controlled the resulting session.
Keep source context
IP address, location, application, client type and Conditional Access result help explain the event and support later correlations.
Stage 2 — reconstruct the mailbox evidence
Add the Exchange evidence that materially affects the incident: mailbox access and inbox-rule manipulation.
let TargetUser = "alex.wilson@contoso.com";
let StartTime = datetime(2026-08-18 13:00:00);
let EndTime = datetime(2026-08-18 17:00:00);
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",
EvidenceType="Exchange audit",
Entity=UserId,
Source=ClientIP,
Activity=Operation,
Detail=tostring(Parameters)Configuration is a fact
If the audit record shows a rule was created, that configuration change can be reported as observed. The attacker's purpose remains an interpretation until supported by the rule actions and surrounding evidence.
Preserve the parameters
The final timeline can be concise, but the underlying parameters should remain available so forwarding destinations and rule actions can be independently verified.
Stage 3 — reconstruct the cloud-data evidence
Add SharePoint and OneDrive access, downloads and sharing activity. These events establish what happened to organisational data after authentication.
let TargetUser = "alex.wilson@contoso.com";
let StartTime = datetime(2026-08-18 13:00:00);
let EndTime = datetime(2026-08-18 17:00:00);
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="Data",
EvidenceType=OfficeWorkload,
Entity=UserId,
Source=ClientIP,
Activity=Operation,
Detail=strcat(SourceFileName, " | ", Site_Url,
" | Recipient=",
tostring(TargetUserOrGroupName))Exposure and access are different
Sharing a file externally establishes that access was granted. It does not prove the external party opened or downloaded the resource unless additional telemetry confirms that outcome.
Volume needs context
High download volume can support a collection hypothesis, especially when it deviates from baseline, but volume alone does not establish malicious intent.
Stage 4 — assemble the complete timeline
Bring the identity and Microsoft 365 evidence together and order it chronologically. This becomes the central working view for the final incident assessment.
let TargetUser = "alex.wilson@contoso.com";
let StartTime = datetime(2026-08-18 13:00:00);
let EndTime = datetime(2026-08-18 17:00:00);
let IdentityEvidence =
SigninLogs
| where TimeGenerated between (StartTime .. EndTime)
| where UserPrincipalName =~ TargetUser
| project TimeGenerated, Stage="Identity",
EvidenceType="Entra sign-in",
Entity=UserPrincipalName, Source=IPAddress,
Activity=AppDisplayName,
Detail=strcat(tostring(Location),
" | CA=", tostring(ConditionalAccessStatus));
let CloudEvidence =
OfficeActivity
| where TimeGenerated between (StartTime .. EndTime)
| where UserId =~ TargetUser
| where OfficeWorkload in ("Exchange", "SharePoint", "OneDrive")
| project TimeGenerated,
Stage=case(OfficeWorkload == "Exchange", "Mailbox", "Data"),
EvidenceType=OfficeWorkload,
Entity=UserId, Source=ClientIP,
Activity=Operation,
Detail=strcat(SourceFileName, " | ",
tostring(TargetUserOrGroupName),
" | ", tostring(Parameters));
union IdentityEvidence, CloudEvidence
| order by TimeGenerated ascSequence reveals relationships
Authentication followed by collection, persistence and external exposure is more informative than any event viewed alone. Still, each relationship should be supported by entities and context rather than chronology alone.
Do not hide conflicting evidence
If a source IP, device or application does not fit the working theory, preserve it. Contradictory evidence may expose an incorrect assumption or reveal multiple sessions.
Stage 5 — separate observations from conclusions
Create a concise evidence view containing only events actually present in telemetry. Interpretation belongs in the analyst's assessment, not disguised as a query result.
let TargetUser = "alex.wilson@contoso.com";
let StartTime = datetime(2026-08-18 13:00:00);
let EndTime = datetime(2026-08-18 17:00:00);
union
(
SigninLogs
| where TimeGenerated between (StartTime .. EndTime)
| where UserPrincipalName =~ TargetUser
| project TimeGenerated,
Finding="Authentication activity",
Evidence=tostring(AppDisplayName),
Source=IPAddress,
Confidence="Observed"
),
(
OfficeActivity
| where TimeGenerated between (StartTime .. EndTime)
| where UserId =~ TargetUser
| where OfficeWorkload in ("Exchange", "SharePoint", "OneDrive")
| where Operation in ("New-InboxRule", "Set-InboxRule",
"UpdateInboxRules", "MailItemsAccessed",
"FileAccessed", "FileDownloaded",
"FileSyncDownloadedFull", "SharingSet",
"SharingInvitationCreated",
"AnonymousLinkCreated", "SecureLinkCreated")
| project TimeGenerated,
Finding=Operation,
Evidence=strcat(OfficeWorkload, " | ",
SourceFileName, " | ",
tostring(TargetUserOrGroupName)),
Source=ClientIP,
Confidence="Observed"
)
| order by TimeGenerated ascFacts first
“An inbox rule was created at 15:22” is an observation. “The attacker created persistence” is an interpretation. The second may be well supported, but it should remain distinguishable from the first.
Confidence should be explainable
If you describe a conclusion as high confidence, be prepared to identify the evidence that makes it high confidence and the evidence that would weaken it.
Agent Foskett's complete cloud compromise timeline
Confirmed, supported and still unknown
| Assessment | Example | How to report it |
|---|---|---|
| Confirmed observation | An inbox rule was created and external sharing was recorded. | State directly and cite the telemetry. |
| Strongly supported interpretation | The events form part of one compromised cloud session. | Explain the correlations that support the conclusion. |
| Possible interpretation | OAuth consent was intended as persistence. | Describe as possible unless permissions and later use support it. |
| Unknown | Whether every externally shared file was actually downloaded. | State the gap and identify the telemetry needed to resolve it. |
| Not established | The physical identity of the person operating the session. | Do not attribute without supporting evidence. |
Write the final finding like an investigator
Example: Microsoft Entra and Microsoft 365 telemetry associated with alex.wilson@contoso.com identified a sequence of security-relevant events during the defined incident window. Observed activity included unusual authentication context, high-volume SharePoint and OneDrive downloads, OAuth consent, subsequent application activity, Exchange inbox-rule creation, external message delivery and external sharing of a sensitive SharePoint resource. The events were correlated by identity, chronology and available source context across independent telemetry sources. Taken together, the evidence strongly supports a connected cloud account-compromise hypothesis affecting identity, mailbox and organisational data. The available telemetry does not by itself establish the physical identity of the actor or prove that every externally shared resource was accessed by its recipient. Incident response should contain the identity, revoke active sessions and tokens, remove unauthorised application consent and mailbox persistence, validate external recipients, review affected data and scope the identified source entities across the wider environment.
Lesson 160 key takeaways
- Rebuild the final timeline from source telemetry so the investigation remains reproducible.
- Combine identity, mailbox and cloud-data evidence without losing workload context.
- Separate observed events from analyst interpretation.
- Use chronology together with identity, source and entity correlation.
- Preserve evidence that contradicts the working hypothesis.
- Distinguish configuration, exposure and confirmed access as separate findings.
- State unanswered questions explicitly.
- Do not attribute a human actor from account activity alone.
- Make confidence levels traceable to supporting evidence.
- A defensible investigation is one another analyst can reproduce and challenge.
Module 13 complete — Advanced Cloud & SaaS Investigation
You began Module 13 with unusual data activity and followed the evidence through geography, OAuth consent, application access, Exchange persistence, external forwarding and SharePoint exposure. The final lesson has brought those fragments together into one defensible cloud compromise timeline.
Continue your KQL investigation training
🔎 KQL Academy — Module 13: Advanced Cloud & SaaS Investigation
Build a complete Microsoft cloud compromise timeline with KQL
Lesson 160 of the Agent Foskett KQL Academy uses Microsoft Sentinel, Microsoft Entra and Microsoft 365 telemetry to reconstruct a complete cloud compromise across identity, Exchange Online, SharePoint and OneDrive.
Turn Microsoft 365 telemetry into a defensible incident assessment
Learn how to correlate cloud evidence, distinguish observations from hypotheses, document uncertainty and produce a final investigation timeline that supports incident response and defensible reporting.
