Skip to content
LEGIT AIDOCS
Open the console

Detection rules

What a rule is made of, how its conditions are read, and how a tenant switches rules off, edits them, adds its own and quiets the noisy ones.

The platform ships 62 production rules, across authentication and endpoint activity, lateral movement, ransomware, reconnaissance, command and control, defence evasion, credential theft, cloud and insider activity. Every one of them names its MITRE ATT&CK techniques and the false positives it is known for; 56 of them come with test events that prove they fire, and events that prove they stay quiet.

Each tenant gets its own copy of the catalogue in Rules. GET /api/rules/mitre-coverage shows which ATT&CK techniques the rules cover, tactic by tactic.

{
"rule_key": "core.auth.brute_force",
"name": "Multiple Failed Authentication Attempts",
"severity": "medium",
"confidence_score": 80,
"condition": {
"event_type_any": ["auth_failure"],
"tags_any": ["auth", "login_failure", "bruteforce", "password_spray"]
},
"mitre_attack": ["T1110"],
"false_positive_notes": [
"Misconfigured service accounts cycling expired passwords — check if source is a known service host"
],
"recommended_actions": [
"Check number of failures in the last 10 minutes for the same user and source IP"
]
}

rule_key reads as <domain>.<platform>.<behaviour>. It also decides which team an alert is routed to (see Teams).

Every key in a condition must hold for the rule to fire. Inside one key, any listed value is enough.

Key Holds when
event_type_any The event’s type is one of the values
source_type_any The event came from one of these sources
tags_any The event has at least one of these tags
field_contains {"field": "process.command_line", "value": "-enc"} — the field contains the text, ignoring case
field_contains_any A list of such checks; at least one holds. Each may give value or values.
field_contains_all A list of such checks; all of them hold
field_not_contains_any, field_not_equals_any, field_not_startswith_any The field matches none of the values — used to leave out a known-good path
threshold {"field": "...", "gte": 100} — the field’s number is at least gte
iocs_present The event carries any indicator of compromise
ioc_any, entity_any The event names one of these indicators or entities
local_ioc_reputation_any One of the event’s indicators has this reputation in your threat intelligence
any_of A list of whole conditions; at least one of them holds

Fields are looked up in the event’s normalised form first, then in the raw event. Tags such as port_scan or beaconing are added when the event arrives — see How detection works.

Action Who How
Switch a rule off or on ANALYST The toggle in Rules, or PATCH /api/rules/{rule_key}/toggle
Edit a rule ADMIN PUT /api/rules/{rule_key} with the fields to change
Add a rule ADMIN POST /api/rules with rule_key, name, severity and condition
Delete a rule ADMIN DELETE /api/rules/{rule_key}

Changes apply to your tenant only and are written to the audit log. Once you edit what a rule detects, later catalogue updates stop overwriting it — it is yours. Switching a rule off or on is not an edit, and the rule keeps receiving updates.

Each confirmation and dismissal counts against the rules behind the alert. GET /api/findings/rule-metrics/{rule_key} gives a rule’s hits, false positives and false-positive rate, and GET /api/findings/noisy-rules lists the rules with at least 5 triaged alerts of which 30% or more were dismissed (both adjustable with min_hits and fp_rate_threshold).

To stop a known-benign pattern without switching a rule off, suppress it from a dismissed alert: POST /api/findings/{id}/suppress-similar with a scope — FINGERPRINT (this exact alert), RULE_KEY (this rule), ENTITY_KEY (this host or user) — and duration_minutes (-1 for permanent). Suppressed events are still stored and each one is written to the audit log, but they raise no alert.

The file scanner’s YARA rules are managed alongside: GET /api/rules/yara, POST /api/rules/yara/upload, DELETE /api/rules/yara/{filename} and POST /api/rules/yara/reload.