Skip to content

High-risk geography ​

Geography as operations manage it: two tenant lists (where the business operates, where every onboarding gets a second look), a numeric geography score the integrating system attaches to the subject, and a rule set that sends review-band outcomes to a reviewer with a three-day SLA. Pack: examples/policies/high-risk-geography/.

A pattern for expressing a geography policy, not compliance guidance. The list rows are placeholders: AQ, BV and UM are uninhabited territories chosen so the example can run without the pack carrying any assessment of a real jurisdiction. Replace them with the tenant's own lists before anything depends on this.

The decision it automates ​

Whether a subject from a given country proceeds, is reviewed or is declined, where "which countries" is data that operations maintain through the lists API or the admin console, not a new version of a rule.

Data expected ​

  • A subject with data.country (ISO 3166-1 alpha-2) and data.geoRiskScore, a number from 0 to 100 the integrating system computes however it likes (a vendor's country score, an internal model).
  • Two lists of kind country: geo_supported_countries and geo_review_countries. The pack creates them with placeholder rows; importing it again adds only rows that are missing.

Steps and rules ​

StepTypeWhy
rulesevaluate_rulesThe geo_risk rule set.
routebranchrules.outcome == manual_review opens a case.
reviewcreate_casegeo_review, priority medium, 72-hour SLA: enhanced review, not urgent.
decideemit_decisionFrom the rules, or the reviewer's decision.

The rule set geo_risk sums weights into bands 0-40 approve, 40-90 manual_review, 90-100 reject:

RuleTypeSeverity, weightBehaviour
geo_country_supportedlist_lookupblock, 100mode: allow: fails when subject.country is not on geo_supported_countries
geo_country_under_reviewlist_lookupwarn, 60mode: block: fails when the country is on geo_review_countries
geo_risk_scorescore_thresholdwarn, 30contributeScore: true adds subject.geoRiskScore to the risk score whether or not the rule fails; above 70 it also fails

So a review-list country alone scores 60 (review); with a geography score of 20 it is 80 (still review); with 30 or more it reaches 90 and rejects; an unsupported country rejects outright. A missing country fails both lookups; a missing or non-numeric score fails or errors the threshold rule, and an error always routes to review.

What a reviewer sees ​

A geo_review case with the three results: which list matched (with the row's reason), the score and the threshold. Lists are live data: a reviewer who concludes a country no longer needs the second look removes the row, and the next run behaves differently without a new version of anything (every list change is audited).

How to adapt it ​

Fill the lists from your own assessment through the CSV import (POST /lists/:key/import) or the admin console (Define › Lists); give rows an expiresAt for temporary measures. Read the country from a collection flow instead of the subject (submission.country) when the applicant declares it. Read the score from a vendor instead of geoRiskScore: a call_app step keeps the app's output under its outputKey, and the score_threshold points at <outputKey>.score. Use inList("geo_review_countries", data.subject.country) inside an expression rule when the geography should only matter in combination with another signal.

Run it ​

bash
pnpm policy:import examples/policies/high-risk-geography --publish

The fixture (expect.json) creates a merchant in AQ with a geography score of 20: supported passes, the review list fails (60), the score contributes 20, rules.riskScore is 80, a geo_review case opens, the check approves it and the run completes with a manual approve.

Released under the Apache-2.0 License.