Detection engineering · write-up
We measured our own detection rule. 102 of 103 alerts were false positives.
Almost every detection stack ships some version of a “user read 100+ distinct files in 5 minutes” rule. Almost nobody publishes what it costs on normal traffic. We built the measurement into the tool, ran it, and here are the numbers — including the uncomfortable one.
The rule everyone has
Bulk file access is a reasonable thing to alert on. An account suddenly touching hundreds of distinct files in minutes can be exfiltration. So a threshold rule — N distinct files within W seconds — is standard.
The problem is that a nightly backup, a search-indexing service, a weekly antivirus sweep, an analyst pulling reference material, an eDiscovery hold, and a batch ETL job all look exactly the same to that rule. Volume is not a signal. It’s a shape that legitimate work and exfiltration share.
The measurement
We generated 18.8 days and 85,509 events of synthetic-but-realistic business activity — the noise sources above, plus approved vendor maintenance on a personal laptop — and dropped exactly one labelled incident into it: an unapproved privileged session from an unmanaged device, through an exposed, unpatched gateway, followed by a burst of reads on sensitive files. Then we scored two rules against it.
| Rule | Alerts | True positives | False positives |
|---|---|---|---|
| AS-003 — bulk file access, on its own | 103 | 1 | 102 |
| AS-004 — exposed gateway + privileged login + bulk access, correlated | 1 | 1 | 0 |
The volume rule caught the incident — and buried it under 102 false positives. The correlation rule caught the same incident with zero false positives over the whole period, because it requires three independent things to line up: an asset that is internet-facing and unpatched, a privileged login that fails its own device/approval conditions, and the bulk access — same user, same session, within a short window.
“Just raise the threshold,” you say
We swept 21 threshold/window combinations. Every configuration that drove the volume rule’s false positives to zero also stopped it detecting the incident:
| Distinct files | Window (s) | Detected | False positives | Missed |
|---|---|---|---|---|
| 60 | 300 | 1 | 115 | 0 |
| 100 | 300 | 1 | 102 | 0 |
| 150 | 300 | 0 | 77 | missed |
| 300 | 120 | 0 | 0 | missed |
| 800 | 300 | 0 | 0 | missed |
There is no threshold that is both quiet and useful. The knob doesn’t separate backups from breaches, because the difference isn’t volume. The difference is the path.
Why publish the ugly number?
Because a false-positive rate you don’t publish is a false-positive rate you’re hiding. The 102 isn’t an embarrassment to bury — it’s the whole argument. It’s why ranking alerts by a severity score, or by raw volume, sends analysts chasing backups while the one correlated case that matters sits in the same queue.
This is synthetic data. It is not a real-world false-positive rate — it’s a rehearsal you re-run on your own logs before you trust a threshold. Add more legitimate noise sources and the volume rule gets worse; the correlation stays at zero. That asymmetry is the point.
Try the measurement yourself
The whole thing is a local, dependency-free Python tool. You can reproduce the numbers above in about a minute:
python3 -m aisecure baseline --days 5 --users 40 --out normal.json
python3 -m aisecure baseline --days 5 --users 40 --attack --out incident.json
python3 -m aisecure evaluate normal.json incident.json --sweep --out report.md
Or point it at a period of your own logs where nothing happened, and see what the rule would have cost you. The importer is read-only and maps only an allowlist of fields — no file contents, no credentials.
We’re looking for testers
This is an early prototype and the most useful thing right now is a second pair of eyes. No security background needed — click through the real UI on synthetic data, then tell us whether the “path over score” idea lands.
AI Secure is a local-first security-triage prototype: Python 3.11+, no dependencies, no LLM in the detection path, binds to 127.0.0.1 only. It is not a production security control. Built after the September 2026 disclosure of unauthorised access to Japan’s Government Solution Service, where a Medium-rated, already-published vulnerability was exploited before patching and a maintenance account read a large number of files — the exact case a CVSS-ordered queue handles badly. Method and caveats: docs/TUNING.md. Security self-review: docs/SECURITY_REVIEW.md.