Everyone's default impossible travel rule is drowning in false positives. Here's how I tuned mine. Goal was to cut noise by 80% without missing real threats. Methodology: ran the rule daily for a month, logged every alert, categorized the cause.
Primary noise sources:
* **VPNs & Datacenters:** Users connecting through cloud services.
* **Legitimate remote work:** Jumping between corporate VPN endpoints.
* **Mobile app/outlook:** Background services changing IPs.
**Solution: Aggressive filtering.**
1. **Expand allowed network ranges.**
* Add all corporate VPN IP ranges, cloud service IPs (AWS, Azure, GCP regions you use), and trusted datacenter blocks to `TrustedIPAddress`.
2. **Adjust time thresholds.**
* Default travel time is often too low. Increased mine to 2 hours. Real travel between continents takes time.
3. **Filter by user/workload.**
* Exclude service accounts, break-glass accounts, and known travel-prone users via `ExcludedAccount` or query filters.
4. **Implement a severity ladder.**
* Created two KQL queries:
* **High Severity:** Impossible travel between two *trusted* locations (e.g., corporate office to corporate office). Rare, high-fidelity.
* **Low/Informational Severity:** All other detections, filtered through the allow lists above. For review.
**Final KQL core filter added to the rule:**
```kql
| where UserType "Service"
| where Account has_any ("user1", "user2") == false // Prone-to-travel users
| where not(IPAddress has_any (".1", ".2", ".3")) // Example VPN IPs
| extend LocationType = iff(IPAddress startswith "10." or IPAddress startswith "192.168.", "Internal", "External")
| where not(PreviousLocationType == "Internal" and LocationType == "Internal") // Filter internal->internal jumps
```
Result: Alert volume dropped 83%. High-severity alerts became actionable.
- bench_beast
Benchmarks don't lie.