
“The record is worth as much as the event.”
Identity verification for the German financial market
A KYC system with liveness checks of both the person and the document, where the model gives a reliable proposal in about 98% of cases — and an operator confirms every decision. The product was sold at MVP stage.
A German financial organization opens accounts remotely, and German regulation requires video identification with a record that survives a review years later. The system takes an applicant through seven steps and asks for proof of liveness from two sides — the person and the document.
Four of the seven steps are randomized per session: prescribed document rotations, a finger on the edge, five spoken digits, head movements. A recording cannot be prepared in advance or replayed. Three document types are checked, and passports and ID cards are read off the NFC chip — cryptographically signed, instead of guessing the data off an image.
The model gives a reliable proposal in about 98% of cases, but a named operator confirms the decision — the system was built to support a decision, not to automate it. The product was sold at MVP stage.
The problem
The constraint
What we did
Randomness as the principle — no session can be staged
Seven steps: face photo, document photo, video with prescribed rotations, finger on the edge, five random numbers, selfie video with random head movements. Nothing can be pre-recorded or replayed.
7 steps, randomized per sessionLiveness for both the person and the document
TensorFlow in the browser tracks the face and gestures — recording starts only with the face in frame. Rotation and the finger prove the document is physical; the NFC chip in passports and ID cards yields cryptographically signed data through our native module (Java, Swift, Turbo Modules).
Passports and ID cards off the NFC chipBiometrics under the user’s key
Unlocked only while processing runs, then moved to a separate bucket under a user- or admin-held key — out of the team’s reach. Encrypted requests, single-use tokens, external penetration testing.
Model 98% — an operator confirms every decision
Seven steps, four of them randomized per session: face and document photos, a video with prescribed rotations, a finger gesture on the edge, five random numbers, a selfie with head movements. TensorFlow in the browser tracks the face — recording starts only once the face is in frame.
The result
Seven steps here were a regulatory requirement, not a UX decision — designing such a flow is a trade between friction and proof.
What we’d do differently
We would log operator access from day one. A decision has to be attributable to a named person, and that means a record of who saw what — not only of who confirmed what.
We would write the chip-reading module once. Java for Android and a Swift rewrite for iOS mean two implementations of the same regulation, and two places to change when the regulation changes.
- TensorFlow
- WebRTC
- Node.js
- Express
- PostgreSQL
- AWS S3
- NFC / ICAO 9303
- React Native / Turbo Modules
- Java
- Swift