The rule catalog documents how LogLens turns normalized authentication events into triage findings. It is intended for reviewers who want to inspect rule logic without reading the C++ implementation first.
The rule catalog is Sigma-informed but not a Sigma-compatible export format.
Sigma's detection, logsource, and metadata framing is useful as a mental model: define what the rule looks for, name the evidence source, and keep rule boundaries explicit. LogLens keeps a narrower local format because its rules operate on normalized Event and AuthSignal objects, not on arbitrary backend query syntax.
Logsource equivalent:
- Linux authentication evidence parsed by LogLens from
syslog_legacyinput, such asauth.logorsecure - Linux authentication evidence parsed by LogLens from
journalctl_short_fullinput, such asjournalctl --output=short-full
Detection equivalent:
- Rule logic runs after parser normalization and signal mapping.
- Unsupported parser warnings do not become rule input.
- Parsed events only become rule input when the signal mapping marks them as relevant evidence for that rule family.
Metadata equivalent:
- Rule names are stable report values.
- Windows and thresholds are configurable through
config.json. - Default values below match the built-in detector configuration.
- The checked-in
assets/sample_config.jsonis a tested default-equivalent fixture.
Within each rule grouping key, LogLens sorts matching signals by timestamp and source line number. Consecutive signals separated by an idle gap greater than the rule window start a new episode candidate. The policy is cooldown-separated maximal-window episodes:
| Policy point | LogLens v0.6 behavior |
|---|---|
| First threshold crossing | Used only to determine that an episode candidate is eligible to emit a finding. The first crossing is not necessarily the reported window. |
| Maximal window | Within each episode candidate, the detector reports the highest-signal window for the rule. |
| Non-overlapping windows | One rule and subject can emit multiple findings, but their selected episode candidates do not reuse the same matching signals. |
| Cooldown merge | Signals separated by an idle gap less than or equal to the rule window stay in the same episode candidate. A larger idle gap starts a new candidate. |
For the maximal-window step, the detector keeps the best sliding window for the rule:
brute_forceandsudo_burst: highest event countmulti_user_probing: highest distinct username count, with event count as the tie-breaker
Each episode candidate that reaches the configured threshold emits one finding.
The same rule_id and subject can therefore appear more than once in one
report when the evidence contains time-separated bursts. Review
finding_id, episode_index, window_start, window_end, and
evidence_event_ids to distinguish those episodes.
Episode splitting is a detector reporting model, not an incident boundary. It does not infer compromise, attribution, causality between rules, or cross-host correlation.
JSON findings include both the finding conclusion and the rule context used to reach it:
finding_id: deterministic report-local identifier for the selected findingrule_id: stable rule identifierepisode_index: 1-based sequence within the samerule_id,subject_kind, andsubjectgrouping_key: the normalized field used to group evidencethreshold: configured threshold for the ruleobserved_count: observed value compared against the thresholdwindow_startandwindow_end: selected evidence windowevidence_event_ids: deterministic local event IDs in the selected window, formatted asline:<number>verdict_boundary: stable token that names the non-verdict boundary for the finding
For multi_user_probing, observed_count is the distinct username count, while event_count remains the number of attempt-evidence events in the selected window.
Current verdict_boundary values are:
| Rule | verdict_boundary |
|---|---|
brute_force |
triage_signal_not_compromise_or_attribution |
multi_user_probing |
triage_signal_not_intent_or_attribution |
sudo_burst |
triage_signal_not_maliciousness_or_authorization |
The taxonomy names benign or ambiguous explanations a reviewer should consider before interpreting a finding. It is not an allow-list, suppression policy, or automatic disposition. The detailed evidence-review matrices are in false-positive-taxonomy.md.
Each rule uses the same review buckets:
- NAT
- bastion
- internal scanner
- lab replay
- scheduled admin task
- shared account
brute_force
Default terminal SSH failure evidence:
ssh_failed_passwordssh_invalid_userssh_failed_publickeyssh_failed_keyboard_interactivessh_max_auth_tries
pam_auth_failure is not terminal SSH failure evidence by default. It can be configured differently through auth_signal_mappings, but the built-in default keeps it lower-confidence.
source_ip
Signals without a source IP are not grouped for this rule.
10 minutes by default.
The detector uses the episode semantics above within each source-IP group.
5 terminal SSH failure signals by default.
subject_kind: source_ip
subject: the source IP that met the threshold
This rule identifies concentrated failed SSH authentication evidence from one source IP. It does not decide whether the source is malicious, shared infrastructure, a vulnerability scanner, an internal test, a NAT gateway, or replayed lab traffic.
The finding is a triage signal. It is not a compromise verdict, attribution claim, or recommendation to block an address.
| Bucket | Review interpretation |
|---|---|
| NAT | Multiple legitimate clients behind one egress address can collapse into one source_ip. |
| bastion | An approved jump host can concentrate many operators or jobs under one source address. |
| internal scanner | Authorized credential auditing or exposure scanning can intentionally generate repeated failures. |
| lab replay | Sanitized sample data, training fixtures, or repeated demos can preserve concentrated failure patterns. |
| scheduled admin task | A recurring job with stale credentials can fail repeatedly inside the rule window. |
| shared account | Several operators or services can retry one shared credential from the grouped source. |
See the brute-force review matrix for corroborating evidence and residual uncertainty.
Unsupported lines are parser warnings, not AuthSignal records. They may appear in failure_categories and top_unknown_patterns, but they do not carry the counts_as_terminal_auth_failure flag required by this rule.
This prevents unsupported preauth noise, malformed lines, and unmodeled auth-family messages from silently increasing brute-force counts.
multi_user_probing
Default attempt evidence:
ssh_failed_passwordssh_invalid_userssh_failed_publickeyssh_failed_keyboard_interactivessh_max_auth_triespam_auth_failure
The rule uses signal mapping, not raw event names directly. By default, pam_auth_failure counts as attempt evidence but not terminal SSH failure evidence.
source_ip
Signals without a source IP are not grouped for this rule. Distinct username counting only uses signals that carry a non-empty username.
15 minutes by default.
The detector uses the episode semantics above within each source-IP group.
3 distinct usernames by default.
The reported event count is the number of attempt-evidence signals in the selected window. The rule fires when the distinct username count reaches the threshold.
subject_kind: source_ip
subject: the source IP that targeted multiple usernames
The finding also reports the username set observed in the selected window.
This rule identifies username spread from one source IP. Username spread can be consistent with probing, but it can also appear in administrative testing, shared bastion traffic, noisy monitoring, or replayed sample data.
The rule does not infer intent. It only states that one source IP produced attempt evidence against multiple usernames inside the configured window.
| Bucket | Review interpretation |
|---|---|
| NAT | Different users behind one egress address can look like one source probing multiple accounts. |
| bastion | A shared administrative entry point can originate expected attempts for several accounts. |
| internal scanner | Authorized username-enumeration tests or account-audit tooling can touch many usernames by design. |
| lab replay | Replayed lab logs can preserve synthetic username spread without representing live probing. |
| scheduled admin task | Account validation, migration, or monitoring jobs can try multiple service or user accounts in one window. |
| shared account | Shared-account workflows can include fallback attempts across several shared or service identities. |
See the multi-user probing review matrix for corroborating evidence and residual uncertainty.
Unsupported records do not provide normalized usernames, source IPs, or attempt-evidence flags. Counting them would turn parser uncertainty into detector confidence.
Keeping them in parser warnings preserves evidence visibility without allowing unknown log patterns to inflate username-probing findings.
sudo_burst
Default sudo burst evidence:
sudo_command
Other sudo-adjacent or session events are not counted by default, including:
sudo_auth_failuresudo_policy_deniedsession_opened
username
Signals without a username are not grouped for this rule.
5 minutes by default.
The detector uses the episode semantics above within each username group.
3 sudo command signals by default.
subject_kind: username
subject: the user who met the sudo burst threshold
This rule identifies concentrated sudo command activity by one user. It does not decide whether the activity is malicious, authorized maintenance, incident response, package management, service repair, or a scripted administrative task.
The finding is strongest when reviewed with session context, change windows, host ownership, and the command text preserved in the report.
| Bucket | Review interpretation |
|---|---|
| NAT | Usually not a primary explanation because this rule groups by username, but it may matter when reviewed alongside source-IP findings. |
| bastion | Approved jump-host workflows can precede a compact sequence of privileged maintenance commands. |
| internal scanner | Endpoint assessment, compliance checks, or privileged inventory tooling can run several sudo commands quickly. |
| lab replay | Demo or training logs can replay a compact privileged-command sequence. |
| scheduled admin task | Maintenance windows, package updates, service repair, or scripted operations can produce bursty sudo activity. |
| shared account | Several administrators or services can concentrate commands under one username. |
See the sudo-burst review matrix for corroborating evidence and residual uncertainty.
Unsupported sudo-like lines are parser warnings, not sudo burst signals. They do not carry counts_as_sudo_burst_evidence.
This prevents malformed or unmodeled privilege-related records from becoming silent evidence for privileged activity bursts.
| Rule | Default grouping key | Default window | Default threshold | Output subject |
|---|---|---|---|---|
brute_force |
source_ip |
10 minutes | 5 terminal SSH failures | source_ip |
multi_user_probing |
source_ip |
15 minutes | 3 distinct usernames | source_ip |
sudo_burst |
username |
5 minutes | 3 sudo commands | username |
LogLens findings are deterministic rule outputs over normalized evidence. They are not incident verdicts. Parser coverage, warning buckets, and unsupported patterns remain visible so reviewers can see what the detector did not count.