OSINT: cross-platform identity fusion

The problem

A subject of interest doesn't confine themselves to one platform. The same person shows up as a phone number in a leaked database, a handle on one social network, a different handle on another, and possibly a face in a CCTV frame — and open-source tooling today treats each of those as a separate lookup in a separate tool, with the analyst doing the correlation by hand and by memory. That doesn't scale past a handful of subjects, and it leaves no defensible trail for how the correlation was made.

The scenario

An analyst has a single verified phone number for a subject of interest. They need every platform that number — or an identifier chained from it — resolves to, ranked and with a confidence score, and they need to know if it's the same underlying identity linking two specific profiles the team has already flagged independently.

Resolve, cluster, and verify — from one identifier

RESOLVE_IDENTITY, IDENTITY_CLUSTER, and SAME_IDENTITY all run against the same IdentityIndex that SmartIngest builds automatically at ingest time — there's no separate cross-platform correlation product to license and feed.

PURPOSE 'osint_investigation:CT-2026-0441'
 
-- Every identity value linked to this phone number — handles, emails, wallets
SELECT * FROM RESOLVE_IDENTITY('+966501234567', MODE => 'cluster');
 
-- Does this specific pair of flagged profiles resolve to the same person?
SELECT * FROM SAME_IDENTITY('profile-twitter-suspectA', 'profile-telegram-suspectB');
 
-- Full cluster for a confirmed entity, once the analyst confirms the match
SELECT * FROM IDENTITY_CLUSTER('person-441');

Typed SDK snippet

from relata import RelataClient, IdentityClient
 
with RelataClient(
    "http://localhost:9090",
    bearer_token="relata-dev",
    purpose="osint_investigation:CT-2026-0441",
) as client:
    id_client = IdentityClient.from_client(client)
 
    # Every identity value this phone number resolves to, across platforms
    cluster = id_client.cluster("+966501234567")
    for identity in cluster:
        print(identity)
 
    # Verdict: do these two independently-flagged profiles belong
    # to the same underlying entity?
    verdict = client.query(
        "SELECT * FROM SAME_IDENTITY("
        "'profile-twitter-suspectA', 'profile-telegram-suspectB')"
    )
 
    # Expand outward from the confirmed subject to known associates
    network = client.query(
        "SELECT * FROM PATHS_BETWEEN('person-441', 'person-associate-118', max_hops => 3)"
    )

Why this replaces five platform-specific lookups

  • One identity graph, not five platform APIs. IdentityIndex links every canonical identifier — phone, email, handle, wallet — to the same underlying entity at write time via SmartIngest, so RESOLVE_IDENTITY is a single query, not a fan-out across tools. See Identity Resolution.
  • The correlation is a verdict, not a guess. SAME_IDENTITY returns a confidence-scored decision on two specific profiles, so an analyst's cross-platform attribution is a reproducible query result, not a judgment call buried in a report.
  • The pivot from identity to network is the same engine. PATHS_BETWEEN walks the same graph RESOLVE_IDENTITY just populated — there's no export into a separate link-analysis tool once identity resolution is done.
  • Every collection act is purpose-scoped and audited. PURPOSE 'osint_investigation:CT-2026-0441' ties every lookup to the case it supports, in the same audit trail that governs every other protected read. See Governance.

See also