KYC | AML

Player identity verification and suspicious financial activity monitoring

Phase 3
Spec
KYC (Know Your Customer) and AML (Anti-Money Laundering) are two distinct but related mechanisms. KYC is a synchronous gate: it checks whether the player is sufficiently verified for a specific operation and blocks it if not. AML is async monitoring: it analyses transaction patterns and flags suspicious ones for manual review by the compliance team. Both are required for most gambling licences. The only synchronous overlap is sanctions screening, which blocks immediately.
AML flags are never shown to the player and in the vast majority of cases do not block the transaction. The exception is a sanctions hit: it immediately freezes the account. Conflating KYC and AML into one flow is a common mistake that leads to over-blocking. [TO BE DISCUSSED]
1.

Purpose

Identity verification (KYC)

Confirm the player is who they say they are before allowing financial activity above thresholds. Required by gambling regulation in every licensed market.

Age verification

Confirm player is 18+ (or legal gambling age in their jurisdiction) before first deposit. Non-negotiable.

Sanctions screening

Screen player name and date of birth against OFAC, EU, and UN sanctions lists at registration and periodically. Synchronous block on hit.

AML transaction monitoring

Detect suspicious patterns: rapid deposit--withdrawal cycles, structuring, large transactions. Flag for compliance review -- almost never auto-block.

Regulatory reporting

File mandatory Currency Transaction Reports (CTR) for large transactions and Suspicious Activity Reports (SAR) when warranted. Jurisdiction-specific.

PEP screening

Identify Politically Exposed Persons for enhanced due diligence. PEP status alone does not block -- triggers Level 3 KYC requirement.

2.

Where it sits and how information flows

Position in the stack

1
Limits & Rules enginecalls KYC check as one of its rules
2
KYC | AML Service ← YOU ARE HEREreturns PASS or KYC_REQUIRED; fires AML checks async
3
Orchestrator (only reached on PASS)selects PSP, applies cascade logic
4
Compliance queue (async, AML only)compliance officer reviews flagged transactions

Invocation flow

1
Limits & Rules engine calls KYC check: (user_id, brand_id, amount, direction)
2
Load user KYC level from cache (Redis) or DB
3
Check: does this operation require a higher KYC level than user currently has?
4
If YES → return KYC_REQUIRED with required_level + redirect_url
5
If NO → return PASS to Limits & Rules engine
6
Async: run AML pattern checks against transaction history (non-blocking)
7
Async: if AML flag triggered → write to aml_flags table + notify compliance queue

Input data and sources

user_id, amount, direction, cumulative deposit total

from Limits & Rules engine

Current KYC level, document status, verification date

user_kyc_profiles table (Redis cache TTL 60s)

Brand KYC thresholds: anonymous cap, L1 cap, EDD threshold

brand_limits table (cached)

Transaction history: deposit totals, methods used, cycle patterns

transactions table (aggregate, Redis)

Sanctions + PEP screening result

External provider (ComplyAdvantage / WorldCheck) — cached per user

3.

Required at launch

KYC levels

Level 0Anonymous

Requirements

  • None — player just registered

Allows

Deposits up to cumulative threshold $X

Blocks

Withdrawals; deposits above threshold
Level 1Basic verified

Requirements

  • Email confirmed
  • Phone number confirmed
  • Date of birth provided + age 18+ confirmed
  • Country of residence declared

Allows

Deposits up to higher threshold $Y; withdrawals up to $Z

Blocks

Withdrawals above $Z; deposits above threshold $Y
Level 2Identity verified

