4.1 Two Tables, Not One

60 minutes · Module 4 · Free

Two Tables, Not One

The single most important thing to understand about Entra ID sign-in investigation is that the data lives in two tables, not one. Missing either table means missing half the picture.

THE TWO SIGN-IN TABLESSigninLogsInteractive sign-insUser enters credentials in a browserUser completes MFA promptUser consents to app permissionsUser logs into Outlook, Teams, portalThe user is physically present and participatingAADNonInteractiveUserSignInLogsNon-interactive sign-insToken refresh (app renews session)Background app sync (Outlook, Teams)SSO redirects between appsStolen token replay by attackerNo user participation — the token acts alone

Figure 4.1: The two sign-in tables. Attackers using stolen tokens appear only in the non-interactive table — missing it means missing the compromise.

Why two tables matter for investigation

In a legitimate session, both tables record activity: the user signs in interactively (SigninLogs), then the applications refresh tokens in the background (AADNonInteractiveUserSignInLogs). Both entries come from the same IP, the same device, the same location. This is normal.

In a token theft attack, the pattern splits. The legitimate user’s interactive sign-in appears from their normal location. The attacker’s token replay appears as a non-interactive sign-in from a completely different IP and location — because the attacker is using the stolen token directly, not signing in through a login page.

The most common investigation mistake

Analysts who only query SigninLogs miss the majority of token replay activity. If you are investigating a suspected account compromise and only checking one table, you are blind to the most dangerous post-compromise activity. Always query both.

The volume difference

Non-interactive sign-ins vastly outnumber interactive sign-ins — often 10:1 or more. Every time Outlook refreshes a token, every time Teams checks for new messages, every time SharePoint pre-loads a document library — each of these generates a non-interactive sign-in event. This is why the tables are separate: combining them would make the interactive sign-ins (which are usually more important for investigation) nearly impossible to find in the noise.

A practical pattern: query both tables together

When investigating a specific user, always check both tables:

1
2
3
4
5
6
7
8
9
let targetUser = "j.morrison@northgateeng.com";
let lookback = 7d;
union SigninLogs, AADNonInteractiveUserSignInLogs
| where TimeGenerated > ago(lookback)
| where UserPrincipalName =~ targetUser
| extend SignInType = iff(Type == "SigninLogs", "Interactive", "Non-Interactive")
| project TimeGenerated, SignInType, IPAddress, AppDisplayName, ResultType,
    tostring(LocationDetails.countryOrRegion), tostring(DeviceDetail.browser)
| sort by TimeGenerated desc

The union operator combines both tables. The iff expression adds a column showing which table each row came from. This gives you the complete sign-in picture for a user in a single query.

Try it yourself

Run the union query above in the Log Analytics demo environment. Pick any user from a SigninLogs | take 10 query. Compare the interactive vs non-interactive counts. How many non-interactive sign-ins does the user have per interactive sign-in?
In most environments, you will see 5-15 non-interactive sign-ins for every interactive one. The non-interactive entries are token refreshes, background syncs, and SSO redirects. All from the same IP as the interactive sign-in. If you see non-interactive sign-ins from a different IP — that is the signal for token replay.

Check your understanding

1. A user signs into Outlook via their browser at 09:00. Over the next hour, Outlook refreshes the token 6 times in the background. How do these events appear in the logs?

7 entries in SigninLogs
7 entries in AADNonInteractiveUserSignInLogs
1 entry in SigninLogs (the browser login) + 6 entries in AADNonInteractiveUserSignInLogs (the token refreshes)

2. An attacker steals a session token via AiTM phishing and replays it from their own machine. Which table records the attacker's access?

SigninLogs — because the attacker is accessing the account
AADNonInteractiveUserSignInLogs — the attacker uses the token directly without going through a login page
Both tables equally

3. Why are non-interactive sign-in logs stored in a separate table from interactive logs?

Non-interactive events outnumber interactive events 10:1 or more — combining them would bury the interactive sign-ins that are usually more important for investigation
They have different column schemas
Microsoft has not merged them yet