Deep dive
FIVUCSAS (Face and Identity Verification Using Cloud-based SaaS) started as a three-person Marmara University senior project (CSE4297/CSE4197) and now ships under RollingCat Software. I led it and built the Spring Boot 3 / Java 21 identity core, the React 18 web app, the ML integration, and the infrastructure. Ayşenur Arıcı built the anti-spoofing and liveness ML algorithms. Ayşe Gülsüm Eren worked across the Kotlin Multiplatform mobile and desktop apps, liveness tuning, the gesture-analysis module, NFC passport reading, and UX. For a deeper technical walkthrough, see the companion write-up.
The shape of the system
Two constraints drove most design decisions: biometric data must never sit unencrypted at rest, and embedding extraction must never be reachable from the public internet.
Those constraints are why the ML stack lives in a separate FastAPI sidecar on a private Docker network rather than inside the Spring Boot API. The identity core is the authoritative source of truth for tenants, users, sessions, audit logs, and MFA factors (TOTP, WebAuthn, NFC, biometric). The biometric processor owns the face mesh, embedding extraction, and active-liveness puzzle scoring, and it answers only to the API, never to a browser.
Active liveness
The “Biometric Puzzle” prompts a randomized sequence of facial actions (smile, blink, look left, look right) rather than accepting a single still frame that a photo or screen replay could defeat. The randomization makes a pre-recorded attack impractical because the attacker cannot know the sequence in advance. The widget exposes this flow the way reCAPTCHA exposes a challenge, so a tenant integrates against the smallest possible surface. Active liveness is flag-gated.
Tenancy and privacy
Multi-tenancy uses a shared schema with PostgreSQL Row-Level Security (RLS) and a Hibernate @Filter, backed by tenant_id columns on every tenant-scoped table. Both layers must agree before a query can reach another tenant’s data.
Face embeddings are encrypted with Fernet at rest in pgvector and decrypted in-process only at the moment cosine similarity runs. The application refuses to start without the embedding encryption key, so it can never silently fall back to an invalid state.
Operational posture
The platform runs on a Hetzner CX43 box behind Traefik, observed with Loki, Promtail, and Grafana, with nightly encrypted database backups. Security hygiene is part of the workflow: GitHub secret-scanning with push-protection is on, and every new OAuth endpoint gets a permitAll-chain review as part of PR review.
The source is private until a third-party security review completes. Source access is available on request.