Skip to main content

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:

FunctionDescription
Session managementCreates and tracks verification sessions
KYC orchestrationCommunicates with KYC provider APIs to initiate and monitor verification
Webhook receptionReceives verification results from providers via secure webhook endpoints
ZK proof generationUses zkFetch with TLS tunnels to generate 14 zero-knowledge proofs per verification
Document encryptionEncrypts document references before IPFS storage
Metadata extractionExtracts non-PII metadata (status, provider, country, timestamp) from provider responses
Rollup submissionSubmits 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

  1. User connects wallet via Privy in the frontend.
  2. The DID is derived from the wallet's public key.
  3. User selects a KYC provider appropriate for their jurisdiction.
  4. Frontend sends a session creation request to the attestor containing the DID and selected provider.

Stage 2: Verification

  1. The attestor creates a session with the KYC provider and returns a verification URL or widget configuration to the frontend.
  2. The user completes the provider's verification flow directly (document upload, biometric capture, etc.).
  3. The provider processes the verification and sends the result to the attestor via webhook.

Stage 3: Proof Generation

  1. The attestor uses zkFetch to establish a TLS tunnel to the provider's API and fetch the verification result.
  2. zkFetch generates 14 ZK proofs attesting to the authenticity and content of the provider's response.
  3. The attestor extracts non-PII metadata from the response.

Stage 4: Storage and Attestation

  1. Document references are encrypted and uploaded to IPFS via Pinata.
  2. Non-PII metadata, proof hashes, and the IPFS CID are packaged into an attestation.
  3. The attestation is submitted as an input to the Cartesi rollup.
  4. The rollup processes the input and updates its state.
  5. Rollup state is periodically committed to Arbitrum.

Stage 5: Completion

  1. The frontend polls the attestor for session status.
  2. Once the attestation is confirmed, the user sees a "Verified" status.
  3. The verification is now publicly verifiable on-chain.

Security Boundaries

The architecture enforces several critical security boundaries:

BoundaryEnforcement
PII isolationPII never leaves the TEE; only non-PII metadata is submitted on-chain
Encryption at restAll IPFS-stored data is encrypted with user-derived keys
TEE integrityHardware attestation ensures the attestor code has not been tampered with
Provider isolationEach provider integration is sandboxed within the attestor
Proof soundnessZK proofs are cryptographically binding -- they cannot be forged
  • 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.