Requirements

  • Government-issued ID (passport / national ID / driver's licence)
  • Proof of address (utility bill or bank statement, max 3 months old)
  • Selfie / liveness check (optional for Phase 3, recommended)

Allows

All deposits and withdrawals within brand limits

Blocks

Transactions above EDD threshold (requires Level 3)
Level 3Enhanced Due Diligence (EDD)

Requirements

  • All Level 2 documents
  • Source of funds declaration
  • Source of wealth evidence (bank statement, payslips, tax return)
  • Manual review by compliance officer

Allows

High-value transactions above EDD threshold

Blocks

Nothing — this is the maximum level

AML rules

TriggerActionBlocks?

Single transaction ≥ CTR threshold (e.g. $10 000)

Value set by regulator, not configurable. Transaction proceeds normally.

File Currency Transaction Report (CTR) — mandatory
No (monitor)

Rapid deposit--withdrawal cycle (deposit then withdraw > 80% within 24h)

Classic layering pattern — funds enter and exit quickly without gameplay

Flag for AML queue + notify compliance officer
No (monitor)

Structuring: multiple deposits just below CTR threshold in short window

Intentional breaking of large amounts into smaller ones to avoid reporting

Flag for AML queue + escalate to compliance
No (monitor)

Sanctions hit: player name / DOB matches OFAC, EU, UN list

This is the only AML check that synchronously blocks a transaction

INSTANT BLOCK — freeze account, notify compliance immediately
Yes (instant)

PEP (Politically Exposed Person) detected

PEP status alone is not a reason to block; requires enhanced due diligence

Flag for enhanced review — do not auto-block
No (monitor)

Deposits from 3+ different payment methods in 7 days

Flag for review — potential money mule or account sharing
No (monitor)

Error codes

CodeHTTPDescriptionPlayer message
KYC_REQUIRED422Operation requires higher KYC level than user has"Verify your identity to continue"
KYC_DOCUMENTS_PENDING422User submitted documents but review is in progress"Your documents are under review (up to 24h)"
KYC_DOCUMENTS_REJECTED422Submitted documents were rejected — resubmission needed"Documents rejected — please re-submit"
SANCTIONS_HIT403Player matches a sanctions list — account frozen"Your account has been restricted. Contact support."
EDD_REQUIRED422Transaction triggers Enhanced Due Diligence threshold"Please provide source of funds documentation"
HTTP 422 -- KYC_REQUIRED response
Blocked
{
  "error": "KYC_REQUIRED",
  "message": "Identity verification is required to continue.",
  "required_level": 2,
  "current_level": 1,
  "kyc_redirect_url": "/kyc/verify?return_to=/deposit"
}

Minimum DB schema for Phase 3

KYC documents -- encrypted at rest, retention per jurisdiction
-- Current KYC status per user per brand
user_kyc_profiles (
  user_id, brand_id,
  kyc_level,           -- 0 | 1 | 2 | 3
  verified_at,
  provider,            -- 'manual' | 'onfido' | 'sumsub'
  sanctions_status,    -- 'clear' | 'hit' | 'pending'
  sanctions_checked_at,
  pep_status           -- 'clear' | 'hit' | 'pending'
)

-- Uploaded verification documents
kyc_documents (
  id, user_id, brand_id,
  type,        -- 'passport' | 'id_card' | 'driving_licence'
               -- 'proof_of_address' | 'source_of_funds' | 'selfie'
  status,      -- 'pending' | 'approved' | 'rejected'
  provider_ref,
  rejection_reason,
  created_at, reviewed_at
)

-- Append-only AML flags
aml_flags (
  id, user_id, brand_id, transaction_id,
  flag_type,   -- 'ctr' | 'rapid_cycle' | 'structuring'
               -- 'sanctions_hit' | 'pep' | 'multi_method'
  status,      -- 'open' | 'reviewed' | 'escalated' | 'closed'
  reviewed_by, reviewed_at,
  created_at
)
4.

Best practices

KYC vs AML -- keep them separate

  • KYC = synchronous gate: "is this user verified enough for this operation?" Always blocks if not.
  • AML = async monitoring: "does this transaction look suspicious?" Almost never blocks synchronously, except sanctions.
  • Do not conflate the two -- mixing them leads to over-blocking legitimate transactions or under-flagging suspicious ones.

Phase 3 scope -- what to build now

  • Manual document review is acceptable for launch -- no need for automated provider (Onfido, Sumsub) in Phase 3.
  • Build the KYC level model and gates now; swap in automated provider later without changing the gate logic.
  • AML for Phase 3: sanctions screening (blocking) + basic transaction pattern flags (non-blocking). Full monitoring rules in Phase 6.

Data, privacy, compliance

  • KYC documents: encrypted at rest, access-logged, retention policy per jurisdiction (typically 5--7 years after account closure).
  • AML flags must never be visible to the player -- they go to an internal compliance queue only.
  • GDPR: player can request data deletion, but AML/KYC records are exempt from erasure (legal obligation overrides right to erasure).
  • Sanctions re-screening: run at registration AND on a scheduled basis (e.g. weekly batch) -- lists change over time.

Performance

  • Cache KYC level per user in Redis (TTL 60s) -- it is read on every payment request.
  • Cache sanctions screening result per user (TTL 24h) -- external API calls are slow and expensive.
  • AML pattern checks run asynchronously via a job queue after the transaction is committed -- never on the hot path.
  • KYC status webhook from provider should update DB and invalidate Redis cache immediately.
DEPO44 | KYC | AML SPEC v1 | PHASE 3