Weird issues with Entra ID Signin Logs

Short depth-of-field photo of a laptop screen showing some signin logs in Sentinel

I recently experienced an issue where a Sentinel alert for successful Entra ID signin from an unexpected location, fired multiple times after an attacker had already been evicted, and all sessions had been revoked. Initially I assumed something had gone wrong with the revocation process, as all of the subsequent signin events showed an existing token granted access without need for MFA/Password - "MFA requirement satisfied by claim in the token"

After some more detailed analysis of the logs, I determined that all of the signin logs after the initial compromise were duplicates of the initial event, with only a few changes in the risk fields. I did find a blog post which highlighted a similar issue, but implied that this would like occur within an hour of the initial signin event, whereas in my situation this had happened 3-4 days later.

The cause of these duplicated alert is other events which causes Microsoft to re-evaluate the risk scoring of the initial login. For instance when the affected user successfully completed a self-service password reset this triggered a new log in the SigninEvents table.

The key to identifying this situation is comparing the TimeGenerated field and the CreatedDateTime field. (Good reference to what each field means from Microsoft )In the majority of logins the delta between these is less than 4 minutes, but a small proportion of them are much longer, I found some examples of events being created 168 hours after the login! I also found that in different organizations between 5% and 90% of logins caused more than 1 signin log to be created.

Table of longest times between logins and new signin events being generated that I've observed in the last 30 days
Table showing average number of logs recorded in the SigninLogs table per login across a number of different tenants.

I have added a small check into my detection rules that look for a single login event which checks that the CreatedDateTime value is within the lookback period of the rule. If you are running queries that need to return the correct count of login events then you might want to use something like arg_min(TimeGenerated,*) by CorrelationId to capture the first event only for each login.

I hope this post causes other people to spend less time pulling their hair out over multiple signin events that actually represent only a single signin.