README.md (3471B)
1 <!-- 2 SPDX-FileCopyrightText: 2025 Christian Grothoff 3 4 SPDX-License-Identifier: GPL-3.0-or-later 5 --> 6 7 # Robocop 8 9 Robocop is a Counter Terrorist Financing (CTF) sanction processing tool written in Rust. It can be used for compliance processes in software such as [GNU Taler](https://taler.net). 10 11 ## Prepare for installation 12 13 Download the repository containing all the [source files](https://git.taler.net/robocop.git/) 14 15 Then make sure you have Rust and Cargo installed. 16 17 ## Install and run 18 19 Once Cargo is installed, we can install `robocop` with the command: 20 21 ``` 22 $ cargo install --path . 23 ``` 24 25 You can then run it by providing the sanction list in JSON format: 26 27 ``` 28 $ ~/.cargo/bin/robocop swiss.json 29 ``` 30 31 32 ## Converting official sanction lists to robocop's internal format 33 34 `robocop` consumes its sanction list as a JSON **array of target records**. Each 35 record has a string `ssid` (its identifier) plus any number of registry fields 36 whose values are **arrays of strings** (e.g. `FULL_NAME`, `PERSON_FIRST_NAMES`, 37 `PERSON_LAST_NAME`, `DATE_OF_BIRTH`, `NATIONALITY`, `PERSON_NATIONAL_ID`, 38 `COMPANY_NAME`, `ADDRESS_*` / `REGISTERED_OFFICE_ADDRESS_*`). At match time 39 `robocop` compares each field of an incoming query against the same-named field 40 of every record (fuzzy, Levenshtein-based), so all converters emit the **same** 41 registry field names regardless of source list. 42 43 One converter is provided per source-list format. Each reads the official XML on 44 stdin and writes the JSON array on stdout; pipe it through 45 `robocop-json-postprocess` (which drops empty/`null` fields) to get the final 46 list: 47 48 | Converter | Source list | Official XML schema | 49 |-----------|-------------|---------------------| 50 | `robocop-ch-to-json` | Switzerland — SECO | `swiss-sanctions-list` | 51 | `robocop-eu-to-json` | EU — Consolidated Financial Sanctions List | `export` / `sanctionEntity` | 52 | `robocop-un-to-json` | UN — Security Council Consolidated List | `CONSOLIDATED_LIST` | 53 | `robocop-ofac-to-json` | US — OFAC SDN **and** Consolidated lists | legacy `sdnList` / `sdnEntry` | 54 | `robocop-uk-to-json` | UK — OFSI Consolidated List | `ArrayOfFinancialSanctionsTarget` | 55 56 Each record's `ssid` is namespaced by authority (`EU-`, `UN-`, `OFAC-`, `GB-`, 57 and the bare numeric Swiss id) so records stay unique if several lists are 58 concatenated into one file. 59 60 ``` 61 $ ./robocop-ch-to-json < swiss.xml | robocop-json-postprocess > swiss.json 62 $ ./robocop-eu-to-json < eu.xml | robocop-json-postprocess > eu.json 63 $ ./robocop-un-to-json < un.xml | robocop-json-postprocess > un.json 64 $ ./robocop-ofac-to-json < SDN.XML | robocop-json-postprocess > ofac-sdn.json 65 $ ./robocop-ofac-to-json --prefix OFAC-CONS- < CONSOLIDATED.XML \ 66 | robocop-json-postprocess > ofac-cons.json 67 $ ./robocop-uk-to-json < ConList.xml | robocop-json-postprocess > uk.json 68 ``` 69 70 Note on the OFAC consolidated (non-SDN) list: OFAC serves it in the legacy 71 `sdnList` format at `.../exports/CONSOLIDATED.XML`, and in the newer "advanced" 72 format at `CONS_ADVANCED.XML`. `robocop-ofac-to-json` reads the **legacy** format, 73 so a single converter handles both the SDN list and the consolidated list; use 74 `CONSOLIDATED.XML` (not `CONS_ADVANCED.XML`, which robocop does not parse). Because 75 OFAC reuses a few `uid`s across the two lists, pass `--prefix OFAC-CONS-` when 76 converting the consolidated list if you intend to merge it with the SDN list into 77 one file, so the records keep distinct `ssid`s.