Agent Foskett Academy • KQL Academy • Module 11 • Lesson 131

Lesson 131 — The Successful Sign-In That Wasn't Normal

A successful sign-in can be one of the most misleading events in an identity investigation.

The password may be correct. Multi-factor authentication may have been satisfied. Conditional Access may show success. Nothing in the single event necessarily says "attack."

Lesson 131 begins the next phase of the KQL Academy by asking a different question: does this successful sign-in make sense for this user? We will use KQL to compare the event with normal behaviour, examine surrounding evidence and build a defensible identity timeline.

Success tells you authentication completed. It does not tell you the person behind it was legitimate.
Agent Foskett KQL Academy identity threat hunting lesson
What you will investigate

One successful Microsoft Entra sign-in that does not fit the user's normal pattern.

✓ Establish the user's baseline
✓ Compare location and IP context
✓ Inspect device and authentication evidence
✓ Build a timeline around the event

The investigation begins

09:17 UTC ↓ User signs in successfully ↓ ResultType = 0 ↓ Conditional Access = success ↓ No obvious authentication failure ↓ But the IP address, location and device context are unusual ↓ QUESTION Was this a legitimate successful sign-in... or a successful attacker sign-in?

Learning objectives

Use KQL to investigate a successful Microsoft Entra sign-in, establish a baseline for the account, identify anomalous context and create an evidence-based timeline instead of treating authentication success as proof of legitimacy.

The table we will use

For this lesson we use SigninLogs in Log Analytics or Microsoft Sentinel. It contains Microsoft Entra sign-in information including the user, application, source IP, location, device details, authentication requirement, Conditional Access status and risk context.

Start with the event

The first query should stay simple. We are orienting ourselves before deciding what the event means.

start-with-the-event.kql
12345678910111213
let TargetUser = "alex.wilson@contoso.com";
SigninLogs
| where TimeGenerated > ago(24h)
| where UserPrincipalName =~ TargetUser
| project TimeGenerated,
          UserPrincipalName,
          AppDisplayName,
          IPAddress,
          Location,
          ResultType,
          ConditionalAccessStatus,
          AuthenticationRequirement
| order by TimeGenerated desc

What ResultType tells us

In SigninLogs, a ResultType value of 0 indicates a successful sign-in. That answers one question: did the sign-in operation succeed?

What ResultType does not tell us

It does not prove the user intended the sign-in, that the originating device was trusted, that the network was expected, or that the session was benign. Authentication success is an outcome, not an attribution verdict.

Step 1 — isolate successful sign-ins

isolate-successful-signins.kql
1234567891011121314
let TargetUser = "alex.wilson@contoso.com";
SigninLogs
| where TimeGenerated > ago(7d)
| where UserPrincipalName =~ TargetUser
| where ResultType == "0"
| project TimeGenerated,
          AppDisplayName,
          IPAddress,
          Location,
          ClientAppUsed,
          ConditionalAccessStatus,
          AuthenticationRequirement,
          DeviceDetail
| order by TimeGenerated desc

Do not start with "malicious"

A new country, ISP or device may be suspicious, but it may also be travel, mobile tethering, a new laptop, a VPN exit node or another legitimate change. KQL should help us test the event rather than confirm our first impression.

Think comparatively

An isolated event is difficult to interpret. The same event becomes more useful when compared with the user's normal applications, locations, IP addresses, client types and devices over time.

Step 2 — build a location baseline

build-location-baseline.kql
12345678910
let TargetUser = "alex.wilson@contoso.com";
SigninLogs
| where TimeGenerated between (ago(30d) .. ago(1d))
| where UserPrincipalName =~ TargetUser
| where ResultType == "0"
| summarize SignInCount=count(),
            FirstSeen=min(TimeGenerated),
            LastSeen=max(TimeGenerated)
          by Location
| order by SignInCount desc

Why exclude the current day?

When building a behavioural baseline, separating the period under investigation from the historical comparison period helps prevent the suspicious activity itself from contaminating the baseline.

