Skip to content

Sanctions and PEP escalation ​

Two escalation paths from one screening step: a sanctions hit opens a critical case before any rule runs, while softer signals (a politically exposed person, adverse media) are scored and may open an ordinary review. Pack: examples/policies/sanctions-and-pep-escalation/.

A pattern for expressing an escalation policy, not compliance guidance: what counts as a hit, which lists are screened and what a reviewer must do with a match are the tenant's and the vendor's business. The pack screens with the deterministic mock-sanctions app, whose install on the development stack blocklists the name Evil Corp; a tenant without that install can import the pack, but its runs fail on unknown_app until the app is installed and enabled.

The decision it automates ​

Whether a subject can proceed without a person looking, must be looked at within hours, or within a day. The point of the pack is the ordering: the expensive, time-critical path is a branch straight after the screening step, not a rule in a set.

Data expected ​

  • A subject with data.name and data.country (what the screen is run on), plus the optional flags data.pep and data.adverseMedia that the integrating system sets from its own sources or from an earlier screening.
  • No collection flow: screening happens on data the platform already holds.

Steps and rules ​

StepTypeWhy
screencall_appmock-sanctions screen on subject.name and subject.country; output under sanctions (hit, matches).
hitbranchsanctions.hit == true goes to escalate; everything else to rules.
escalatecreate_casesanctions_escalation, priority critical, 4-hour SLA. No rules run: the case context carries the matches, and the reviewer decides.
rulesevaluate_rulesThe screening_pep rule set, for subjects that cleared the screen.
routebranchrules.outcome == manual_review opens the softer case.
pep_reviewcreate_casepep_review, priority high, 24-hour SLA.
decideemit_decisionThe reviewer's decision when there was a case (either one), otherwise from the rules. A run that took the escalation branch has no rule results; the decision is the reviewer's alone.

The rule set screening_pep sums weights into two bands, 0-40 approve and 40-100 manual_review: there is no automatic reject on these signals, by design.

RuleTypeSeverity, weightFails when
screening_pep_declaredcomparisonwarn, 60subject.pep == true (passWhen: false turns the match into a failure)
screening_adverse_mediacomparisonwarn, 40subject.adverseMedia == true

What a reviewer sees ​

A sanctions_escalation case at the top of the queue (critical, four hours) with the vendor's matches and scores in its context; or a pep_review case with the two rule results. A case queue in the admin console can pin either type (see Admin console: queues and filters).

How to adapt it ​

Screen with the opensanctions app of the App catalogue instead of the mock, once its apiKey secret is stored: the same screen action, plus input: { "type": "Company" } or Person. Use an app rule against the same app instead of screening_pep_declared, with input: { "type": "Person", "topics": ["role.pep"] } and resultPath: hit, as the seeded pep_hit rule does, so the PEP signal comes from the vendor instead of the subject record. Add a score_threshold on the best match score to route weak matches to the softer review instead of the critical case.

Run it ​

bash
pnpm policy:import examples/policies/sanctions-and-pep-escalation --publish

The fixture (expect.json) screens Evil Corp: the mock reports a hit, the run skips the rules and opens a sanctions_escalation case, the check rejects it and the run completes with a manual reject; sanctions.hit is true in the run context.

Released under the Apache-2.0 License.