Data Flow
This page walks through the complete data flow for identity verification in Hadinet Africa, from user initiation to on-chain proof storage.
KYC Verification Flow
The verification process follows 10 distinct steps:
1. User selects a KYC provider (e.g. Smile ID)
2. Attestor creates a session with the provider
3. User completes verification on the provider's interface
4. Provider sends webhook to attestor
5. Attestor creates zkFetch TLS tunnel to provider
6. 14 ZK proofs are generated proving the response is authentic
7. Attestor extracts non-PII metadata (country, level, status)
8. Metadata + ZK proof submitted to Cartesi rollup
9. Cartesi stores the attestation record
10. User sees "Verified" status on their dashboard
Step-by-Step Breakdown
Step 1: Provider Selection
The user selects a KYC provider from the available options (Smile ID for African countries, Plaid for US/EU/UK). The frontend sends this selection to the attestor.
Step 2: Session Creation
The attestor contacts the selected KYC provider's API and creates a new verification session. This session is linked to the user's DID (not their personal identity).
Step 3: User Verification
The user is redirected to the provider's verification interface. For Smile ID, this involves a selfie and document photo. For Plaid, this involves connecting through Plaid Link. The provider processes the documents and biometrics.
Step 4: Webhook Notification
When the provider completes processing, it sends a webhook notification to the attestor. This triggers the next phase of the flow.
Step 5: zkFetch TLS Tunnel
The attestor establishes a TLS-encrypted connection to the KYC provider using zkFetch (Reclaim Protocol). This tunnel is used to retrieve the verification result while generating cryptographic proofs of the interaction.
Step 6: ZK Proof Generation
This is the critical step. 14 separate ZK proofs are generated during the TLS session. These proofs mathematically prove that the KYC provider returned a positive verification result, without revealing what personal data was checked. Any third party can verify these proofs independently without trusting the attestor.
Step 7: Metadata Extraction
The attestor extracts only non-personally-identifiable metadata from the result:
- Country code (e.g., "NG")
- Verification level (e.g., "enhanced")
- Verification status (pass/fail)
- Provider name (e.g., "smile_id")
All personal data is discarded at this point.
Step 8: On-Chain Submission
The metadata and ZK proof are encrypted with the Cartesi rollup's public key and submitted to the blockchain. The encrypted input is processed by the rollup VM.
Step 9: Attestation Storage
The Cartesi rollup stores the attestation record in its deterministic SQLite database. This record is now part of the immutable on-chain state.
Step 10: Dashboard Update
The frontend queries the rollup for the user's updated status and displays the "Verified" badge on their identity card.
Data Storage Architecture
What Lives Where
| Data | Location | Encrypted | Who Can Access |
|---|---|---|---|
| Verification status | Cartesi rollup (on-chain) | Input encrypted | User + authorized parties |
| ZK proof | Cartesi rollup (on-chain) | No (public proof) | Anyone (for verification) |
| Document files | IPFS (Pinata, private) | AES-256-GCM | User + attestor (for decryption) |
| Document metadata | Cartesi rollup (on-chain) | Input encrypted | User |
| Session data | Attestor (in-memory) | N/A | Attestor only, auto-expires |
| Personal data (PII) | Nowhere (discarded) | N/A | Briefly seen by TEE during KYC |
Data Retention
| Data Type | Retention Period | Reason |
|---|---|---|
| On-chain attestations | Permanent | Immutable blockchain record |
| ZK proofs | Permanent | Required for ongoing verification |
| Document vault files | Until user deletes | User-controlled storage |
| Vault metadata | Permanent (soft-delete marker) | Audit trail |
| Personal data | Zero (discarded immediately) | Privacy by design |
| Session data | Auto-expires (minutes) | Temporary processing only |
Document Upload Flow
The document vault follows a separate but related flow:
1. User selects a file and document type
2. File is sent to the attestor's TEE
3. Attestor encrypts the file with AES-256-GCM (unique salt per document)
4. Encrypted blob is uploaded to IPFS via Pinata
5. Metadata (file name, type, size, IPFS hash) is submitted to Cartesi rollup
6. User sees the document in their vault
Document Download Flow
1. User requests a document from their vault
2. Frontend sends authenticated request to attestor
3. Attestor fetches encrypted blob from IPFS
4. Attestor decrypts file inside the TEE
5. Decrypted file is delivered to the user's browser
The decryption key never leaves the TEE. The raw file only exists in the user's browser and the TEE's memory (temporarily).
Next Steps
- Blockchain Layer — How Cartesi and Arbitrum work together
- Encryption — Detailed encryption architecture
- System Overview — Full component breakdown