Technical Document

Security Architecture Whitepaper

Version: Draft 1.0 · Scope: the security architecture, threat model and verifiability guarantees of the zero-knowledge Turkish digital identity verification platform.

This document is based on the architecture of the product's actual codebase. It aims for defensible engineering facts, not marketing language.

1. Summary

VerifyBlind is a verification system that proves a person holds a real, live, NFC-chip-verified identity without disclosing their identity data to any integrating partner — or to the VerifyBlind infrastructure itself.

The principle at the heart of the design is this: sensitive identity data never leaves the path between the user's device and the AWS Nitro Enclave (a hardware-isolated, verifiable compute environment). The partner receives only the minimum verification result (e.g. age: 18+, a pseudonymous code).

This document describes the cryptographic design, the hardware root of trust (Nitro attestation + PCR0 version verification), NFC identity authentication, biometric liveness checking, session/ticket security, client integrity and build verifiability.

2. Design Principles

  1. Data minimisation / zero-knowledge: the partner learns not "who you are", but only whether the specific verification proposition it asked is true. Identity data is never transmitted to the partner.
  2. Isolation: all cryptographic decryption and identity-processing steps happen only inside the Nitro Enclave. The network-facing relay service (API) cannot see or store plaintext identity data.
  3. Verifiability: which enclave code is running is cryptographically proven by the PCR0 measurement in the attestation document; the integrity of the client apps is tested via platform attestation.
  4. No retention: VerifyBlind does not persistently store raw identity/biometric data; it keeps only the identity-non-revealing records needed for auditing (see §12).

3. System Architecture

  Mobile App                    Relay (API)                Enclave (Nitro)
  (Android / iOS)               :5102, network-facing      isolated, /dev/nsm
  ───────────────              ─────────────              ────────────────
  NFC ID read          ──TLS──►  routing/                    decryption,
  liveness (face)                rate limiting,              NFC verification,
  encryption (on device)         nonce/state (Redis),        biometrics, liveness,
                                 audit/log                   ticket signing (MAC)
                                       │
                                       ├── PostgreSQL 15
                                       └── Redis 7 (nonce/state)

  Partner Website ──► verifyblind.js widget ──► Relay (result channel)
  • Relay (ASP.NET 9): the only network-facing component. A bridge between mobile, partner and enclave; rate limiting, nonce/state management (Redis), audit logging and webhook delivery. It never sees plaintext identity data — the payload sent to the enclave is already encrypted on the device.
  • Enclave (ASP.NET 9, ARM64/Graviton): runs inside an AWS Nitro Enclave. In production it is connected to the outside world only over vsock; its RAM is hardware-isolated from the host machine (parent EC2). All sensitive cryptography happens here.
  • Data layer: PostgreSQL 15 (audit, consent, verification logs, nonce ledger) + Redis 7 (short-lived nonce/state, atomic replay protection).
  • Clients: Android (com.verifyblind.mobile) and iOS (app.verifyblind.ios) mobile apps; a browser widget for partners (verifyblind.js) and Android and iOS SDKs.

4. Threat Model

VerifyBlind rejects the assumption that "the partner is honest and the infrastructure is secure". The principal attacker profiles it defends against:

#AttackerGoalDefence
T1Malicious/curious partnerLearn the user's national ID number (TCKN)Data minimisation; TCKN never reaches the partner (§2, §12)
T2Network eavesdropper / MITMRead data in transitTLS + end-to-end hybrid encryption (§5)
T3Attacker who seizes the relay/parent EC2 shellHarvest plaintext identity / forge ticketsNitro isolation + attestation; in-enclave HMAC; attestation-bound KMS trust (§6, §8, §10)
T4Fake/cloned ID cardPass verification with an invalid identityPassive Authentication (CSCA+CRL+DG hash) + mandatory Active Authentication (§7)
T5Presentation attack (photo/mask/screen)Bypass the liveness checkMove sequence + biometric match on every frame + passive anti-spoof (§7)
T6Holder of a leaked/stolen ticketPass verification with someone else's ticketHolder-of-key signature + live face at every verification (§8)
T7Replay attackerReplay a valid requestSingle-use nonce + atomic Redis Lua + nonce ledger (§8)
T8Fake/modified client appA forged flow from an emulated devicePlay Integrity / App Attest (§9)
T9Supply chain / malicious enclave versionRun a backdoored enclaveDeveloper-signed PCR0 verification (§6)

