Anthropic User Activity From High Number of Countries


Description

Detects Anthropic activity for the same user email from at least three countries and two unique user agents within a four-hour interval. This highly unusual activity may indicate leaked session cookies being abused by a remote adversary using a VPN.

Query · esql

FROM logs-anthropic.audit-* 
| where user.email IS NOT NULL and source.ip IS NOT NULL and  `user.email` != "unknown@invalid.internal"
| IP_LOCATION geo = source.ip with { "properties": ["country_name", "city_name", "location"] }
| stats Esql.country_count = COUNT_DISTINCT(geo.country_name), 
        Esql.source_ip_count = COUNT_DISTINCT(source.ip), 
        Esql.user_agent_count = COUNT_DISTINCT(`user_agent`.original),
        Esql.event_count = count(*),
        Esql.event_action_values = values(event.action), 
        Esql.source_ip_values = values(source.ip), 
        Esql.source_geo_country_name_values = values(geo.country_name), 
        Esql.source_geo_city_name_values = values(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.country_count >= 3 AND Esql.user_agent_count >= 2 AND 
  (MV_CONTAINS(Esql.event_action_values, "claude_chat_created") or MV_CONTAINS(Esql.event_action_values, "claude_chat_deleted") or MV_CONTAINS(Esql.event_action_values, "claude_user_settings_updated") or MV_CONTAINS(Esql.event_action_values, "claude_file_deleted") or MV_CONTAINS(Esql.event_action_values, "claude_chat_updated")) 
| Keep user.email, Esql.*

Investigation fields

Pivot points the source recommends for triage.

  • user.email
  • Esql.country_count
  • Esql.event_count
  • Esql.event_action_values
  • Esql.source_ip_values
  • Esql.source_geo_country_name_values
  • Esql.source_geo_city_name_values
  • Esql.user_agent_original_values
  • Esql.timestamp_first_seen
  • Esql.timestamp_last_seen

Known false positives

  • Users on VPN or proxy egress that geo-resolves through a region distant from the user's physical location. Mobile clients on cellular networks that peer through regional hubs may geo-resolve differently than the user's location.
  • Cloud egress, split-tunnel, or dual-homed clients that present different public IPs for concurrent Anthropic sessions (for example browser and API tooling) can look like impossible travel when both resolve far apart.

Analyst notes

Investigating Anthropic User Activity From High Number of Countries

Successful user_actor activity for the same email spans distant countries too quickly for travel.

Escalate when countries differ, UAs diverge (browser vs curl/python), login events are absent, or admin/export actions appear on the distant IP. Close as FP for documented dual-homed VPN/cloud egress with consistent corporate UAs.

Possible investigation steps

  • Use Esql.source_geo_country_name_values to verify the user's activity history by country.
  • Use Esql.event_action_values to verify the performed actions.
  • Contact the user to verify if he is using VPN.
  • Check for nearby logins. Absence + privileged distant actions → treat as cookie replay until proven otherwise.

False positive analysis

  • Split-tunnel / dual-homed clients (browser + API tooling) and VPN geo noise are the main FPs — require ASN/UA corroboration.

Response and remediation

  • On suspected replay/compromise: force logout for the target user from all connected devices, revoke sessions, reset credentials/MFA, hunt concurrent sessions, and review compliance/export and role changes for the same user.email after the distant events.
Raw source Anthropic User Activity From High Number of Countries · Elastic TOML
Esc
Published by elastic/detection-rules ↗, licensed under Elastic License 2.0 ↗. Reproduced here unmodified.
[metadata]
creation_date = "2026/10/05"
integration = ["anthropic"]
maturity = "production"
min_stack_comments = "ES|QL IP_LOCATION requires 9.5.0+."
min_stack_version = "9.5.0"
updated_date = "2026/10/05"

[rule]
author = ["Elastic"]
description = """
Detects Anthropic activity for the same user email from at least three countries and two unique user agents within a four-hour interval.
This highly unusual activity may indicate leaked session cookies being abused by a remote adversary using a VPN.
"""
false_positives = [
    """
    Users on VPN or proxy egress that geo-resolves through a region distant from the user's physical location. Mobile
    clients on cellular networks that peer through regional hubs may geo-resolve differently than the user's location.
    """,
    """
    Cloud egress, split-tunnel, or dual-homed clients that present different public IPs for concurrent Anthropic
    sessions (for example browser and API tooling) can look like impossible travel when both resolve far apart.
    """,
]
from = "now-4h"
interval = "5m"
language = "esql"
license = "Elastic License v2"
name = "Anthropic User Activity From High Number of Countries"
note = """## Triage and analysis

### Investigating Anthropic User Activity From High Number of Countries

Successful `user_actor` activity for the same email spans distant countries too quickly for travel. 

Escalate when countries differ, UAs diverge (browser vs curl/python), login events are absent, or admin/export
actions appear on the distant IP. Close as FP for documented dual-homed VPN/cloud egress with consistent corporate
UAs.

#### Possible investigation steps

- Use `Esql.source_geo_country_name_values` to verify the user's activity history by country.
- Use `Esql.event_action_values` to verify the performed actions.
- Contact the user to verify if he is using VPN.
- Check for nearby logins. Absence + privileged distant actions → treat as cookie replay until proven otherwise.

### False positive analysis

- Split-tunnel / dual-homed clients (browser + API tooling) and VPN geo noise are the main FPs — require ASN/UA
  corroboration.

### Response and remediation

- On suspected replay/compromise: force logout for the target user from all connected devices, revoke sessions, reset
  credentials/MFA, hunt concurrent sessions, and review compliance/export and role changes for the same `user.email`
  after the distant events.
"""
references = ["https://platform.claude.com/docs/en/api/compliance/activities/list"]
risk_score = 99
rule_id = "6a9de6a3-fc25-4e94-a735-dd147ffb0067"
severity = "critical"
tags = [
    "Domain: GenAI",
    "Domain: Identity",
    "Platform: Anthropic",
    "Data Source: Anthropic Audit Logs",
    "Use Case: Identity and Access Audit",
    "Use Case: Threat Detection",
    "Resources: Investigation Guide",
    "Rule Type: ES|QL",
    "Tactic: Credential Access",
    "Tactic: Initial Access",
    "Mitre Atlas: AML.T0012",
    "Threat: Impossible Travel"
]
timestamp_override = "event.ingested"
type = "esql"

query = '''
FROM logs-anthropic.audit-* 
| where user.email IS NOT NULL and source.ip IS NOT NULL and  `user.email` != "unknown@invalid.internal"
| IP_LOCATION geo = source.ip with { "properties": ["country_name", "city_name", "location"] }
| stats Esql.country_count = COUNT_DISTINCT(geo.country_name), 
        Esql.source_ip_count = COUNT_DISTINCT(source.ip), 
        Esql.user_agent_count = COUNT_DISTINCT(`user_agent`.original),
        Esql.event_count = count(*),
        Esql.event_action_values = values(event.action), 
        Esql.source_ip_values = values(source.ip), 
        Esql.source_geo_country_name_values = values(geo.country_name), 
        Esql.source_geo_city_name_values = values(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.country_count >= 3 AND Esql.user_agent_count >= 2 AND 
  (MV_CONTAINS(Esql.event_action_values, "claude_chat_created") or MV_CONTAINS(Esql.event_action_values, "claude_chat_deleted") or MV_CONTAINS(Esql.event_action_values, "claude_user_settings_updated") or MV_CONTAINS(Esql.event_action_values, "claude_file_deleted") or MV_CONTAINS(Esql.event_action_values, "claude_chat_updated")) 
| Keep user.email, Esql.*
'''


[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1539"
name = "Steal Web Session Cookie"
reference = "https://attack.mitre.org/techniques/T1539/"


[rule.threat.tactic]
id = "TA0006"
name = "Credential Access"
reference = "https://attack.mitre.org/tactics/TA0006/"
[[rule.threat]]
framework = "MITRE ATT&CK"
[[rule.threat.technique]]
id = "T1078"
name = "Valid Accounts"
reference = "https://attack.mitre.org/techniques/T1078/"
[[rule.threat.technique.subtechnique]]
id = "T1078.004"
name = "Cloud Accounts"
reference = "https://attack.mitre.org/techniques/T1078/004/"



[rule.threat.tactic]
id = "TA0001"
name = "Initial Access"
reference = "https://attack.mitre.org/tactics/TA0001/"
[[rule.threat_mappings]]
framework = "MITRE ATLAS"
version = "2026.08"
[[rule.threat_mappings.threat]]
framework = "MITRE ATLAS"
[[rule.threat_mappings.threat.technique]]
id = "AML.T0012"
name = "Valid Accounts"
reference = "https://atlas.mitre.org/techniques/AML.T0012/"


[rule.threat_mappings.threat.tactic]
id = "AML.TA0004"
name = "Initial Access"
reference = "https://atlas.mitre.org/tactics/AML.TA0004/"


[rule.investigation_fields]
field_names = [
    "user.email",
    "Esql.country_count",
    "Esql.event_count",
    "Esql.event_action_values",
    "Esql.source_ip_values",
    "Esql.source_geo_country_name_values",
    "Esql.source_geo_city_name_values",
    "Esql.user_agent_original_values",
    "Esql.timestamp_first_seen",
    "Esql.timestamp_last_seen",
]

[rule.alert_suppression]
group_by = ["user.email"]
missing_fields_strategy = "suppress"

[rule.alert_suppression.duration]
unit = "h"
value = 4

Detection rules belong to the projects that publish them and remain under their own licenses. This site indexes and links to them; it claims no rights in them.