What would interest us?

A location that has never appeared for the account, an application the user rarely accesses, an unexpected client type, a new device context or a source IP seen only during the suspicious window all deserve investigation.

Step 3 — compare source IP addresses

compare-source-ip-addresses.kql
123456789101112
let TargetUser = "alex.wilson@contoso.com";
SigninLogs
| where TimeGenerated > ago(30d)
| where UserPrincipalName =~ TargetUser
| where ResultType == "0"
| summarize SignInCount=count(),
            Locations=make_set(Location, 10),
            Applications=make_set(AppDisplayName, 20),
            FirstSeen=min(TimeGenerated),
            LastSeen=max(TimeGenerated)
          by IPAddress
| order by LastSeen desc

Do not over-trust IP addresses

Public IP addresses can represent office gateways, home broadband, mobile networks, VPNs, secure access services and cloud infrastructure. An unfamiliar IP is a clue, rarely a conclusion by itself.

Look for combinations

The stronger signal is often not "new IP" but a combination: new IP + new location + unfamiliar device + unusual application + unusual time. KQL lets us bring those clues together.

Step 4 — inspect the device detail

inspect-device-detail.kql
1234567891011121314151617
let TargetUser = "alex.wilson@contoso.com";
SigninLogs
| where TimeGenerated > ago(7d)
| where UserPrincipalName =~ TargetUser
| where ResultType == "0"
| extend DeviceId = tostring(DeviceDetail.deviceId),
         OperatingSystem = tostring(DeviceDetail.operatingSystem),
         Browser = tostring(DeviceDetail.browser)
| project TimeGenerated,
          AppDisplayName,
          IPAddress,
          Location,
          DeviceId,
          OperatingSystem,
          Browser,
          ConditionalAccessStatus
| order by TimeGenerated desc

Device evidence changes the question

If the account normally signs in from a known Windows device and suddenly authenticates from a different browser, operating system or unidentified device, that difference becomes a useful pivot.

Missing device data matters too

A blank device identifier does not automatically mean malicious activity. Some client and sign-in scenarios provide less device context than others. Treat absence of telemetry as an evidence limitation, not as proof.

Step 5 — examine Conditional Access and authentication

inspect-authentication-context.kql
1234567891011121314151617
let TargetUser = "alex.wilson@contoso.com";
SigninLogs
| where TimeGenerated > ago(24h)
| where UserPrincipalName =~ TargetUser
| where ResultType == "0"
| project TimeGenerated,
          AppDisplayName,
          IPAddress,
          Location,
          AuthenticationRequirement,
          AuthenticationMethodsUsed,
          AuthenticationDetails,
          ConditionalAccessStatus,
          ConditionalAccessPolicies,
          RiskLevelDuringSignIn,
          RiskState
| order by TimeGenerated desc

MFA success is not the end

MFA can be satisfied in legitimate and compromised sessions. The analyst still needs to understand which requirement applied, what method was used, whether the activity fits the user's behaviour and what happened immediately afterwards.

Risk is supporting evidence

Risk fields can add context where the required Microsoft Entra licensing and telemetry are available. A low or absent risk value should not be treated as proof that a sign-in was legitimate.

Step 6 — build the timeline around the event

build-signin-timeline.kql
123456789101112131415
let TargetUser = "alex.wilson@contoso.com";
let SuspiciousTime = datetime(2026-08-13 09:17:00);
SigninLogs
| where TimeGenerated between (SuspiciousTime - 2h .. SuspiciousTime + 4h)
| where UserPrincipalName =~ TargetUser
| project TimeGenerated,
          ResultType,
          AppDisplayName,
          ResourceDisplayName,
          IPAddress,
          Location,
          ClientAppUsed,
          ConditionalAccessStatus,
          AuthenticationRequirement
| order by TimeGenerated asc

Why surrounding events matter

One successful sign-in may be preceded by failures from the same IP, followed by access to unusual applications, or surrounded by other changes in behaviour. Sequence often tells a stronger story than one row.