5. Cryptographic Design

5.1 Hybrid encryption (device → enclave)

The mobile app encrypts the sensitive enrolment payload (NFC data groups, selfie, etc.) on the device:

  • Content: AES-256-GCM (confidentiality + integrity/AEAD).
  • Key wrapping: the one-time AES key is wrapped with the enclave's public key using RSA-OAEP-SHA256 (MGF1-SHA256).
  • Decryption happens only inside the enclave; the relay cannot unwrap the wrapped key.
Platform note: for Android Keystore TEE compatibility, some on-device operations use OAEP-SHA1/MGF1-SHA1; for enclave- and partner-directed encryption, OAEP-SHA256/MGF1-SHA256 is the standard.

5.2 Signing

Signatures are produced with RSA-PSS (SHA-256, MGF1-SHA256, 32-byte salt length). This is used in the holder-of-key proof (§8) and the related signature paths.

5.3 Partner result channel (browser widget)

The browser-side verifyblind.js generates a one-time (ephemeral) RSA-OAEP key pair via the Web Crypto API. Its public key is relayed to VerifyBlind through the partner backend; the result comes back encrypted with this ephemeral public key and can be opened only with the private key held in that browser session. The partner's API key never reaches the browser (it stays at the server-side "nonce" end).

6. Hardware Root of Trust: AWS Nitro Enclave + PCR0

6.1 Isolation

The enclave runs in a hardware-isolated memory region, separate from the host machine (parent EC2). The parent machine's operating system (and any attacker who seizes it) cannot read the enclave's RAM. The enclave speaks to the outside world only over a narrow vsock channel.

6.2 Attestation and PCR0 version verification

The Nitro Security Module (NSM) produces an attestation document containing measurements of the running enclave image. This document is signed by AWS Nitro hardware, and its certificate chain roots in AWS's root authority — meaning it can be cryptographically verified that the document truly came from a Nitro enclave. VerifyBlind verifies the PCR0 (enclave image measurement) value in the document to be signed with the VerifyBlind developer key:

  • The mobile app verifies the attestation document and the developer signature supplied for its PCR0 with the developer public key embedded in the app. No identity data is sent to an enclave version without such a signature (T9).
  • The relay serves the signatures of the live enclave version and the previous one.
  • Partners can run the same check: the attestation document and the PCR0 signature come with the verification result, and the developer public key is published at /api/public/developer-key.

7. Identity Proof: NFC + Biometrics + Liveness

7.1 NFC Passive Authentication

The ID card's data groups (DGs) and its signed security object (SOD) are verified inside the enclave:

  • CSCA + CRL verification: the country signing certificate authority chain that signed the card is verified; revocation lists (CRLs) are checked. The relevant root certificates and revocation lists are embedded in the enclave.
  • DG hash binding (DG1 + DG2 + DG15): the hashes of the read data groups are verified against the signed LDSSecurityObject in the SOD. DG2 (the face) is mandatory and is bound slot-wise against the SOD — that is, the verified face is an inseparable part of the card's signed content.

7.2 NFC Active Authentication

The card signs a challenge with its internal private key; this proves that the chip is a genuine, un-cloned physical card. In VerifyBlind this check is mandatory: if DG15 or the active signature is missing/incorrect, verification is rejected.

7.3 Biometric match

The face embedding vector extracted from the user's live selfie (an ArcFace-based face embedding model) is compared against the DG2 face on the card via cosine similarity. This comparison runs at enrolment and again at every later verification (§8.4). The real security gate is inside the enclave (the threshold is enforced on the enclave side); the threshold on the phone side is only a pre-check for user experience and, even if bypassed by an attacker, does not break security.

7.4 Passive liveness (anti-spoof)

A passive presentation-attack (anti-spoof) detection runs on the selfie inside the enclave; if the liveness probability is below the threshold, verification is rejected. This is the security gate enforced on the enclave side against presentation attacks such as photo/screen/mask.

7.5 Active liveness (move sequence)

