It doesn't. It lives in government systems, company registries, and identity providers — and the onboarding architecture should reflect that.
This post breaks down what a modern KYC onboarding flow looks like when it's built around existing identity infrastructure instead of manual data collection. I'll walk through the technical components: the identity redirect, registry pull, UBO graph, AML hook, and risk scoring inputs.
The core architectural shift
Traditional KYC onboarding is a data collection pipeline:
User inputs data → Bank stores → Verification service checks → AML runs → Decision
The problem: the bank is treating the user as the data source. They're not — they're an unreliable intermediary between the bank and verified government records.
Modern onboarding treats identity providers and registries as the data source, and the user as the consent layer:
User consents → Gov identity provider returns verified data →
Registry returns entity structure → AML runs on verified graph → Decision
Step 1: The identity redirect (OAuth-style)
The flow starts when the user selects digital ID at the onboarding entry point.
The bank initiates an OAuth 2.0 / OpenID Connect authorization request to the government identity provider (e.g. Estonia's X-Road / Smart-ID, Moldova's MPASS). The user authenticates at the provider level — the bank never sees credentials.
On successful authentication, the identity provider returns a signed assertion:
json
{
"sub": "EE38512120123456",
"given_name": "Anna",
"family_name": "Mägi",
"birthdate": "1985-12-12",
"document_type": "ID_CARD",
"document_number": "AA1234567",
"verified_at": "2026-05-20T10:32:00Z",
"assurance_level": "high"
}
The assurance_level: high signals that identity was verified by a government-issued credential at LoA3 (Level of Assurance 3), satisfying strong KYC requirements under AMLD5/6 in the EU context.
No document upload. No OCR. No liveness check needed if the IdP already performed biometric verification.
Step 2: Registry pull for business accounts
For corporate onboarding, the bank queries the national company registry API using the verified identity as the lookup key.
GET /registry/entities?beneficial_owner=NATIONAL_ID&status=active
The registry returns all entities where the authenticated individual appears as a director, shareholder, or beneficial owner:
{
"entities": [
{
"registration_number": "12345678",
"legal_name": "Example OÜ",
"legal_form": "private_limited",
"registered_address": "Tallinn, Estonia",
"industry_code": "6419",
"directors": ["..."],
"shareholders": [
{
"name": "Anna Mägi",
"national_id": "EE38512120123456",
"ownership_percentage": 75.0,
"ownership_type": "direct"
},
{
"name": "Holding OÜ",
"registration_number": "87654321",
"ownership_percentage": 25.0,
"ownership_type": "indirect"
}
]
}
]
}
If a shareholder is itself a legal entity, the bank resolves ownership recursively — calling the registry again for that entity’s shareholders — until every chain terminates at a natural person with ≥25% ownership (the standard UBO threshold under AMLD).
Step 3: Building the UBO ownership graph
The result of the recursive registry resolution is an ownership graph. For AML screening, this graph needs to be flattened into a list of UBOs with calculated effective ownership.
`def resolve_ubos(entity_id, ownership_pct, visited=set()):
if entity_id in visited:
return [] # break circular ownership loops
visited.add(entity_id)
shareholders = registry.get_shareholders(entity_id)
ubos = []
for s in shareholders:
effective_pct = ownership_pct * (s.ownership_percentage / 100)
if s.is_natural_person:
ubos.append(UBO(person=s, effective_ownership=effective_pct))
else:
ubos.extend(resolve_ubos(s.registration_number, effective_pct, visited))
return ubos`
This gives you a clean list of natural persons with their effective ownership percentage — ready for AML screening.
Step 4: AML screening hooks into the UBO graph
Each UBO is submitted to the bank’s sanctions and PEP screening provider:
{
"subjects": [
{
"name": "Anna Mägi",
"dob": "1985-12-12",
"nationality": "EE",
"role": "UBO",
"effective_ownership": 75.0
}
],
"screening_types": ["sanctions", "pep", "adverse_media"],
"match_threshold": 85
}
Screening runs against OFAC, EU consolidated list, UN sanctions, and PEP databases. Results return with match confidence scores. Hits above the threshold trigger a manual review queue rather than auto-approval.
Because UBO data came from a verified registry rather than self-reported fields, false positive rates drop significantly — names and dates of birth are verified, not user-entered.
Step 5: Risk scoring inputs
AML risk scoring combines verified identity and structural data with behavioral signals:
| Signal | Source | Notes |
|---|---|---|
| Industry code | Company registry | NACE code maps to AML risk category |
| Geography | Registry + IP | Incorporation country, operating countries |
| Expected transaction volume | User-provided | Only manual input in the flow |
| Typical recipient types | User-provided | Cross-border, consumer, B2B |
| Device fingerprint | Client-side SDK | Fraud signal, not AML directly |
| Open banking behavior | PSD2 / consent | Transaction pattern from existing accounts |
The risk score output determines initial access tier — which transaction limits apply, whether enhanced due diligence is triggered, and whether any services are conditionally available.
What the user actually enters manually
With this architecture, the only data a user provides manually is what genuinely doesn’t exist in any system yet:
• Expected monthly transaction volume
• Typical payment recipients (individuals, businesses, cross-border)
• Purpose of the account
Everything else — identity, corporate structure, UBO chain, verified document data — comes from authoritative sources via API.
UX layer: the progress bar as a trust signal
For flows with multiple steps (identity verification → entity selection → risk questions → decision), always surface a step indicator to the user.
This is not cosmetic. Abandonment in multi-step onboarding correlates strongly with uncertainty about remaining duration, not with actual step count. A user who knows they’re on step 3 of 5 behaves differently from a user who doesn’t know when it ends.
For compliance flows specifically, where you legally can’t skip steps, the UX contract with the user depends on setting accurate expectations.
Infrastructure that already exists
• Estonia: X-Road + Smart-ID + e-Business Register — full stack connected
• EU eIDAS 2.0: European Digital Identity Wallet — framework being rolled out across member states
• Moldova: MPASS identity portal + State Registration Chamber API — components exist, not yet connected into a unified onboarding product
• UK: GOV.UK One Login — identity layer live, banking integration limited
The technical building blocks are mostly there. The gap is product integration — banks treating these APIs as onboarding infrastructure rather than optional add-ons.
I build payment and compliance systems inside a regulated EMI, working across AML tooling, sanctions screening, and KYC architecture. Writing here about what compliance engineering actually looks like from the inside.
Originally discussed on LinkedIn
Top comments (0)