Dashboard

Policy

Policy is what turns a risk score into a decision your application can act on. It's kept as a separate step from scoring deliberately: the signals and weights that produce a score are Sentriq's domain expertise, but what you want to happen at a given risk level is your own business decision — and it can change at any time without touching how risk is computed.

Two-step decision

Every environment has exactly one active policy, evaluated in two steps for each event:

  1. The score is mapped through a threshold mapallow_max, monitor_max, challenge_max — to a baseline decision. Anything above challenge_max is block. Every environment has a threshold map, with sensible defaults, even with zero custom rules configured.
  2. Your rules for that event type are then checked, highest priority first. The first rule whose conditions match overrides the baseline decision. If none match, the baseline decision from step 1 stands.

Example rule

A rule is one group of conditions — all (every condition must match) or any (at least one must match) — that produces a decision when it matches:

{
  "name": "Challenge risky login",
  "event_type": "login",
  "conditions": { "all": [
    { "field": "risk.score", "operator": "gte", "value": 60 },
    { "field": "device.trusted", "operator": "eq", "value": false }
  ]},
  "action": { "decision": "challenge" },
  "priority": 100
}

event_type can be left unset so a rule applies to every event type — useful for something like "never automatically block login events, challenge instead." Rules are one level deep by design: no nested groups, no arbitrary expression language, no code execution. Every condition is a plain field/operator/value triple checked against a fixed whitelist.

Condition fields

FieldMeaning
risk.scoreThe event's numeric risk score (0–100).
risk.levelThe banded risk level.
event.typeThe event type (e.g. login).
signal.present / signal.absentWhether a specific signal code fired on this assessment.
automation.scoreThe event's automation confidence score.
device.newWhether this is a new device.
device.trustedWhether this device has been explicitly trusted.

Condition operators

OperatorMeaning
eqEquals.
neqNot equal to.
gtGreater than.
gteGreater than or equal to.
ltLess than.
lteLess than or equal to.
containsValue contains the given substring/item.
inValue is one of a given set.

A rule with a malformed or unrecognized field, operator, or value never throws or blocks scoring — the condition simply never matches. Rules are validated strictly when you create or edit them, so this is a safety net, not something you should rely on in practice.

Explainability

Every risk assessment records exactly which policy version decided it, and which rule (if any) matched:

Risk score: 72        Default decision: challenge
Applied policy: v4     Matched rule: "Challenge risky login"
Final decision: challenge

A null matched rule is a real, valid outcome — it means the plain threshold map decided the event, not that something went wrong.

Versioning

Your policy's version increments on every threshold change or rule create/update/delete. Each risk assessment permanently snapshots the exact policy version that decided it, so a past decision never appears to have been made under today's rules — even after you've since changed your thresholds or rules. Recomputing a past event against your current policy only ever happens explicitly, through the simulator below, never automatically.

Simulator

Before changing thresholds or adding a rule, you can preview what decision a hypothetical event would produce, without creating any real security event, risk assessment, or outcome:

POST /v1/environments/{env}/policy/simulate
Authorization: Bearer <dashboard session>
Content-Type: application/json

{ "event_type": "login", "risk_score": 85, "signals": ["NEW_DEVICE"] }

# => { "data": { "decision": "challenge", "matched_rule": { "id": "polr_...", "name": "..." }, "policy_version": 4 } }
Policy is account-level configuration
Managing thresholds, rules, and the simulator all require an authenticated dashboard session — never a secret or public API key. This is configuration you set once and reuse, not runtime data your integration reads or writes per event.

What this is not

  • Signal weights are not customer-tunable — only the decision-mapping layer (thresholds and rules) is.
  • Rule conditions are a fixed field/operator whitelist, not an arbitrary query language — this is deliberate, to avoid arbitrary code execution.
  • There's no rule-vs-rule conflict warning beyond unique priority enforcement — two overlapping rules simply have the higher-priority one win, silently.