The user holds the phone at a single, comfortable distance and makes short moves: a blink, a smile, opening the mouth and a double blink. Which moves are asked, and in which order, is derived from the operation's nonce; the client cannot choose the sequence.

  • When adding a card: five moves; the same move never comes twice in a row.
  • At every verification: one move (a smile, opening the mouth or a double blink).

The phone detects the move; for each move it sends a neutral frame and a move frame to the enclave. The enclave checks that the proof matches the requested sequence and that the face in every frame belongs to the card holder. A photo cannot make the moves, and making them with someone else's face fails the identity check.

8. Session / Ticket Security

After a successful enrolment, the enclave issues a signed Ticket stored on the user's device. Subsequent verifications (login) rely on this ticket. Four mechanisms stop the ticket from being a "bearer token":

8.1 Ticket-MAC (in-enclave HMAC) — against ticket forgery

The ticket's integrity is verified with a symmetric HMAC key held only inside the enclave. This key is encrypted with a KMS wrapping key (CMK) and stored in wrapped form; at every enclave startup it is unwrapped via an attestation-bound KMS decrypt operation — meaning only an enclave with the correct PCR0 measurement can decrypt the key. Thus the secret that verifies ticket integrity never leaves the enclave.

8.2 Holder-of-key — against stolen tickets

The ticket owner's key pair is generated on the device during enrolment. On Android the private key is held in Android Keystore (in the hardware-protected area, TEE, on devices that support it); on iOS it is held in the Keychain, bound to that device only. It is not included in backups or moved to other devices, and it can be used only after the user approves with biometrics or the screen lock.

The owner's public key is carried inside the ticket, within the MAC scope. At login the device signs a login-specific canonical message (nonce + key fingerprint + timestamp) with that private key, using RSA-PSS/SHA-256; the enclave verifies this signature against the MAC-verified public key, within a narrow time window. Result: a leaked ticket cannot be used by anyone who does not also hold its corresponding private key (T6).

8.3 Nonce / replay protection

Every flow is bound to a single-use nonce. Spending the nonce is done as an atomic operation, so two requests racing for the same nonce (TOCTOU) are prevented. A separate nonce ledger is kept for durable auditing (T7).

8.4 Live face at every verification

At enrolment, the face photo extracted from the SOD-verified DG2 is sealed into the ticket within the MAC scope. At every verification the enclave compares the live frame from the phone with this reference, runs the passive anti-spoof check and verifies the one-move sequence (§7.5). If any check fails, the verification is rejected. The goal is to stop someone who can unlock the phone from verifying on the card holder's behalf.

9. Client Integrity: Play Integrity / App Attest

The enrolment and verification flows carry a platform attestation that the request comes from the genuine, untampered VerifyBlind mobile app:

  • Android: app and device integrity, and the app's signing certificate, are verified via the Google Play Integrity API.
  • iOS: Apple App Attest (challenge → enroll → assertion; the CBOR + X.509 chain is verified to the Apple Root CA, with an ECDSA assertion and a strictly increasing counter for replay resistance).
  • Routing is done per platform (iOS → Apple App Attest, other → Play Integrity).
Note: this attestation guarantees the request comes only from the genuine VerifyBlind mobile app, and it is enforced by the relay.

10. Parent Isolation and KMS Key Trust

Nitro isolates the enclave's RAM from the parent; however, the enclave obtains its AWS credentials from the parent's IMDS vsock-proxy → at the IAM level, the enclave and the parent are indistinguishable. The only distinguishing factor is attestation. KMS usage is designed to preserve security even if the parent is compromised:

  1. KMS connection: on the enclave↔KMS connection, the TLS certificate chain and hostname match are strictly verified. Even if the parent is seized and network traffic is redirected to the attacker, a rogue endpoint cannot present a valid KMS certificate, so the sensitive data being processed cannot be exfiltrated.
  2. Ticket integrity: the ticket is signed and verified with an in-enclave symmetric HMAC (signer = verifier = enclave). The wrapping key is unwrapped only via an attestation-bound decrypt operation; the production role holds only minimal, key-scoped permissions — it has no authority to sign tickets, create keys or change key policy. The HMAC secret that produces the pseudonymous codes (user_id, nsbd_id, doc_id) is likewise stored wrapped by KMS, unwrapped only inside the enclave via an attestation-bound decrypt, and the codes are computed inside the enclave → even an attacker who seizes the partner database cannot reverse user_id back to a TCKN.

