Risk score recomputation at scale

Risk scores are pre-computed and stored, never calculated at read time. Two mechanisms keep them fresh:

  • Event-driven recompute — the primary path. When something relevant changes (an entitlement is granted or revoked, a membership is edited, an identity signs in, a reviewer attests an item), only the affected subject and the scores that depend on it are recomputed, immediately.
  • The nightly sweep — the backstop. Once a night (02:00 by default) the Risk Manager walks the whole population: it re-derives time-decayed entitlement scores, re-scores every membership, and rolls every identity's aggregate up again. This realizes time decay, backfills subjects created since the last run, and reconciles any event missed while the Risk Manager was down.

A one-time go-live bootstrap runs the same full-population pass when the Risk Manager first starts on a fresh installation, so scores are meaningful from day one.

This page describes how those population-wide passes behave on large deployments and the properties that tune them.

How the sweep scales

The sweep is designed so that its memory use and its per-subject cost stay flat as the population grows:

  • The population is enumerated in pages. The Risk Manager asks the ESB for entitlement ids, memberships, and identity ids one page at a time (1,000 by default), processing each page before fetching the next. The full population is never held in memory or shipped in a single message, so the sweep behaves the same at 500 users and at 50,000.
  • Each page is scored in batches. Within a page, the projections needed for scoring are fetched with one call per batch rather than one per subject, stored scores are read with one bulk lookup, and results are written back with one bulk write. An entitlement's inherent score is resolved once per sweep and reused by every membership that grants it — a role held by ten thousand users no longer costs ten thousand identical reads.
  • Membership scores flow forward. The identity roll-up phase reuses the membership scores computed earlier in the same sweep instead of re-reading them from storage.

Failure behavior

A sweep whose population enumeration fails — for example the ESB is down, or a reply times out — aborts loudly. The failure is logged as an error, the sweep is not recorded as completed, and the next scheduled run retries. The same applies to the go-live bootstrap: on an enumeration failure it does not mark itself done and re-arms for the next startup. A transport failure is never mistaken for an empty population, so stored scores cannot silently go stale behind a "successful" sweep.

The recompute queue

Recompute work runs on its own message queue, separate from the queue that serves score reads. This matters under load: a burst of sign-ins or a broad entitlement change can enqueue thousands of recompute commands, and without the split those commands would sit ahead of certification score lookups and stall them into timeouts. With it, reads stay responsive no matter how deep the recompute backlog is.

Two kinds of work use this queue:

  • Subject recompute signals — the event-driven notifications fired by sign-ins, provisioning changes, and attestations. Recording an attestation replies as soon as the attestation is stamped; the follow-up recompute is queued rather than performed while the caller waits.
  • Cascade pages. When an entitlement's own risk changes, every membership that grants it — and every identity holding one — must be re-scored. Rather than walking all of them in one long-running operation, the Risk Manager splits the dependents into pages (200 identities per page by default) and queues each page as an independent unit of work. An identity's affected memberships always travel in the same page, so each identity is rolled up exactly once per cascade.

Configuration

These properties are set in the Risk Manager service's properties (under ${confpath}/conf/properties/):

PropertyDefaultDescription
org.openiam.risk.sweep.cron0 0 2 * * *Cron expression for the nightly sweep. Keep it off-peak: the sweep competes with regular traffic for the ESB.
org.openiam.risk.sweep.pageSize1000How many subjects each population enumeration call returns. Larger pages mean fewer round trips but bigger messages; the ESB caps a page at 10,000.
org.openiam.risk.sweep.chunkSize500How many subjects are scored per batch within a page. This is also the size of each bulk read and bulk write.
org.openiam.risk.cascade.pageSize200How many identities each entitlement-cascade page covers. Lower this if broad entitlement changes produce pages that take too long to process individually.

The defaults are appropriate for most deployments; none of these properties needs to be changed to enable the behavior described above.