OpenAI ChatGPT Enterprise Impossible Travel Login

Last updated 11 days ago on 2026-10-06
Created 11 days ago on 2026-10-06

About

Detects successful ChatGPT Enterprise logins for the same user email from source IPs whose geo-locations are separated by at least 1,000 km, with implied travel faster than 800 km/h, within a 24-hour window. That pattern can indicate account sharing, VPN or proxy egress mismatches, or an adversary authenticating from a geography far from the legitimate user's baseline.
Tags
Domain: GenAIPlatform: OpenAIData Source: OpenAI ChatGPT EnterpriseService: OpenAI ChatGPT EnterpriseUse Case: Threat DetectionRule Type: ES|QLDomain: IdentityUse Case: Identity and Access AuditTactic: Initial AccessMitre Atlas: AML.T0012Threat: Impossible TravelLanguage: esql
Severity
high
Risk Score
73
MITRE ATT&CK™

Initial Access (TA0001)(external, opens in a new tab or window)

False Positive Examples
Users on VPN or proxy egress that geo-resolves through a region distant from the user physical location.Mobile clients on cellular networks that peer through regional hubs may geo-resolve differently than the user location.
License
Elastic License v2(external, opens in a new tab or window)

Definition

Integration Pack
Prebuilt Security Detection Rules
Related Integrations

openai_chatgpt_enterprise(external, opens in a new tab or window)

Query
text code block:
from logs-openai_chatgpt_enterprise.auth_log-* | where data_stream.dataset == "openai_chatgpt_enterprise.auth_log" and event.action in ("login_success", "native_login_success") and user.email is not null and source.ip is not null and source.geo.location is not null and source.geo.country_iso_code is not null | eval Esql.source_geo_lat = st_y(source.geo.location), Esql.source_geo_lon = st_x(source.geo.location) | where Esql.source_geo_lat is not null and Esql.source_geo_lon is not null | stats Esql.first_lat = first(Esql.source_geo_lat, @timestamp), Esql.first_lon = first(Esql.source_geo_lon, @timestamp), Esql.last_lat = last(Esql.source_geo_lat, @timestamp), Esql.last_lon = last(Esql.source_geo_lon, @timestamp), Esql.event_count = count(*), Esql.country_count = count_distinct(source.geo.country_iso_code), Esql.event_action_values = values(event.action), Esql.source_ip_values = values(source.ip), Esql.source_geo_country_iso_code_values = values(source.geo.country_iso_code), Esql.source_geo_region_name_values = values(source.geo.region_name), Esql.source_geo_city_name_values = values(source.geo.city_name), Esql.user_agent_original_values = values(user_agent.original), Esql.timestamp_first_seen = min(@timestamp), Esql.timestamp_last_seen = max(@timestamp) by user.email | where Esql.event_count >= 2 and Esql.country_count >= 2 | eval Esql.p1 = to_geopoint(concat("POINT(", to_string(Esql.first_lon), " ", to_string(Esql.first_lat), ")")), Esql.p2 = to_geopoint(concat("POINT(", to_string(Esql.last_lon), " ", to_string(Esql.last_lat), ")")) | eval Esql.distance_km = round(st_distance(Esql.p1, Esql.p2) / 1000.0, 0), Esql.window_minutes = date_diff("minute", Esql.timestamp_first_seen, Esql.timestamp_last_seen), Esql.travel_kmh = case(Esql.window_minutes > 0, round(Esql.distance_km * 60.0 / Esql.window_minutes, 0), null) | where Esql.distance_km >= 1000 and Esql.travel_kmh >= 800 | keep user.email, Esql.*

Install detection rules in Elastic Security

Detect OpenAI ChatGPT Enterprise Impossible Travel Login in the Elastic Security detection engine by installing this rule into your Elastic Stack.

To setup this rule, check out the installation guide for Prebuilt Security Detection Rules(external, opens in a new tab or window).