11. Operational Security

  • Audit logging: every verification operation is written to the audit log and event stream without revealing identity.
  • Monitoring and incident response: infrastructure and administrative events are logged centrally and raise alerts on anomalies. A ready incident process exists to cut off access, rotate secrets and collect immutable evidence during a security event.
  • Backup / recovery: database backups are stored encrypted and version-protected; restore is drilled regularly.

12. KVKK / Data Minimisation

  • No identity data reaches the partner and none is stored by VerifyBlind.
  • The partner receives only the result of the proposition it asked and, if requested, pseudonymous codes:
    • user_id — a TCKN-derived pseudonymous code (to recognise a returning person without storing them);
    • nsbd_id — a biographic person bucket (stable even across card renewal);
    • doc_id — a document-based fixed code.
    These codes give the partner duplicate-account detection and continuity without revealing identity. All three codes are derived partner-scoped: the same person receives different codes at two different partners. This prevents cross-partner correlation — codes at one partner cannot be matched to the same person at another partner.
  • KVKK infrastructure: explicit consent records, data-subject requests (access/erasure/portability/objection/rectification), breach log, table-based retention rules.
  • Outcome: because the most sensitive personal data (TCKN, ID photo) is never transmitted to the partner and never persistently stored anywhere, the partner's data-processing burden and risk surface under KVKK are markedly reduced. (Final compliance depends on the partner's processing purpose; this document is not legal advice.)

13. Verifiability

VerifyBlind's core stance is not "trust us" but "verify the math": which code the system runs can be independently tested.

  • Enclave — reproducible build + attestation (the core guarantee): the enclave source code is open (github.com/VerifyBlind/VerifyBlind-Enclave). The enclave image compiled from this source produces a deterministic PCR0 fingerprint — if even a single character in the code changes, PCR0 changes entirely. An independent auditor can: (1) clone the source, compile it and note the resulting PCR0; (2) obtain the live attestation document, signed by AWS Nitro hardware, from the running system (§6); (3) compare the two PCR0s. If they match, the enclave running in production is exactly that published code. Thus the claim "VerifyBlind cannot see/store raw data" rests not on a promise but on a measurement anyone can reproduce. In addition, the enclave "seals" the key it generates at each startup into the attestation document → a document belonging to an old/other enclave cannot be replayed.
  • Android — reproducible build: every release is built on GitHub Actions from the public source commit (github.com/VerifyBlind/VerifyBlind-Android), and the same commit is built a second time to confirm that the code (DEX) files come out identical. Public verification scripts compare the DEX files of the app on the phone with the hash list published for that release. It can also be tested via Play "code transparency" (bundletool check-transparency).
  • iOS — build provenance: the FairPlay encryption in App Store distribution prevents the binary from being verified by bit-for-bit reproduction from the device. Instead, every release is built on GitHub Actions from the public source commit (github.com/VerifyBlind/VerifyBlind-iOS) and published with Sigstore-signed build provenance. Public verification scripts for Windows, macOS and Linux compare the published IPA's hash with the release manifest and verify the provenance record with cosign. That the app on the device is the genuine App Store build is checked by the server with App Attest on every protected request (§9).

These mechanisms are explained step by step, in plain language for end users, on the transparency and zero-knowledge pages.

14. Glossary

TCKN
Turkish national identity number.
Enclave / Nitro Enclave
A verifiable compute environment, hardware-isolated from the host machine.
Attestation
A hardware-signed document containing measurements of the running code.
PCR0
The enclave image measurement; the cryptographic answer to "which code is running".
NFC Passive Authentication
Verifying the card's data against the country CA's signature.
NFC Active Authentication
The chip proving it is not a clone by signing a challenge with its private key.
Holder-of-key
The presenter of a ticket proving, by signature, that they also hold the private key bound to the ticket.
Ticket-MAC
Verifying ticket integrity with a symmetric HMAC known only to the enclave.
Nonce
A single-use random value that prevents replay.

This document is a draft and will be updated as the product evolves.