Look after authentication

The next question is what the account did after the successful sign-in. That becomes the bridge into cloud, email, endpoint and cross-domain telemetry later in this module.

The evidence table

ObservationWhat it provesWhat it does not prove
ResultType = 0The sign-in succeeded.That the legitimate user performed it.
New IP addressThe source IP is not in the observed baseline.That the IP is malicious.
New locationThe resolved location differs from historical sign-ins.That the user physically travelled there.
Conditional Access successThe applicable Conditional Access evaluation succeeded.That the session is trustworthy in every respect.
MFA requirement satisfiedThe authentication requirement was met.That an attacker could not have abused valid authentication or session material.
Unfamiliar device contextThe recorded device information differs from prior activity.That the device is attacker-controlled.

Agent Foskett's investigation

09:17 UTC ↓ Successful Microsoft Entra sign-in ↓ No authentication error ↓ Conditional Access succeeds ↓ At first glance, nothing appears broken ↓ KQL checks 30 days of successful activity ↓ The source IP has never appeared before ↓ The location has never appeared before ↓ The application is familiar ↓ Device context is different from the user's normal pattern ↓ The analyst expands the timeline ↓ More activity appears around the same source ↓ The evidence now justifies deeper investigation ↓ Not because the sign-in failed ↓ Because the successful sign-in did not fit the identity
The clue was not that authentication failed. The clue was that authentication succeeded somewhere the user did not normally exist.

Investigation questions to ask next

  • Has this IP address authenticated any other accounts?
  • Is the location genuinely unusual for the user?
  • Was the device previously associated with this identity?
  • Which application and resource were accessed?
  • Which authentication requirement and methods were used?
  • Which Conditional Access policies applied?
  • Were there failures or unusual sign-ins immediately before the success?
  • Did the account perform unusual cloud, email or endpoint activity afterwards?
  • Does the evidence support compromise, legitimate travel, VPN use or another benign explanation?

Lesson 131 key takeaways

  • A successful sign-in proves authentication success, not user legitimacy.
  • Start with a simple query before building a theory.
  • Compare suspicious activity with the user's own historical baseline.
  • Use location, IP, application, client and device context together.
  • Conditional Access and MFA outcomes are evidence, not automatic conclusions.
  • Build a timeline around the suspicious event.
  • Separate unusual behaviour from confirmed malicious behaviour.
  • Preserve missing telemetry and uncertainty.
  • Strong identity investigations rely on multiple supporting clues.
  • KQL is most useful when it helps you ask progressively better questions.

Continue your KQL investigation training

Lesson 131 begins Module 11: Identity Threat Hunting. The next lesson will examine repeated authentication attempts and MFA fatigue patterns.

Related Agent Foskett Investigations

Take the KQL techniques from this lesson into real investigation scenarios. These case files show why identity evidence must be tested in context rather than judged from a single sign-in result.

🔎 KQL Academy — Module 11: Identity Threat Hunting

Phase Two starts here: use the KQL skills from Lessons 1–130 to investigate identity behaviour as evidence.
⬅ Previous lesson
Lesson 130 — Complete Hunting WorkbookThe original KQL Academy capstone.
✅ Current lesson
Lesson 131 — The Successful Sign-In That Wasn't NormalInvestigate a successful sign-in by comparing it with the user's normal behaviour.
Next lesson
Lesson 132 — Hunting MFA Fatigue and Repeated Authentication AttemptsUse KQL to identify repeated authentication pressure and suspicious sign-in sequences.

KQL successful sign-in investigation

Lesson 131 of the Agent Foskett KQL Academy teaches analysts how to investigate a successful Microsoft Entra sign-in using SigninLogs, KQL baselines, source IP addresses, location, applications, device details, Conditional Access and authentication context.

Microsoft Entra identity threat hunting with KQL

Identity threat hunting requires more than checking whether a sign-in succeeded. Analysts compare current authentication activity with historical user behaviour, build timelines and correlate contextual evidence before deciding whether an event is suspicious or compromised.