A new OFAC designation can ripple through a supplier base in hours. A vessel quietly added to the EU consolidated list can derail a load that's already at sea. A UK OFSI update can trigger a frozen-funds report obligation before the trade compliance team's daily digest.
This is the unglamorous half of OSINT: sanctions monitoring. Public data, public APIs, but the diffing + matching layer is what every compliance vendor charges money for. You can build it yourself.
The three primary lists
OFAC SDN (US Treasury)
The Specially Designated Nationals list. Sanctioned individuals + entities + vessels + aircraft. Published in three formats:
# Full XML with addresses + akas + identifiers
https://www.treasury.gov/ofac/downloads/sdn.xml
# Tab-delimited "DELTA" — daily diff
https://www.treasury.gov/ofac/downloads/delta/sdn_delta.zip
# Consolidated non-SDN list (sectoral + executive-order)
https://www.treasury.gov/ofac/downloads/consolidated/consolidated.xml
Refresh daily is enough. Diff against yesterday's snapshot to spot new designations.
EU Consolidated Financial Sanctions List (FSF)
Maintained by the European External Action Service. Updated multiple times per week:
https://webgate.ec.europa.eu/europeaid/fsd/fsf/public/files/xmlFullSanctionsList_1_1/content?token=...
Token required (free registration). XML format includes designations with akas, dates of birth, passport numbers, and effective sanction dates.
UK OFSI Consolidated List
UK Treasury's sanctioned-persons list:
https://www.gov.uk/government/publications/financial-sanctions-consolidated-list-of-targets/consolidated-list-of-targets
Published as XLSX + CSV + JSON. JSON variant is most diffable.
Daily diff pattern
A practical sanctions-monitoring pipeline:
1. Daily 06:00 UTC cron:
- Download all three lists
- Compare to yesterday's stored snapshot
- Emit added rows + removed rows + modified rows
2. For each added designation:
- Cross-reference against your supplier / counterparty / vessel database
- Score: 100 if direct match, 70 if aka match, 40 if name+country fuzzy match
- Fire alert to compliance Slack
3. For each modified designation (e.g. address change, new aka):
- Re-run match against your database
- Score: 50 (lower priority than new designations)
The matching layer
This is where you can spend infinite time. Three approaches by sophistication:
1. Exact match on identifiers
Match new SDN rows against your supplier DB by:
- Tax ID / VAT number / DUNS
- IMO number (for vessels)
- ICAO 24-bit address (for aircraft)
- Passport / national ID number
Catches the 30% of designations that have hard identifiers in your DB.
2. Name + jurisdiction fuzzy match
Levenshtein distance ≤2 on company name, restricted to the same country. Catches another 40-50%, with a manageable false-positive rate if you filter on jurisdiction.
3. Network-graph match
Match on beneficial-ownership chains, shared directors, shared addresses. Catches another 15-20%. Requires a graph database (Neo4j, Postgres+pgRouting) and an ownership-data source (Open Ownership, OpenCorporates).
Most operations stop at #2. #3 is where dedicated KYC vendors (LSEG, Refinitiv, Sayari) earn their fee.
False-positive tax
Sanctions lists have legitimate name overlaps with non-sanctioned people. The "John Smith" problem is real. Three filters cut noise:
- Jurisdiction filter — require same country before considering a name match
- Date-of-birth filter (when available) — require ±2 years for individuals
- Industry filter — for entities, require same NAICS or SIC code
Even with these, expect ~5-10% false-positive rate. The trade-off vs missing a true match makes the false-positives acceptable.
Severity scoring
Map sanctions matches to a 0-100 severity:
Direct identifier match → 95
Strict name + jurisdiction → 75
Fuzzy name + jurisdiction → 50
Network-graph match → 60
Modified existing record → 35
Above 70 → wake the compliance officer immediately. 50-70 → log to compliance Slack, manual review within 24h. Below 50 → daily digest only.
Geofencing isn't the layer here
For most OSINT use cases the geofencing layer is what reduces noise. For sanctions monitoring, jurisdiction is the equivalent. Filter inbound designations to:
- Countries you operate in
- Countries your suppliers operate in
- Countries your counterparties bank in
Drops 60-80% of irrelevant designations on day one.
Free starter stack
Minimum viable sanctions monitoring this week:
- Daily 06:00 UTC cron pulling all three lists
- Diff against yesterday → new + removed + modified rows
- Strict-then-fuzzy name match against your supplier DB
- Score on 0-100, route Slack channel
#compliance-sanctionsfor ≥50 - CSV export of weekly hits for the compliance file
Augur's OFAC + EU + UK consolidated-list ingest wraps the diff + match layer with the same geofencing + severity pipeline as the rest of the platform.
What this looks like in production
Mid-market commodities trader: daily OFAC diff against 4,000 counterparty rows + jurisdiction filter cuts alert volume from 200/week to 8/week. Compliance team reviews + flags within 24 hours.
European bank: EU FSF + OFAC diff against 50,000 customer rows. Direct-identifier hits trigger immediate account-freeze; fuzzy matches queue for human review.
Maritime operator: OFAC SDN vessel list + AIS feed + IMO cross-reference catches port-call attempts by sanctioned vessels in real time. Has saved one near-miss already.
The lists are free. The diff + match is the work.
When you need more
For regulated industries (banks, insurers, payment processors):
- LSEG World-Check — global PEP + sanctions database with continuous monitoring
- Refinitiv — same playbook, different vendor
- Sayari — beneficial-ownership network graph + sanctions overlay
- Dow Jones Risk & Compliance — adverse-media + sanctions combined
For non-regulated operations, the OSINT stack above gets you 80% of the value at 0% of the cost.