IMPOSSIBLE TRAVEL
GEO-VELOCITY
NEW COUNTRY
ASN BASELINE
DetectionBlue TeamSOCOctober 12, 2026•9 min read

Detecting Impossible Travel and Anomalous Sign-ins

Two successful sign-ins an hour apart and two continents apart cannot both be the same person. The hard part is the VPN that makes it look true.

Scroll

Impossible travel compares successive successful sign-ins for an account and flags a pair whose implied speed no traveller could achieve. It is one of the oldest cloud detections and one of the noisiest, because VPNs, mobile carriers and proxies break the assumption that an IP address maps to a physical place. Done well, it combines distance, speed and baseline context rather than speed alone.

Signals at a Glance

SignalWhereATT&CK
Implied speed between consecutive sign-ins above a plausible thresholdSigninLogsT1078.004
First sign-in from a country or ASN never seen for the userSigninLogsT1078.004
Success after password spray or MFA failures from the new locationSigninLogsT1110.003
Legacy protocol or unusual client app from the new locationSigninLogsT1078.004
Entra ID Protection atypical travel and unfamiliar sign-in propertiesRisk detectionsT1078.004

Computing Geo-velocity

SigninLogs carries latitude and longitude in LocationDetails.geoCoordinates. Order each user’s successful sign-ins, measure the distance to the previous one and divide by elapsed time:

// Microsoft Sentinel (KQL) - impossible travel candidates
SigninLogs
| where TimeGenerated > ago(1d)
| where ResultType == 0
| extend lat = todouble(LocationDetails.geoCoordinates.latitude),
         lon = todouble(LocationDetails.geoCoordinates.longitude),
         country = tostring(LocationDetails.countryOrRegion)
| where isnotnull(lat) and isnotnull(lon)
| project TimeGenerated, UserPrincipalName, IPAddress, country, lat, lon, AutonomousSystemNumber, AppDisplayName
| order by UserPrincipalName asc, TimeGenerated asc
| serialize
| extend prevUser = prev(UserPrincipalName), prevTime = prev(TimeGenerated),
         prevLat = prev(lat), prevLon = prev(lon), prevCountry = prev(country), prevIP = prev(IPAddress)
| where prevUser == UserPrincipalName and country != prevCountry
| extend km = geo_distance_2points(lon, lat, prevLon, prevLat) / 1000.0,
         hours = max_of(datetime_diff('minute', TimeGenerated, prevTime) / 60.0, 0.01)
| extend kmh = km / hours
| where km > 500 and kmh > 900
| project TimeGenerated, UserPrincipalName, prevCountry, country, prevIP, IPAddress, km, kmh
// tune/validate: 900 km/h approximates airliner speed; exclude known VPN egress ranges and corporate proxy ASNs

Adding Baseline Context

Speed alone is a weak signal. Stronger detections ask whether the new location is also new for this user and whether the sign-in looks risky. This version flags a first-seen country that is paired with other anomalies:

// KQL - first-seen country for the user with supporting risk indicators
let baseline = SigninLogs
    | where TimeGenerated between (ago(30d) .. ago(1d)) and ResultType == 0
    | summarize KnownCountries = make_set(tostring(LocationDetails.countryOrRegion)) by UserPrincipalName;
SigninLogs
| where TimeGenerated > ago(1d) and ResultType == 0
| extend country = tostring(LocationDetails.countryOrRegion)
| join kind=inner baseline on UserPrincipalName
| where not(set_has_element(KnownCountries, country))
| where ClientAppUsed in ("Exchange ActiveSync", "IMAP4", "POP3", "SMTP", "Other clients")
      or RiskLevelDuringSignIn in ("medium", "high")
      or AuthenticationRequirement == "singleFactorAuthentication"
| project TimeGenerated, UserPrincipalName, country, IPAddress, ClientAppUsed, RiskLevelDuringSignIn, AppDisplayName
// tune/validate: users who travel will appear; suppress via a travel-calendar or HR feed if you have one
Vetted sources

Use Microsoft Entra ID Protection risk detection documentation, Microsoft Sentinel anomalous sign-in content, the Elastic rule for sign-ins from impossible locations and Splunk ESCU geo-velocity analytics. Baseline your own environment: the quality of this detection depends almost entirely on how well you model VPN and proxy egress.

Build Detections That Fire

Mjolnir Security helps blue teams turn threat intelligence into high-fidelity detections across endpoint, network, identity and cloud telemetry.

Detection EngineeringManaged Detection & ResponseThreat HuntingIncident ResponsePurple Teaming
  • Detection Engineering We build and tune detections mapped to ATT&CK from your own telemetry.
  • Threat Hunting as a Service Hypothesis-driven hunts for the behaviours on this page.
  • 24/7 Incident Response Containment when a detection fires. Call +1 833 403 5875.
Written by: Mjolnir Threat Research (MTAC)  |  Published: October 12, 2026  |  Last reviewed: October 12, 2026