The system flagged it. A person closed it.
Most of Interactive Brokers' $11,832,136 settlement was about customers in embargoed jurisdictions and trades in restricted securities. This page is about two paragraphs in the middle of the release, where the screening tool did its job and the alert workflow did not: one alert on a blocked person was closed as a false positive by an analyst, and another sat unreviewed for more than a month. Both are failures of what happens after the match. That is what Noble's alert workflow is built to refuse, and to time.
Source: ofac.treasury.gov/media/934501/download (PDF, 9 pages). Every quotation below is verbatim from that document. Part of Noble's enforcement series.
Interactive Brokers LLC (IB), a Greenwich, Connecticut-based global electronic broker-dealer providing brokerage and investment services to millions of customers worldwide through its online brokerage platform, has agreed to pay the U.S. Department of the Treasury’s Office of Foreign Assets Control (OFAC) $11,832,136 to settle its potential civil liability for apparent violations of multiple OFAC sanctions programs.
Enforcement Release, page 1. Aggravating factor 1: IB "failed to exercise due caution or care for its sanctions compliance obligations when it allowed the sanctions compliance deficiencies described above to exist across its business for a period of at least eight years" (page 6).
KEY to a Noble API key. A free-tier key works; keys are invite-only while Noble is in beta (sales@noblesight.io). The workflow requests after the first two need an alert you own (ALERT_ID, from the first response) and two analysts registered on your team through POST /v1/team.
Blocked Person-1 · Venezuela
Screening alerted on a customer designated for "involvement in a front network enabling corruption in the Venezuelan Government". An analyst closed the alert as a false positive. The account stayed open for another twelve to thirty-one days.
Alert 2018-09-28 · restricted 2018-10-10 and 2018-10-29Blocked Person-2 · Syria
Screening flagged a customer designated for "involvement in an international network benefiting the Assad regime". Nobody reviewed it. Two transfers of about $339,000 went through while it waited.
Flagged ~2019-06-12 · transfers 2019-06-18 and 2019-06-25The match itself was never the problem
IB’s screening systems alerted Blocked Person-1 as a potential match to OFAC’s List of Specially Designated Nationals and Blocked Persons (the “SDN List”) on September 28, 2018. IB staff, however, incorrectly dispositioned the sanctions alert as a false positive. IB did not restrict funds transfer and trading capabilities in Blocked Person-1’s account until October 10, 2018 and October 29, 2018, respectively.
Enforcement Release, page 5, "IB Dealt in the Property of a Blocked Person under the Venezuela Sanctions Regulations".
What failed
The tool found the match. One person decided it was nothing, and that decision was final. Nothing required a second look at an alert on a designated person, and nothing recorded why the first look was wrong.
Noble's control
A match at or above the threshold opens an alert in the same response as the screening. At score 90 or above the alert is born with four_eyes_required: true and a 24-hour due_at. The names below are listed under the same two programs as IB's two blocked persons.
Run it: a Venezuela program designation
curl -s -X POST https://api.noblesight.io/v1/screen -H "X-API-Key: $KEY" -H "Content-Type: application/json" -d '{"name":"Alex Saab","lists":["ofac"]}'
Run it: a Syria program designation
curl -s -X POST https://api.noblesight.io/v1/screen -H "X-API-Key: $KEY" -H "Content-Type: application/json" -d '{"name":"Rami Makhlouf","lists":["ofac"]}'
The fields: alert_id, alert_reason, then the alert's four_eyes_required and due_at
"alert_id": 43309, "alert_reason": "score_threshold",
"summary": { "verdict": "confirmed_match", "top_match": { "uid": "26995", "name": "SAAB MORAN, Alex Nain", "score": 100, "source": "OFAC SDN" } },
"matches": [ { "uid": "26995", "score": 100, "programs": ["VENEZUELA-EO13850"], "prohibition_type": "blocking", ... } ]
"alert_id": 43310, "alert_reason": "score_threshold",
"summary": { "verdict": "confirmed_match", "top_match": { "uid": "10725", "name": "MAKHLUF, Rami", "score": 100, "source": "OFAC SDN" } },
"matches": [ { "uid": "10725", "score": 100, "programs": ["PAARSSR-EO13894"], "prohibition_type": "blocking", ... } ]
# curl -s https://api.noblesight.io/v1/alerts/43309 -H "X-API-Key: $KEY"
"id": 43309, "status": "new", "score": 100,
"four_eyes_required": true,
"due_at": "2026-10-24T20:19:09Z", "overdue": false,
"created_at": "2026-10-23T20:19:09Z"
Captured from production on 2026-10-23, engine 2.4.0. "Rami Makhlouf" is the common press spelling; OFAC lists "MAKHLUF, Rami". The match is 100 anyway, which is the other half of why the tool was never the problem.
Closing a high-score alert takes two people, and the second one has a name
IB staff, however, incorrectly dispositioned the sanctions alert as a false positive.
Enforcement Release, page 5. Among IB's remedial measures (page 7): "implementing a second-level review of an increased scope of screening results".
What failed
One disposition, by one analyst, ended the matter. OFAC's own list of what IB fixed afterwards starts with a second-level review. That is a workflow rule, and a workflow rule is something a system can refuse to break.
Noble's control
An alert cannot go from new straight to closed; it is reviewed or escalated first. At score 90 or above, the analyst who closes it must differ from the analyst who last acted on it. Analysts are named through X-Actor, validated against the tenant's registered team, and an unregistered name is refused rather than recorded. A closure needs a reason from a fixed vocabulary. All of it lands in the alert's append-only activity.
Escalate as the first analyst
curl -s -X POST https://api.noblesight.io/v1/alerts/$ALERT_ID/escalate -H "X-API-Key: $KEY" -H "X-Actor: analyst1@yourbank.example" -H "Content-Type: application/json" -d '{"note":"Exact name, score 100, OFAC SDN. Needs a second reviewer."}'
Then try to close it as the same analyst
curl -s -X POST https://api.noblesight.io/v1/alerts/$ALERT_ID/resolve -H "X-API-Key: $KEY" -H "X-Actor: analyst1@yourbank.example" -H "Content-Type: application/json" -d '{"status":"closed_false_positive","reason":"false_positive_name_only"}'
Then close it as a second, registered analyst
curl -s -X POST https://api.noblesight.io/v1/alerts/$ALERT_ID/resolve -H "X-API-Key: $KEY" -H "X-Actor: analyst2@yourbank.example" -H "Content-Type: application/json" -d '{"status":"closed_true_match","reason":"true_match","disposition":"blocked","note":"Second reviewer confirms."}'
The responses, in order
# escalate as analyst1 → 200
"id": 43257, "status": "escalated", "four_eyes_required": true, "due_at": "2026-10-24T18:56:39Z"
# resolve as analyst1 → refused
{ "type": "compliance_rule_error", "code": "four_eyes_violation",
"message": "four-eyes required: a different analyst must close high-score alerts" }
# resolve as someone not on the team → refused
{ "type": "invalid_request_error", "code": "invalid_actor",
"message": "X-Actor is not a registered active team member of this tenant; register analysts via POST /v1/team" }
# resolve as analyst2 → 200
"id": 43257, "status": "closed_true_match", "disposition": "blocked",
"activity": [
{ "action": "status_change", "actor": "analyst:analyst1@royalbank.example" },
{ "action": "status_change", "actor": "analyst:analyst2@royalbank.example", "reason": "true_match" }
]
# resolve straight from "new", skipping review → refused
{ "type": "compliance_rule_error", "code": "invalid_status_transition",
"message": "invalid status transition: cannot transition from \"new\" to \"closed_false_positive\"" }
Captured from production on 2026-10-23 on a test alert (Qasem Soleimani, score 100). A true-match closure carries a disposition; GET /v1/alerts/{id}/ofac-report then renders the blocking report OFAC requires within 10 business days. A false-positive closure needs one of the fixed reasons (name only, DOB mismatch, country mismatch, entity-type mismatch, other) and is refused without one.
"More than a month" is a number, and the number is on the alert
IB’s screening function identified Blocked Person-2 as a customer and flagged Blocked Person-2’s account as a potential match to the SDN List on or around June 12, 2019. Despite IB having controls and procedures in place, IB failed to block Blocked Person-2’s account for more than a month after IB’s screening function identified Blocked Person-2 as a potential match. IB processed the transactions because of its delay in reviewing alerts due to a lack of resources and because it lacked a clear procedure for prioritizing and escalating sanctions queries.
Enforcement Release, page 5, "IB Dealt in the Property of a Blocked Person under the Syrian Sanctions Regulations".
What failed
Nobody decided the alert was a false positive. Nobody decided anything. A queue with no clock and no escalation path left a flagged blocked person an ordinary customer for more than a month.
Noble's control
Every alert carries due_at from the moment it exists: 24 hours at score 90 or above, 72 hours otherwise, and escalation never loosens it. overdue flips on the alert and GET /v1/alerts/stats counts overdue and within_sla for the whole queue, so "a lack of resources" shows up as a number an examiner can read rather than a sentence in a release. Escalation is one request, not a procedure that has to exist in a binder.
Read the queue
curl -s https://api.noblesight.io/v1/alerts/stats -H "X-API-Key: $KEY" curl -s "https://api.noblesight.io/v1/alerts?status=new&limit=50" -H "X-API-Key: $KEY"
The fields: overdue, within_sla, by_score_band
{ "total": …,
"by_status": { "new": …, "under_review": …, "escalated": …, "closed_false_positive": …, "closed_true_match": … },
"by_score_band": { "95-100": …, "90-94": …, "80-89": …, "below-80": … },
"overdue": …, "within_sla": …, "no_deadline": 0 }
The shape, with your numbers in it. Pair it with a webhook on alert.created and the alert reaches your case system before anyone has to poll. Noble cannot make an analyst look at an alert. It can make sure the alert is never the one thing in the building without a deadline.
Run the requests against your own key
Keys are invite-only while Noble is in beta. Ask for an invite code and you will have a key, two registered analysts, and the refusal above, in a few minutes.
Noble Sight