Behavioural risk score
The behavioural score is a per-identity signal, on the same 0–100 scale as every other risk score, that answers a different question from the rest of the risk model: not what access does this identity hold, but how unusual has this identity's recent activity been. It is exposed to the risk model as the identity.behaviouralScore selector, so that a risk factor can raise an identity's standing risk when its behaviour drifts from its own established pattern.
The score is an input to risk scoring, not a score in its own right: on its own it changes nothing. None of the built-in factors in the risk score configuration consumes it in this release — the score is collected and stored as groundwork for custom, rule-based factors that reference the selector, which do not yet have an administration UI. Until such a factor exists, the score is visible only in the stored risk data.
Where the score comes from
OpenIAM's machine-learning module already maintains a behavioural model per identity, built from that identity's own access history (times of day, locations, devices, IP addresses, user agents) and used at sign-in time for adaptive authentication. The behavioural score reuses that same model for a standing, rather than per-request, judgement: it scores the identity's most recent access records against its own model and reports the percentage of them the model considers anomalous.
That framing matters when reading a score:
- 0 means the identity's recent activity is entirely consistent with how it normally behaves.
- A higher score means a larger share of recent activity looks unlike this identity's own history — not that it is unlike other people's.
- No score at all is a distinct outcome from a score of 0. An identity whose history is too short to model — fewer than 1,000 recorded access events — is left unscored, and the
identity.behaviouralScoreselector is simply absent for it, so no factor fires on a value that was never measured. Scoring judges the identity's 100 most recent records against its model; both limits are fixed in this release. On a fresh or low-traffic deployment it is therefore expected that most identities carry no score at first — this is not a pipeline fault.
Because the model is per-identity, the score is not comparable across people in the way a shared threshold implies; a rule such as "score above 30" means "more than 30% of this identity's recent activity is unusual for them".
When the score is refreshed
An identity is re-scored after it authenticates, because a sign-in is when new behavioural evidence arrives. The scoring itself is deliberately not performed during the sign-in: authentication only queues the identity, and a background sweep in the ESB fetches the score from the machine-learning module and stores it. Sign-in latency is therefore unaffected, whether the machine-learning module is fast, slow, or not deployed at all.
When a stored score changes, the ESB notifies the Risk Manager so the identity's aggregate risk is recomputed immediately rather than at the next nightly sweep — an anomaly signal that took a day to surface would be of little use.
Freshness
Behavioural signals are time-varying, so a stored score does not stay valid indefinitely. A score older than the freshness window is treated as absent rather than presented as the identity's current behaviour, and the selector goes back to being unset. An identity that stops signing in therefore stops carrying a behavioural score, which is the intended outcome: no recent activity is not evidence of normal behaviour.
Freshness is a hard cutoff on whether the raw observation still counts as evidence. It is separate from a factor's decay setting, which controls how an accepted contribution fades over time; both can be configured, and they compose.
Requirements
The behavioural score requires the machine-learning module to be deployed and consuming, along with the OpenSearch index of access statistics it reads. The module is optional: when it is not running, no scores are collected, queued identities are retained rather than discarded, and the selector stays unset. Nothing else in risk scoring or authentication is affected.
Configuration
These properties are set in openiam.esb.properties:
| Property | Default | Description |
|---|---|---|
org.openiam.risk.behavioural.threadsweep | 60000 | How often, in milliseconds, the ESB collects scores for identities that have authenticated since the previous sweep. |
org.openiam.risk.behavioural.maxPerSweep | 250 | The maximum number of identities scored in a single sweep. Identities beyond the cap are carried over to the next sweep. The carry-over queue is held in memory, so an ESB restart clears any backlog — an identity affected is simply queued again the next time it signs in. Lower this to reduce load on the machine-learning module during sign-in peaks. |
org.openiam.risk.behavioural.freshness.days | 30 | How many days a stored score remains usable. Past this age the score is treated as absent. |
Using your own analytics pipeline
If you already produce behavioural or user-analytics scores elsewhere, you can feed them to OpenIAM directly instead of relying on the built-in module. The ESB accepts a RECORD_IDENTITY_BEHAVIOURAL_SCORE message on its risk-data queue carrying:
- the user id the score belongs to;
- the score, on a 0–100 scale (values outside the range are clamped);
- optionally, the time the score was observed — this drives the freshness window, and defaults to the time of receipt;
- optionally, a source label recorded for provenance.
Each identity has one current score: a new observation replaces the previous one. Pushed scores are stored, aged and consumed exactly like scores from the built-in module, so the two paths can also coexist — distinguishable afterwards by their source label.