Docs/Graph Analysis

Graph-Based Fraud Detection

RiskGuard uses Neo4j to model relationships between users, devices, phone numbers, and merchants. Graph queries catch fraud patterns that rule engines miss.

The Graph Model

Node Types

UserKYC-verified account. Properties: phone, name, created_at, risk_level
DevicePhone/tablet/emulator. Properties: device_id, model, os, first_seen
PhoneSIM/number. Properties: msisdn, carrier, country
MerchantReceiving business. Properties: merchant_id, category, location
AgentCash-in/cash-out agent. Properties: agent_id, location, daily_volume

Relationship Types

SENTUser sent a transaction. Properties: amount, currency, timestamp
RECEIVEDUser/merchant received a transaction
USES_DEVICEUser logged in from this device
HAS_PHONEUser registered with this phone number
CASHED_OUT_ATUser withdrew cash at this agent

Common Fraud Patterns

Mule Chain Detection

Find chains of users who receive and immediately forward money, typical of money laundering.

Cypher
MATCH path = (source:User)-[:SENT*3..6]->(sink:User)
WHERE ALL(r IN relationships(path)
  WHERE r.timestamp > datetime() - duration('P7D'))
AND source <> sink
AND ALL(n IN nodes(path)
  WHERE size((n)-[:SENT]->()) > 0
  AND size((n)<-[:SENT]-()) > 0)
RETURN path, length(path) as chain_length
ORDER BY chain_length DESC
LIMIT 20

Shared Device Ring

Detect multiple "independent" users sharing the same device — often synthetic identities.

Cypher
MATCH (u1:User)-[:USES_DEVICE]->(d:Device)<-[:USES_DEVICE]-(u2:User)
WHERE u1 <> u2
WITH d, collect(DISTINCT u1) + collect(DISTINCT u2) as users
WHERE size(users) >= 3
RETURN d.device_id, size(users) as user_count,
  [u IN users | u.phone] as phones

Agent Collusion

Find agents where multiple unrelated users cash out within a short window — indicates coordinated fraud.

Cypher
MATCH (u:User)-[c:CASHED_OUT_AT]->(a:Agent)
WHERE c.timestamp > datetime() - duration('PT2H')
WITH a, collect(DISTINCT u) as users, count(c) as txn_count
WHERE size(users) >= 4
RETURN a.agent_id, a.location, size(users) as distinct_users,
  txn_count, [u IN users | u.phone] as user_phones

Using the Graph API

You can run custom Cypher queries via the API for investigation and monitoring. All queries are read-only — the graph is populated automatically from evaluated transactions.

curl -X POST /v1/graph/query \
  -H "Authorization: Bearer rg_live_..." \
  -d '{
    "query": "MATCH (u:User {phone: $phone})-[:SENT]->(t) RETURN t LIMIT 10",
    "params": { "phone": "+22507585827580" }
  }'

Rate limit: 100 graph queries/minute. Complex queries may timeout at 30s. For heavy analysis, use the Neo4j browser directly (available in Enterprise plan).