Maritime: dark-fleet detection from AIS
The problem
Vessels evading sanctions have a well-known playbook: turn off the AIS transponder in open water, transfer cargo ship-to-ship, re-flag, rename, and re-appear somewhere else. Catching this today means stitching together an AIS aggregator subscription, a vessel registry, a sanctions screening tool, and a GIS package — four vendors, four exports, and no single place where "this vessel went dark near a sanctioned port, and its beneficial owner is designated" is one traceable answer.
The scenario
An analyst is reviewing a tanker with a history of AIS gaps in the Gulf of Oman. Before escalating to enforcement, they need three things joined together: confirmation the vessel (or a vessel in the same footprint) was actually in the area during the gap, a sanctions screen on the vessel and its registered owner, and the ownership chain traced up to whoever ultimately controls it — because the vessel itself is rarely the sanctioned party.
Geofence, screen, and trace ownership — one engine
GEOFENCE, SANCTIONS_SCREEN, and BENEFICIAL_OWNERSHIP_CHAIN are all SQL-reachable operators against the same governed store — there's no export between the AIS platform and the sanctions tool.
PURPOSE 'maritime:sanctions-investigation'
-- 1. What else was moving through the same waters during the AIS gap window?
-- (fence is a pre-registered geofence name; from_ts/to_ts are epoch-ns)
SELECT * FROM GEOFENCE(
'gulf-of-oman-50km',
target_type => 'VesselPositionReport',
from_ts => 1773327600000000000,
to_ts => 1773597600000000000
);
-- 2. Screen the vessel's registered owner against sanctions lists
SELECT * FROM SANCTIONS_SCREEN('Meridian Shipping SA')
WITH PROVENANCE;
-- 3. Trace beneficial ownership to the natural person or ultimate parent
SELECT * FROM BENEFICIAL_OWNERSHIP_CHAIN('Meridian Shipping SA', 7)
WITH PROVENANCE;Typed SDK snippet
from relata import RelataClient
with RelataClient(
"http://localhost:9090",
bearer_token="relata-dev",
purpose="maritime:sanctions-investigation",
) as client:
# Vessels sharing the geofence during the AIS gap window
# (from_ts / to_ts are epoch-ns; fence is a pre-registered geofence name)
nearby = client.query(
"SELECT * FROM GEOFENCE('gulf-of-oman-50km', "
"target_type => 'VesselPositionReport', "
"from_ts => 1773327600000000000, to_ts => 1773597600000000000)"
)
for vessel in nearby:
print(vessel["mmsi"], vessel["last_position"])
# Screen the registered owner
hits = client.query("SELECT * FROM SANCTIONS_SCREEN('Meridian Shipping SA')")
for hit in hits:
print(f"Sanctions hit: {hit['list_id']} ({hit['designation_date']})")
# Walk the ownership chain looking for the actual designated party
chain = client.query(
"SELECT * FROM BENEFICIAL_OWNERSHIP_CHAIN('Meridian Shipping SA', 7)"
)
for link in chain:
print(f"depth {link['depth']}: {link['owner_name']} ({link['ownership_pct']}%)")Why the same engine wins on this workload
- Geospatial, graph, and identity queries are one plan, not three tools.
GEOFENCE(S2-cell indexed), the ownership graph, and sanctions screening all run against the same governed store — no CSV round-trip between the AIS aggregator and the sanctions vendor. See the Query Cookbook for the full operator surface. - The vessel isn't the sanctioned party — the owner usually is.
BENEFICIAL_OWNERSHIP_CHAINtraces through shell-company layers the same way it would for a wire transfer, because it's the same operator, not a maritime-specific reimplementation. - Every hit carries provenance.
WITH PROVENANCEon the sanctions screen and ownership trace means the eventual enforcement package cites exactly which list, which designation date, and which ownership record produced each finding. See Governance. - Bi-temporal by default. Flag changes, renames, and ownership transfers are tracked over time, not overwritten —
AS OFreconstructs the ownership structure as it stood on the date of the incident, not as it stands today.
See also
- AML: sanctions screening with an audit trail — the same
SANCTIONS_SCREENandBENEFICIAL_OWNERSHIP_CHAINoperators applied to correspondent banking - Governance —
PURPOSE, provenance, and the audit hash chain behind every finding - Query Cookbook —
GEOFENCEand the full graph/geospatial operator reference - Identity Resolution — how
MmsiandImoNumberresolve to the same vessel across a flag change