add new structure

This commit is contained in:
larssand
2026-09-23 17:06:05 +02:00
parent 7cbec64b0e
commit 8c155ec9cf
8 changed files with 343 additions and 24 deletions

View File

@@ -159,6 +159,20 @@ Interpret findings by maturity:
- `event_rate_burst`, `auth_failure_burst`, `dns_query_burst`, and
`deny_action_burst` compare the current window to historical buckets.
Field deviations that share the same detector and field are clustered before
scoring, not after. If the same `(detector, field)` signature appears across
five or more entities in one poll (`false_positive`/`expected`-suppressed
deviations don't count toward that total), every deviation in the cluster is
tagged with a `cluster_size` and its score is capped at 25, and the Evidence
column shows `[part of a N-entity pattern]` ahead of the reason. This is a
deliberate inversion of the usual "more occurrences = more severe" rule: a
pattern hitting many unrelated entities identically almost always means a
detector or profile problem (a field that shouldn't have been picked as a
relationship target, for example) rather than N separate critical security
events, so it is scored at or below an isolated occurrence instead of above
it. A small, isolated deviation keeps its full score. See
[`ARCHITECTURE.md`](ARCHITECTURE.md) for the incident that motivated this.
The review buttons are part of the detection loop:
- `Expected`: known behavior that should stay visible but not keep creating
@@ -217,6 +231,16 @@ dashboard status payload carries the underlying per-field shape and confidence
values, so a `field_confidence`/`field_shapes` map is available for any field
even when it was not selected into the applied profile.
A name match never overrides value shape, even for names on the trusted
priority lists such as `context`. If the observed values for a name-matched
field confidently look like free text (a raw log line or URL, not a
low-cardinality category) it is excluded from entity, categorical, and
relationship-target selection regardless of its name, both for a fresh
recommendation and as a second, independent check when a field reaches
relationship-candidate selection through cross-stream field sharing. A field
with too few samples to classify is never excluded on that basis alone; the
veto only fires on a confident, contradicting shape.
Windows-like streams are recognized from stream names such as `Windows`,
`Winlog`, `Security Event Log`, `Sysmon`, and `Powershell`, or from Windows event
fields. The MCP search asks for common Winlogbeat/ECS names such as
@@ -337,6 +361,15 @@ After the baseline has learned those relationships, a new `username -> srcip` or
`username -> hostname` pair is reported as `new_relationship` with sample events.
The dashboard profile editor exposes this as `Behavior relationships (JSON)`.
An existing stored profile's `categorical_fields` and `relationship_fields` are
re-checked against current observed shapes on every poll, not just when the
profile was first created — a field can look fine at profile-creation time and
drift into free text later, or the classifier's read of it can simply have been
wrong initially. A mismatch never rewrites the stored profile automatically;
it only shows up under `Recommended Stream Profiles` as a warning naming the
field, the stream, and the confidence behind the mismatch, with a button that
opens that stream's profile editor so a person decides whether to remove it.
SignalScope keeps a common alias map for fields such as source IP, destination
IP, ports, action, severity, service/protocol, DNS query, URL, message, and event
type. This lets Related Activity and correlations work with firewall/proxy/DNS