Skip to content

Risk scoring in LogMan.io Correlator

LogMan.io Correlator assigns a numeric risk score to each detection output (complex events, signals, alerts). Analysts use it to sort queues, tune rules, and feed entity risk on assets.

Scores are floating point values, typically on a 0 to 100 scale. As a rule of thumb: 20 is low, 50 is medium, 80 is high. Values can go above 100 when several bonuses stack.

Risk score vs. severity

Severity describes the potential impact if a finding were true (low, medium, high, critical). It is a stable label for the scenario.

Risk score is a number that changes at output time: the rule base, prior score on the triggering event, lookups, and IOC matches all contribute. It answers "How strongly should we act on this detection right now?"


What happens when a detection fires

When a correlation rule triggers (complex event or signal), the Correlator computes event.risk_score in four steps unless the trigger template sets the field explicitly:

Step Source Effect
1. Base Rule define.risk_score or define.severity, and optionally existing event.risk_score on the triggering event Starting value, or escalation of an existing score (see below)
2. Rule tuning ruleid2riskscore lookup Added to the base
3. IOC / threat intel Lookups in the ioc group (and lookups listed in define.lookups that match window dimensions) Added per matching dimension value
4. Asset weight hostid2riskscore, userid2riskscore, serviceid2riskscore Added when the event carries the matching principal id

The result is written to the detection output (ECS field event.risk_score by default). That value is what you see in Discover, alerts, and on the Assets entity score (see Entity risk score on assets).

Analyst view

You do not configure the formula in the UI. You influence the outcome by:

  • risk_score or severity in the rule YAML
  • Rows in Lookups (ruleid2riskscore, ioc, …)
  • Risk score weight on an asset in Assets (feeds userid2riskscore and siblings)

Base score from the rule

Set the rule base in define:

define:
  name: "Failed login burst"
  risk_score: 40.0

If you omit risk_score, you can use categorical severity instead. It is converted to a number, for example low → 30, medium → 50, high → 70, critical → 90.

If the triggering event has no prior risk score, the base is simply that rule value.


When the triggering event already has a risk score

Parsed or upstream events sometimes already carry event.risk_score (for example a prior detection on the complex lane). A downstream rule does not replace that number. It escalates it toward 100 using the rule's own risk_score (or mapped severity):

new_base = existing + (100 - existing) × (rule_risk / 100)

The rule acts like a percentage of the remaining headroom to 100. High existing scores move less; low scores can jump more.

Escalation example

A host already has event.risk_score: 40 from an earlier detection. A second rule fires with define.risk_score: 30.

40 + (100 - 40) × (30 / 100) = 40 + 18 = 58

The second rule raised the score by 18 points, it did not add 30 on top of 40.

Strong escalation

Same starting 40, but the second rule has risk_score: 80:

40 + 60 × 0.8 = 88

A high rule base on a chained detection can push the output close to the top of the scale in one step.

If the rule has neither risk_score nor severity in define, the existing event score is kept as the base (lookups in steps 2 to 4 still apply).


Rule tuning (ruleid2riskscore)

Add per rule adjustments in the ruleid2riskscore lookup. The key is the rule id (Library path to the YAML file). The score column is added after the base.

key                                                              score
/Correlations/Windows/Failed login burst.yaml                    10.0

Tuning noisy rules

A useful rule that fires often might keep define.risk_score: 50 for honest severity, but ruleid2riskscore: -15 (or a lower positive value) so analysts are not flooded with top priority alerts until IOC or asset weight pushes the total higher.


IOC and threat intelligence

Lookups in the ioc group (and compatible lookups listed under define.lookups) are checked against window dimensions on the event (for example source.ip, user.name, dns.question.name). Each hit adds its risk.score (default 10 if the row has no score).

key                         risk.score
203.0.113.66                25.0
evil.example.com            20.0

IOC on a dimension

A failed VPN login rule has base 45 after escalation. The source IP matches an IOC row with 25. The output becomes 70 before asset weight. Analysts see a medium rule become high priority because the IP is known bad.


Per asset risk score weight

In Assets → asset detail, you can set Risk score weight (0 to 100) for a host, user, or service. That value lives in hostid2riskscore, userid2riskscore, or serviceid2riskscore. When a detection output includes that principal id, the weight is added to the final score.

VIP service account

Rule base 35, no IOC. User svc-backup has risk score weight 30 in Assets. Final event.risk_score: 65. The same rule on a generic user stays at 35.

This weight is independent from Average risk score in Assets (entity score over time). Weight affects future detection outputs; entity score reflects past detections. See Entity risk score in LogMan.io Assets.


Full example (all layers)

A window rule define.risk_score: 50 fires on user jsmith.

  1. Triggering complex event already has event.risk_score: 20 (upstream detection).
  2. Base after escalation: 20 + 80 × 0.5 = 60
  3. ruleid2riskscore entry for this rule: +565
  4. source.ip matches IOC: +1580
  5. userid2riskscore for jsmith: +1090

Output complex event:

event.risk_score: 90.0

Order matters in your head, not in config

You only configure the rule and lookups. The Correlator always applies: base (with escalation) → rule tuning → IOC → asset weight. You cannot reorder steps in YAML.


Explicit score in the trigger

If the trigger block sets event.risk_score (or your schema risk field) in the output template, that value is used as written. Automatic calculation is skipped for that trigger.

Use this for exceptional cases. Most rules should rely on define and lookups so tuning stays centralized.


Summary

Layer Where configured Effect
Rule base define.risk_score or define.severity Starting score, or escalates existing event.risk_score
Rule tuning ruleid2riskscore lookup Add
IOC / intel ioc group (+ define.lookups) Add per matching dimension
Asset weight Assets UI → risk score weight Add when principal id is on the event

For rule authoring, see Correlator and How to write a window correlation rule.


Entity risk score on assets

The event.risk_score on a complex lane event is the score of that detection. LogMan.io Assets maintains a separate entity risk score on each asset (host, user, service): a number that fades over time when no new detections arrive for that principal.

Layer Where Role
Correlator / complex event event.risk_score One detection (rule + lookups)
Asset inventory Risk score in Assets UI Current risk of the principal after decay

Sort the asset list by risk score to prioritize investigation. The asset detail sidebar shows Average risk score (entity state now); the risk score chart shows detection peaks over time.

For examples and optional Risk score weight, see Entity risk score in LogMan.io Assets.