Decaying Models

Indicators of compromise do not stay relevant forever. An IP address used in a campaign today may be reassigned next week; a phishing domain is taken down; a malware hash stops being seen. Decaying models let MISP express this decay of relevance automatically, turning a static attribute into a score that falls over time, and a decayed flag once that score drops below a chosen cut-off. Instead of manually toggling the IDS flag on ageing indicators, you define how each type of indicator should age and let MISP compute an up-to-date score whenever you query.

Decaying models are based on the MISP indicator-scoring research (arxiv.org/abs/1902.03914). They are managed under Global Actions → Decaying Models (the “Decaying Tool”) and require a role with the Decaying Model Editor permission (perm_decaying) to create or edit.

How scoring works

For a given attribute and model, MISP computes:

  • a base score — the indicator’s intrinsic importance, derived from its tags, and
  • a current score — the base score multiplied by a time-decay factor based on how long it has been since the indicator was last seen (its most recent sighting, or its last_seen / last-modified time).

An attribute is considered decayed by a model once its current score falls below that model’s threshold. Crucially, a single attribute can carry several scores at once — one for every enabled model that applies to its type — so the same indicator can be “still hot” for one detection use-case and “decayed” for another.

Scores are computed on demand at query time; there is no background job precomputing and storing them. This keeps scores always current but means score-heavy queries cost CPU (see the performance note at the end).

The base score

The base score is derived from taxonomy tags on the attribute (and its event) that carry a numerical value — for example a confidence or false-positive-risk taxonomy. A model’s base_score_config maps such taxonomies to weights; MISP combines the numerical values of the matching tags into the base score. If the attribute carries none of the configured taxonomies, the model’s default_base_score is used instead. Attribute-level tags take precedence over event-level tags of the same taxonomy.

Model parameters

A decaying model is defined by a formula plus a small set of parameters:

Parameter Meaning
Lifetime Number of days after which the score reaches 0.
Decay speed Controls the shape of the decay curve — a higher value decays more slowly.
Threshold The cut-off score; below it, the indicator is marked decayed.
Default base score Base score used when no configured taxonomy tag is present (0–100).
Base score config Mapping of numerical-value taxonomies to weights, used to compute the base score from tags.
Formula The decay formula class to use (see below).
Settings Optional per-formula settings (only some formulas use this).

Decay formulas

The decay curve is provided by a pluggable formula. MISP ships three:

  • Polynomial (default) — the classic scoring formula: the score decays from the base score to zero over the model’s lifetime, with the curve shaped by the decay speed.
  • Polynomial (Extended) — the same, but additionally honours the retention taxonomy: an indicator tagged with a retention period is forced to a score of 0 once that period has elapsed, giving a hard end-of-life on top of the smooth decay.
  • Sightings — scores the indicator from its true-positive versus false-positive sightings rather than purely from elapsed time. It returns the base score until a minimum number of sightings has accumulated, then weights the score by the true-positive ratio. This formula requires sightings to be recorded.
Note

Formulas are ordinary PHP classes under app/Model/DecayingModelsFormulas/. To add a custom decay behaviour, drop in a new class that extends the decaying-model base class and implements the score/decayed logic; it appears in the formula dropdown automatically. This is an advanced, code-level extension.

Mapping models to attribute types

A model only applies to the attribute types you associate with it. The Decaying Tool shows a matrix of attribute types against models, letting you link each model to the types it should score (for example, a phishing model applies to domain, hostname, url, ip-dst, and so on). Default models carry their applicable types built in; models you create store their type associations separately, which you edit from the tool.

Simulating and previewing a model

Before enabling a model you can simulate it. The model editor includes a simulation view that plots the score over time as an interactive chart, so you can see the effect of your lifetime, decay speed and threshold choices. You can drive the simulation two ways:

  • By REST search — score a set of real attributes matching a filter (tags, to_ids, and so on), and
  • By specific attribute — score a single attribute by ID or UUID.

The simulation also shows the base-score computation steps and lets you override model parameters on the fly, so you can tune a model against your own data before committing it.

Using decay scores in queries and the event view

Decay scores are exposed through the REST API’s attribute and event search (restSearch) with these filters:

Filter Effect
includeDecayScore Attach the decay score(s) to each returned attribute.
includeFullModel Include the full model definition alongside each score, not just its id/name.
decayingModel Restrict scoring to a specific model.
excludeDecayed Drop attributes that are decayed under all their applicable models (implies includeDecayScore).
modelOverrides Override threshold, lifetime or decay_speed for this query only.
score Shortcut to override the threshold for this query.

Each returned score contains the numeric score, the base_score, the decayed boolean, and the model it came from. This makes it straightforward to, for example, export only the indicators that are still relevant for detection (excludeDecayed), rather than everything ever recorded.

In the web interface, the event view has an Include Decay Score toggle in the attribute filter/query-builder. Enabling it adds a decay-score column to the attribute list so you can see, per indicator, how relevant it currently is.

Ownership, sharing and default models

Models fall into a few categories, reflected by the filters in the model index:

  • My models — models your organisation created.
  • Shared models — models flagged to be usable by every organisation on the instance.
  • Default models — models shipped with MISP. These can be enabled/disabled and shared, but their formula and parameters are locked (they are maintained upstream).

A model is editable by a site admin, or by a user with the Decaying Model Editor permission when the model belongs to their organisation and is not a default model.

Import, export and updating defaults

You can export a model as JSON and import one from JSON (the import is always brought in as a non-default model owned by your organisation). Default models can be updated from the upstream misp-decaying-models collection: MISP upserts models by UUID and upgrades those whose shipped version is newer than the local copy.

Tip

Decay scoring is computed at read time and can be CPU-intensive on large result sets. Enable includeDecayScore (and related options) deliberately on big exports, and lean on excludeDecayed / model thresholds to keep result sets focused. A workflow action module, Attach decay score, is also available to attach scores as part of a workflow.