AG
TR

// writing / May 5, 2026

How FIVUCSAS is built: a multi-tenant biometric authentication platform

A technical note on the architecture of FIVUCSAS, covering multi-tenant RLS, the supported auth methods, refresh-token rotation, active liveness, and the team that built it.

FIVUCSAS (Face and Identity Verification Using Cloud-based SaaS) is a production multi-tenant biometric authentication platform and OAuth2/OIDC authorization server. It originated as a three-person Marmara University senior project (CSE4297/CSE4197). 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, later extracted into a standalone spoof-detector library. 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. The stack is Java 21, Spring Boot 3, FastAPI, React 18, Kotlin Multiplatform (Android and Desktop ship; iOS is Phase 2, blocked on Apple enrollment), PostgreSQL with pgvector, Redis, Flyway (85 migrations, V1 to V86), Traefik on Hetzner CX43, and Loki + Promtail + Grafana for observability.

Multi-tenancy

The platform uses a shared PostgreSQL schema with Row-Level Security (RLS) and a Hibernate @Filter. Every tenant-scoped table carries a tenant_id column. Both the database and application layers enforce the boundary; a query has to satisfy both before it can reach another tenant’s data. Backups are nightly encrypted database dumps.

Authentication

The identity core supports WebAuthn/FIDO2 passkeys, TOTP, email OTP, QR code, NFC, and biometric factors. Tokens are RS256-signed JWTs in production. Refresh tokens use hashed family revocation: each rotation stores only the hash of the new token, and a short reuse-grace window prevents flaky network retries from triggering a false family-revoke. The Marmara tenant’s default login flow is password plus one of EMAIL_OTP, TOTP, or QR_CODE. WebAuthn is one supported method among several, not the default first factor.

Active liveness

The “Biometric Puzzle” prompts a randomized sequence of facial actions (smile, blink, look left, look right). A single still frame can be defeated by a photo or screen replay; the randomized sequence makes a pre-recorded attack impractical. The feature is flag-gated. The ML sidecar (FastAPI) lives on a private Docker network and is never exposed to the public internet. 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 there is no silent fallback path. Model delivery to clients uses SHA-256 integrity checks, and a per-client pre-filter (quality gate plus compression) ensures the server only receives frames worth processing.

Security posture

GitHub secret-scanning with push-protection is on. Every new OAuth endpoint gets a permitAll-chain review as part of PR review. The source is private pending a third-party security review. Source access is available on request at ahmetabdullahgultekin@gmail.com.

  • architecture
  • biometric
  • postgres
  • webauthn