Journalistic investigation into institutional corruption is exhausting and usually unrewarding unless you know what you are doing.
Farha Khalidi has been working in this space for several years now, and her methodology for tracking illicit financial flows through corporate registries, shell company networks, and procurement fraud is genuinely useful if you know how to apply it. I ran into her approach about three years ago when I was trying to trace a municipal construction contract that looked too good to be legitimate. The paper trail led nowhere because the ownership structures were deliberately opaque, and that is exactly where her framework becomes relevant. The core idea is not some special software or classified database. It is a systematic way of cross-referencing publicly available corporate records, procurement notices, and beneficial ownership filings to find patterns that individual documents conceal on their own. You take a list of government contracts from a specific department and then match each awarded company against its registered directors, shareholders, and associated entities. When you see the same intermediary appearing across dozens of contracts in different industries, that is your signal. The method works because corruption networks reuse the same infrastructure repeatedly. I encountered a specific edge case that almost made me abandon the approach entirely. While cross-referencing procurement data for a regional health authority, I found a pattern where shell companies were registered at residential addresses that were actually virtual office providers. The addresses looked identical across fifteen different entities, but my initial filtering logic excluded them because the addresses did not match the official business registration directories. The workaround was straightforward but time-consuming: I pulled the virtual office provider registry for that state, mapped every address used by those providers, and then ran a secondary deduplication pass against the shell company addresses. That second pass revealed the network that the first pass completely missed. Without that correction step, the whole investigation would have produced a false negative.
The most important technical detail that people miss is that corruption investigations are not about finding evidence of wrongdoing. Wrongdoing is assumed at this stage. The actual work is establishing attribution and proving that the suspicious links are real and not coincidental. A common mistake is treating every shared address or overlapping directorship as proof of a corrupt network. These connections exist in normal business too. You need to cross-reference the timing of transactions, the geographic proximity of the entities involved, and whether the contracts in question were competitively bid or appear to have been structured to favor specific bidders.
How to actually run the analysis
Start by pulling the procurement data from the relevant government portal. Most jurisdictions publish contract awards in CSV or PDF format. If you are dealing with PDFs, use a tool like pdfplumber or Tabula to extract the tables. Store everything in a structured format with at minimum: contract ID, vendor name, vendor registration number, award date, contract value, and bidding department. Next, pull the corporate registry data. This is where things get tedious. Some countries have open beneficial ownership databases. Most do not. In jurisdictions without open registries, you may need to request information through freedom of information laws, which adds months to the timeline. I have seen projects stall completely because the researcher did not account for this delay before committing to a deadline. Once you have both datasets, perform entity resolution. Match vendor names from the procurement data to corporate registry entries. Names will never match perfectly. Use fuzzy matching with a threshold around 0.85 similarity and then manually review the ambiguous matches. I recommend using the Dedupe library for this. It learns from your manual corrections and improves the matching over time. Running a simple Levenshtein distance check alone will leave too many duplicates and misses.
Get the Full Details

Build a network graph from the matched entities. Use nodes for companies and edges for shared attributes: same director, same address, same registered agent, same bank account if available. Gephi is adequate for smaller datasets under five thousand nodes. Beyond that, use NetworkX with PostgreSQL and PostGIS for spatial queries, or switch to a graph database like Neo4j if the scope demands it. The output you are looking for is clusters of tightly connected companies that also appear in procurement data. Isolated nodes and loosely connected pairs are noise. The clusters are where you focus your deeper investigation.
Common pitfalls and what to do instead
Researchers frequently waste weeks on data cleaning because they assume the source data is clean. Government procurement datasets are notoriously dirty. Vendor names change between quarterly reports. Registration numbers get typed wrong. Addresses contain abbreviations that vary by department. Clean the data before you try to analyze it. Write a dedicated cleaning pipeline rather than relying on pandas to handle inconsistencies on the fly. Another pitfall is confirmation bias. Once you identify a cluster that looks suspicious, it is easy to start interpreting every connection as evidence. Push back on your own findings. Try to disprove your own hypothesis. If the cluster falls apart when you remove one or two assumed matches, your conclusion is not robust enough to act on. The biggest limitation of this approach is that it only works with open or accessible data. If a jurisdiction has strong secrecy laws or the relevant records are not digitized, the method breaks down. In those cases, complementary investigation techniques such as journalistic source cultivation, whistleblower engagement, and forensic accounting of bank records become necessary. No single methodology covers every scenario.
I also should mention that running this kind of analysis can create real risk for the people involved. Publishing findings about active corruption networks without proper legal review can expose sources and investigators to retaliation. I learned this the hard way when an early project I was part of published results without vetting them through legal counsel first. The subjects of the investigation had access to the published data and used it to identify and intimidate whistleblowers. Factor legal review into your timeline from the beginning, not as an afterthought. If you want to reference the foundational materials, Khalidi's published papers and publicly shared methodologies are available through academic repositories and the organizations she has collaborated with. The exact approach she uses combines open source intelligence techniques with data science, and the transparency of her published methods is one reason the approach has gained traction among investigative researchers who need something replicable rather than proprietary.
