New Value Detector
The New Value Detector raises alerts when previously unseen values appear in configured fields (for example new user names, IP addresses, or process names). It is useful to detect novelty, configuration drift, or the appearance of new actors in the environment.
In/out
Input and output schemas in the pipeline
| Schema | Description | |
|---|---|---|
| Input | ParserSchema | Structured log |
| Output | DetectorSchema | Alert / finding |
At a glance
| Learns from training data | Auto-configuration | Needs events |
Federation |
|---|---|---|---|
| ✅ | ✅ picks the variables to monitor | ✅ unless auto_config: true |
✅ |
Description
This detector keeps the set of values observed during training for each monitored field and emits an alert whenever a value that is not in the set appears. Alerts don't add the value to the set, so the same unseen value raises an alert every time it appears.
Example
import yaml
from detectmatelibrary import schemas
from detectmatelibrary.detectors.new_value_detector import NewValueDetector
with open("docs/examples/detectors/new_value.yaml") as f:
config = yaml.safe_load(f)
detector = NewValueDetector(name="NewUserDetector", config=config)
def login(user: str, ip: str) -> schemas.ParserSchema:
"""What a parser emits for 'Accepted password for <user> from <ip> port
22'."""
return schemas.ParserSchema({"eventID": 0, "variables": [user, ip, "22"]})
# the first 3 logs train the detector (data_use_training: 3)
for log in [login("alice", "10.0.0.1"), login("bob", "10.0.0.2"), login("alice", "10.0.0.3")]:
detector.process(log)
print(detector.process(login("bob", "10.0.0.9"))) # None: bob is a known user
alert = detector.process(login("mallory", "10.0.0.1"))
print(dict(alert["alertDetails"])) # {'EventID 0 - user': "Unknown value: 'mallory'"}
Configuration file
The configuration used by the example above. It sets only what this use case needs; every other parameter keeps its default (see Configuration arguments).
detectors:
NewUserDetector:
method_type: new_value_detector
auto_config: false # we pick the variables ourselves (see `events`)
params:
data_use_training: 3 # learn from the first 3 logs, then detect
events:
0: # EventID: "Accepted password for <*> from <*> port <*>"
login: # instance name, free to choose
variables:
- pos: 0 # first <*> in the template
name: user
The same file works unchanged in both places a detector runs:
- Library: load it with
yaml.safe_loadand pass the dict asconfig=, as in the example. The key underdetectors:must match the detector'sname. - DetectMateService: use it as the service's detector configuration.
Configuration arguments
All parameters this detector accepts, grouped by the YAML block they go in. Scope tells whether a parameter is specific to this detector or shared with other detectors (see the Detectors overview). Where this detector changes a shared default, the shared value is shown in brackets.
Top level
| Field | Type | Default | Scope | Description |
|---|---|---|---|---|
method_type |
string | new_value_detector | shared | Indicates what type of method it is. |
auto_config |
boolean | True | shared | Runs the configuration step before the training process. Has no effect unless data_use_configure is set. |
events |
object | {} | shared | Events configuration dict keyed by event_id. |
global |
object | {} | shared | Instances monitoring event-independent header variables (e.g. hostname, level), keyed by instance name. Written as global in YAML. |
persist |
object, null | None | shared | Periodic state saving (path, interval_seconds, events_until_save, auto_load, storage_options). None disables it. See Saving state (persist) on the Detectors page. |
params
| Field | Type | Default | Scope | Description |
|---|---|---|---|---|
start_id |
integer | 10 | shared | Number used to start the unique ID generator. |
data_use_training |
integer, null | None | shared | Number of logs used for training. None skips training. |
data_use_configure |
integer, null | None | shared | Number of logs used for the configuration step. None skips it. |
use_config_data_as_training |
boolean | True | shared | Combine the configured data in the training process if True. |
train_buffer_max_records |
integer | 100000 | shared | Configure records kept in memory for training (use_config_data_as_training) before the buffer spills to Parquet files on disk, in parts of this many records. |
train_buffer_dir |
string, null | None | shared | Local directory for the spilled training buffer. None uses the system temp directory (TMPDIR). Each spill goes to a private detectmate-train-* directory, removed after training reads it; a killed process leaves it behind. |
parser |
string | PARSER | shared | Name of the parser used. |
allow_fed |
boolean | False | shared | Builds the stores needed to take part in federation. |
auto_config_params (read only while auto_config is true)
| Field | Type | Default | Scope | Description |
|---|---|---|---|---|
classification.index |
boolean | True | shared | Segment-mean test over equal-count segments. |
classification.time |
boolean | False | shared | Segment-mean test over equal-duration segments. Needs timestamp_variable. |
classification.segment_thresholds |
array | [1.1, 0.3, 0.1, 0.01] | shared | Upper bound on the mean change rate, one per segment; the list length is the segment count. Used by index and time. |
classification.slope_index |
boolean | False | shared | Change-centroid test on the index axis. |
classification.slope_time |
boolean | False | shared | Change-centroid test on the time axis. Needs timestamp_variable. |
classification.slope_threshold |
number | -0.05 | shared | A variable is STABLE when its change centroid (-0.5 to +0.5) is at or below this. Used by slope_index and slope_time. |
classification.decision |
string | consensus | shared | How the enabled methods' verdicts combine: consensus needs all of them, majority needs more than half. |
timestamp_variable |
string, null | None | shared | Header variable (from the parser's log_format) holding each event's time. Required by the time and slope_time classification methods. |
timestamp_format |
string, null | None | shared | Format of timestamp_variable. None detects it automatically. |
use_stable_vars |
boolean | True | shared | Monitor the variables the configure phase classifies as STABLE. |
use_static_vars |
boolean | True | shared | Monitor the variables the configure phase classifies as STATIC (a single value). |