Cosmin Marginean

February 5, 2023

Querying UBOs with Open Ownership and BODS RDF

Identifying the ultimate beneficial owners (UBOs) for a company or an asset is a common use case in Financial Services and an integral part of Risk & Compliance solutions. Today we will look at some practical solutions for identifying UBOs using the Open Ownership register.

As mentioned before, the BODS schema is a good fit for graph/network reasoning. Together with the RDF vocabulary and tooling, it makes querying and traversing ownership structures an organic development.

For this exercise, we'll write and test some SPARQL queries against the RDF version of the Open Ownership register. The BODS RDF GitHub project contains instructions on how to produce this from the BODS register. If you're new to this, then our earlier introductory article is a good place to start.

Finding all the UBOs for an entity

There are always application and jurisdiction-specific requirements regarding the definition of a UBO. For this exercise, we consider a (U)BO any individual on the Open Ownership register with any control or ownership over an entity or asset. In other words, we will traverse all bods:ownsOrControls relationships.

In this example, we are querying the UBOs for FAIR OAK LAND LIMITED which has the BODS ID openownership-register-7925164146744028567.

PREFIX rdf: <>
PREFIX bods: <>
PREFIX bods-res: <>
PREFIX foaf: <>

SELECT ?uboName ?directCtrlCompanyName
    ?ubo rdf:type bods:Person .
    ?ubo foaf:name ?uboName .
    ?ubo bods:ownsOrControls ?directCtrlCompany .
    ?directCtrlCompany foaf:name ?directCtrlCompanyName .
    ?directCtrlCompany bods:ownsOrControls* 
       bods-res:openownership-register-7925164146744028567 .
ORDER BY ?uboName

The query simply lists the names of the UBOs and the companies they control directly - companies which in turn control the target directly or indirectly. It returns 4 records with the Open Ownership register version at the time of this writing.


The ownership and control chain

The next level of detail is to find which intermediate entities are involved in the ownership/control network. This is crucial as it can identify other assets or entities related to the target and will produce a comprehensive picture of the corporate group.

One way to achieve this is to retrieve the entire ownership structure from any UBO down to our target. This can be done with a single query and some additional logic for parsing the result set.

PREFIX rdf:      <>
PREFIX bods:     <>
PREFIX bods-res: <>
PREFIX foaf: <>

SELECT ?uboName ?parent ?child
    ?ubo bods:ownsOrControls* ?a .
    ?ubo foaf:name ?uboName .
    ?ubo rdf:type bods:Person .
    ?a foaf:name ?parent .
    ?a bods:ownsOrControls ?b .
    ?b foaf:name ?child .
    ?b bods:ownsOrControls* 
            bods-res:openownership-register-6295574063848670981 .
ORDER BY ?uboName


This query produces a list of direct (parent->child) relationships between any two consecutive entities in the ownership chain. Then it's simply a matter of traversing this list and producing the chain of ownership for each UBO.

For that, we firstly group the rows based on the UBO (first column) and then for each of these groups we apply the following logic: start from the row where the UBO is named as a parent, get the child in that row, find the row where that child is a parent, and so on until the child on the current row is the target entity (FAIR OAK LAND LIMITED).


Note: This is a conceptual algorithm, not an implementation guideline: in a real-world application, we'd obviously identify entities based on their unique IDs, not their names.

So the chain of ownership from the UBO named Tony Darsey to the target FAIR OAK LAND LIMITED would be something like this (Source):