Security settings reference (siteConfig.security)¶
siteConfig.security holds the per-site configuration for the
suspicious activity monitor — currently its only child is
security.suspiciousActivity. There is no site-wide default record for
this namespace: every value is optional, and anything a site does not
set falls back to the defaults listed below (defined in the API's
auditService).
Most fields are editable on the Settings screen (General tab → Suspicious activity monitor, superusers only); four bot-tuning keys have no UI control and can only be set by editing the site's stored config directly. See the site settings reference for how settings are saved.
How values are read¶
The monitor never reads siteConfig.security raw. Every run calls a
merge routine that lays the site's values over the defaults with
defensive rules:
- A key that is missing, null, or blank keeps its default.
- Numeric fields only accept numbers — a non-numeric value is ignored.
- Boolean fields (
enabled,botDetection) only accept booleans.
So a site can never break the monitor with a bad value; it can only tune it.
What the monitor does¶
An hourly scheduled task sweeps the audit trail and runs two independent detectors. Users flagged by either (or both) produce one alert email — with the user's full activity report attached as a PDF — to the configured recipients, and every alert is written back into the audit trail as a "Suspicious Activity Alert" event (which is also what drives the cooldown). If the master switch is off the task exits immediately.
- Volume detector — flags users whose distinct deal views or document downloads in the window are far above their own historical baseline. Distinct matters: refreshing one deal fifty times never counts as fifty. Users too new to have a baseline are never flagged.
- Bot detector — looks at all of a user's API activity for non-human patterns; several independent signals must agree before a user is flagged.
General fields¶
| Key | Default | Meaning |
|---|---|---|
enabled |
true |
Master switch for the whole monitor. Off = the hourly task does nothing. |
recipients |
(blank) | Comma-separated alert email addresses. Blank falls back to bugs.supportEmails; if neither yields a valid address the sweep logs "no recipients" and sends nothing. |
maxAlertsPerRun |
10 |
Safety cap on flagged users (and therefore emails) per sweep. |
Volume detector fields¶
| Key | Default | Meaning |
|---|---|---|
windowHours |
24 |
The rolling activity window each sweep examines. |
baselineDays |
30 |
How much history forms the user's personal baseline. The current window is excluded, so a spree cannot inflate its own baseline. |
multiplier |
4 |
Window count must be at least this many times the user's own daily average to flag. |
minDealViews |
30 |
Absolute floor: fewer distinct deals viewed in the window never flags, regardless of baseline. |
minDocDownloads |
15 |
Absolute floor: fewer distinct documents downloaded never flags. |
minHistoryDays |
14 |
The user's first audit event must be at least this old — newer accounts have no "character" and are skipped. |
minActiveDays |
5 |
The user must have been active on this many days within the baseline period. |
cooldownDays |
3 |
After a user is alerted, the same evidence cannot re-alert for this many days. Activity accrued after the alert that crosses the floors on its own still goes out, as a "continued activity" escalation. 0 disables the cooldown (useful in testing). |
A user is flagged when a metric is over its absolute floor and over
multiplier × their baseline daily average. Both floors failing means
the user is skipped before any baseline query runs.
Bot detector fields¶
| Key | Default | UI control | Meaning |
|---|---|---|---|
botDetection |
true |
yes | Switch for the bot detector (the volume detector runs regardless). |
botMinEvents |
300 |
yes | Activity floor: users with fewer total audited events in the window are never bot-analysed. Also the volume floor inside the endpoint-hammering signal. |
botPeakPerMinute |
40 |
yes | Burst signal: any single minute containing at least this many requests. |
botSignalsRequired |
2 |
yes | How many independent signals must fire together before the user is flagged. |
botCadenceCV |
0.25 |
no | Metronomic-timing signal: coefficient of variation of inter-request gaps below this (humans are irregular; scripts are not). |
botCadenceSamples |
200 |
no | Minimum number of inter-request gaps before cadence is judged at all. |
botSequentialRun |
20 |
no | Enumeration signal: a run of this many ascending IDs against one endpoint. |
botActiveHours |
20 |
no | Never-sleeps signal: activity in this many distinct hours of the day. |
The four keys without a UI control exist only in the API defaults; a
site can still override them, but only by editing its stored
siteConfig record directly.
The five signals are: burst rate, metronomic cadence, sequential-ID
enumeration, never-sleeps hours, and endpoint hammering (≥90% of at
least botMinEvents requests against a single endpoint). One signal
alone never flags anyone at the default botSignalsRequired of 2.
Tuning guidance¶
- Too many alerts: raise
multiplieror the floors (minDealViews/minDocDownloads); for bot noise, raisebotMinEventsorbotSignalsRequired. - Alerts for busy-but-legitimate screens: raise
botPeakPerMinute— dashboard pages that fire many API calls per click are the usual cause. - Suspected slow exfiltration: lower the floors and raise
windowHoursso slower activity accumulates into one window. - Alert emails include the exact reasons and numbers that fired, so the thresholds to adjust can be read straight off a false positive.
What this is not¶
- Not a blocking mechanism — the monitor only alerts; it never locks accounts, throttles requests, or blocks traffic.
- Not the permissions system — it watches usage patterns, not access rights.
- Not the healthcheck's request statistics — the healthcheck dashboard charts aggregate traffic; this monitor judges individual users.