Architecture Overview
zkIdentity is composed of several interconnected layers that work together to provide privacy-preserving identity verification. This document describes the system architecture, the role of each component, and the data flow from user initiation through to on-chain attestation.
System Diagram
The following diagram illustrates the high-level data flow through the zkIdentity system:
+------------------+
| User Wallet |
+--------+---------+
|
v
+------------------+
| Frontend |
| (Next.js + Privy)|
+--------+---------+
|
v
+-------------------------------+
| TEE Attestor |
| (Trusted Execution Env) |
| |
| - Session management |
| - KYC orchestration |
| - ZK proof generation |
| - Document encryption |
| - Rollup submission |
+---+----------+----------+-----+
| | |
+--------+ +-----+-----+ +-+----------+
v v v v v
+--------+--+ +-----+-----+ +----+--+--+ +-------+------+
| KYC | | IPFS | | Cartesi | | Arbitrum |
| Provider | | (Pinata) | | Rollup | | (L2) |
| (Smile ID | +-----------+ +----------+ +--------------+
| or Plaid) |
+------------+
Component Roles
Frontend (Next.js + Privy)
The frontend is a Next.js application that provides the user interface for the verification flow. It handles:
- Wallet connection via Privy Auth, supporting multiple wallet types (MetaMask, WalletConnect, email, social login).
- Provider selection, allowing the user to choose between available KYC providers based on their jurisdiction.
- Session initiation, sending the user's DID and chosen provider to the attestor.
- Status polling, displaying real-time verification progress to the user.
- Result display, showing the final verified/rejected status along with on-chain proof references.
The frontend never handles sensitive identity data. All PII flows directly between the user's device and the KYC provider's interface, with the attestor coordinating the session.
There are no protocol fees for end users.
TEE Attestor
The attestor is the central orchestration service and the most security-critical component in the architecture. It runs inside a Trusted Execution Environment (TEE), which provides hardware-level isolation. See TEE Attestor for a deep dive.
The attestor is responsible for:
| Function | Description |
|---|---|
| Session management | Creates and tracks verification sessions |
| KYC orchestration | Communicates with KYC provider APIs to initiate and monitor verification |
| Webhook reception | Receives verification results from providers via secure webhook endpoints |
| ZK proof generation | Uses zkFetch with TLS tunnels to generate 14 zero-knowledge proofs per verification |
| Document encryption | Encrypts document references before IPFS storage |
| Metadata extraction | Extracts non-PII metadata (status, provider, country, timestamp) from provider responses |
| Rollup submission | Submits attestation data to the Cartesi rollup for on-chain recording |
KYC Providers
zkIdentity integrates with external KYC providers that perform the actual identity verification:
- Smile ID: Covers 12+ African countries. Performs document verification (national ID, passport, driver's license) combined with biometric selfie matching. Returns structured verification results via webhook.
- Plaid: Covers US, UK, and EU. Performs financial identity verification using banking credentials. Returns identity match results via webhook.
Providers are treated as black boxes by the system. The attestor only needs the provider's webhook response to generate proofs. The user's PII is handled entirely within the provider's infrastructure.
IPFS (Pinata)
Encrypted document references are stored on IPFS through the Pinata pinning service. This provides:
- Decentralized storage that is not controlled by any single entity.
- Content addressing via CIDs (Content Identifiers) that ensure data integrity.
- Persistence through Pinata's pinning guarantees.
All data stored on IPFS is encrypted before upload. The encryption key is derived from the user's wallet, meaning only the user can decrypt their own document references.
Cartesi Rollup
The Cartesi rollup serves as the computation and storage layer for verification attestations. It runs a RISC-V Linux virtual machine and provides:
- Deterministic computation via the Cartesi Machine (a RISC-V VM).
- State management for all verification records.
- Input processing for new attestation submissions from the attestor.
- Voucher generation for on-chain state commitments to Arbitrum.
The rollup stores only non-PII metadata:
- Verification status
- Country code
- Verification level
- Provider name
- ZK proof
- Timestamp
It does NOT store: name, date of birth, ID numbers, photos, biometrics, address, or phone number.
Arbitrum (Settlement Layer)
Arbitrum L2 serves as the settlement layer where Cartesi rollup state commitments are anchored. This provides:
- Finality through Ethereum-equivalent security guarantees.
- Public verifiability of rollup state roots.
- Interoperability with other Arbitrum-based applications that may want to check verification status.
Data Flow
The complete data flow through the system follows these stages:
Stage 1: Initiation
- User connects wallet via Privy in the frontend.
- The DID is derived from the wallet's public key.
- User selects a KYC provider appropriate for their jurisdiction.
- Frontend sends a session creation request to the attestor containing the DID and selected provider.
Stage 2: Verification
- The attestor creates a session with the KYC provider and returns a verification URL or widget configuration to the frontend.
- The user completes the provider's verification flow directly (document upload, biometric capture, etc.).
- The provider processes the verification and sends the result to the attestor via webhook.
Stage 3: Proof Generation
- The attestor uses zkFetch to establish a TLS tunnel to the provider's API and fetch the verification result.
- zkFetch generates 14 ZK proofs attesting to the authenticity and content of the provider's response.
- The attestor extracts non-PII metadata from the response.
Stage 4: Storage and Attestation
- Document references are encrypted and uploaded to IPFS via Pinata.
- Non-PII metadata, proof hashes, and the IPFS CID are packaged into an attestation.
- The attestation is submitted as an input to the Cartesi rollup.
- The rollup processes the input and updates its state.
- Rollup state is periodically committed to Arbitrum.
Stage 5: Completion
- The frontend polls the attestor for session status.
- Once the attestation is confirmed, the user sees a "Verified" status.
- The verification is now publicly verifiable on-chain.
Security Boundaries
The architecture enforces several critical security boundaries:
| Boundary | Enforcement |
|---|---|
| PII isolation | PII never leaves the TEE; only non-PII metadata is submitted on-chain |
| Encryption at rest | All IPFS-stored data is encrypted with user-derived keys |
| TEE integrity | Hardware attestation ensures the attestor code has not been tampered with |
| Provider isolation | Each provider integration is sandboxed within the attestor |
| Proof soundness | ZK proofs are cryptographically binding -- they cannot be forged |
Related Documentation
- ZK Proof System -- How the 14 ZK proofs are generated and verified.
- TEE Attestor -- Detailed documentation of the trusted execution environment.
- DID Model -- How decentralized identifiers are derived from wallets.