4.2 Key Fields in the Sign-In Log

60 minutes · Module 4 · Free

Key Fields in the Sign-In Log

The sign-in log tables contain over 50 columns each. You do not need all of them. In practice, eight fields answer 80% of your investigation questions. Learn these eight cold, and you can triage any sign-in event in under a minute.

THE EIGHT FIELDS YOU CHECK ON EVERY SIGN-IN1. ResultTypeSuccess (0) or failure? Which error code?2. IPAddress + LocationWhere from? Known or unfamiliar?3. TimeGeneratedWhen? Off-hours? Right after a phishing email?4. AppDisplayNameWhich application? Exchange = high risk target5. ClientAppUsedBrowser, mobile app, or legacy protocol (IMAP)?6. ConditionalAccessStatusCA allowed, blocked, or not applied?

Figure 4.2: The six fields shown above, plus MfaDetail and DeviceDetail, cover 80% of your investigation needs.

ResultType — Success or failure

ResultType is a numeric code. Zero means success. Everything else is a failure with a specific reason.

Memorise these five error codes

You will see them constantly. Knowing what they mean without looking them up saves minutes per investigation.

Error CodeMeaningInvestigation significance
0SuccessThe sign-in worked. If from an unfamiliar location, this is a compromise indicator.
50126Invalid credentialsWrong password. Many from one IP = brute force. Many IPs targeting many users = spray.
50074MFA required, not completedUser or attacker did not finish MFA. Often benign (user cancelled).
50053Account lockedLockout threshold hit. Follows a burst of 50126 failures.
53003Blocked by conditional accessA CA policy stopped the sign-in. Check which policy in the ConditionalAccessPolicies field.

The full error code reference is at learn.microsoft.com/en-us/entra/identity-platform/reference-error-codes, but these five account for the vast majority of what you will encounter.

IPAddress and LocationDetails

The IP address and its geolocation tell you where the sign-in came from. Compare against the user’s normal patterns.

1
2
3
4
5
6
7
8
SigninLogs
| where TimeGenerated > ago(30d)
| where UserPrincipalName =~ "j.morrison@northgateeng.com"
| where ResultType == 0
| extend Country = tostring(LocationDetails.countryOrRegion)
| extend City = tostring(LocationDetails.city)
| summarize SignInCount = count(), LastSeen = max(TimeGenerated) by IPAddress, Country, City
| sort by SignInCount desc

This builds a baseline: which IPs and locations does this user normally sign in from? Any sign-in from an IP not in this list is worth investigating.

Build IP baselines before you need them

Investigating a compromise is much faster when you already know the user's normal IPs and locations. Consider running baseline queries proactively for VIP users and high-privilege accounts, and storing the results as a watchlist in Sentinel.

ClientAppUsed — The legacy authentication signal

This field identifies the authentication protocol. Modern authentication (browser, mobile app, desktop app) supports MFA. Legacy protocols do not.

ClientAppUsed valueTypeMFA support
BrowserModernYes
Mobile Apps and Desktop clientsModernYes
Exchange ActiveSyncLegacyNo
IMAP4LegacyNo
POP3LegacyNo
SMTPLegacyNo
AutodiscoverLegacyNo
Legacy authentication is how attackers bypass MFA

After obtaining credentials through phishing, attackers often attempt IMAP or POP3 access to read email without triggering an MFA challenge. A conditional access policy blocking legacy authentication eliminates this entire attack path. If your organisation has not deployed this policy, it is the single highest-impact security improvement you can make.

ConditionalAccessStatus and ConditionalAccessPolicies

ConditionalAccessStatus gives you the overall verdict: success (allowed), failure (blocked), or notApplied (no policies evaluated). The ConditionalAccessPolicies field is a JSON array containing every policy that evaluated, with its individual result.

Parsing the policies array to find the specific blocking policy:

1
2
3
4
5
6
7
8
9
SigninLogs
| where TimeGenerated > ago(1d)
| where ConditionalAccessStatus == "failure"
| mv-expand CAPolicy = parse_json(ConditionalAccessPolicies)
| where tostring(CAPolicy.result) == "failure"
| extend PolicyName = tostring(CAPolicy.displayName)
| project TimeGenerated, UserPrincipalName, IPAddress, PolicyName
| summarize BlockCount = count() by PolicyName
| sort by BlockCount desc

This shows which conditional access policies are doing the most blocking — useful for understanding your security posture and identifying policies that may need tuning.

MfaDetail

Shows whether MFA was satisfied and which method was used (phone call, authenticator app push, FIDO2 key, OTP). Critical for AiTM investigation: if MFA was satisfied but the user says they were not involved, the token was likely captured after MFA completion on a proxy page.

DeviceDetail

Contains the device name, operating system, browser, compliance status, and whether the device is Intune-managed. An unregistered device from an unfamiliar IP is a stronger compromise indicator than an unregistered device from a known corporate network.

Check your understanding

1. ResultType 53003 means the sign-in was blocked. What specifically blocked it?

Invalid credentials
Account lockout
A conditional access policy — check the ConditionalAccessPolicies JSON array for the specific policy name

2. You see a sign-in with ClientAppUsed = "IMAP4" and ResultType = 0. Why is this concerning?

IMAP is slow
IMAP is a legacy protocol that does not support MFA — the attacker authenticated with just a username and password, bypassing any MFA requirement
IMAP is only used on mobile devices

3. How do you find out which specific conditional access policy blocked a sign-in?

Check the ConditionalAccessStatus field
Check the ResultType field
Use mv-expand on the ConditionalAccessPolicies JSON array and filter for result == failure