FaceAppFace Recognition with Liveness & Geofencing
University attendance is trivially cheatable — a friend signs you in, a photo fools the camera, a VPN fakes your location. FaceApp is a defence-in-depth answer built entirely on commodity hardware: eight independent verification layers, no infrared, no depth sensor, no GPU.
The problem
Roll-call, paper sheets, smart cards and QR codes all share one flaw: they verify a token, not a person. Adding face recognition alone just moves the attack — a printed photo, a phone screen, or an OBS virtual camera defeats naive verification. And even a perfect face check says nothing about whether the student is actually in the room.
The approach
I built a three-tier polyglot system: Rails 8.1 owns authentication and persistence, a Flask 3.0 service hosts the verifier and the ONNX Runtime inference path, and a single shared secret binds the trust boundary. Identity comes from 512-dimensional InsightFace buffalo_l ArcFace embeddings at a calibrated 0.45 cosine threshold. Liveness fuses an active randomised head-pose challenge with passive MediaPipe landmarks, a MiniFASNet anti-spoof CNN, FFT screen-artefact analysis, depth-motion and camera-authenticity heuristics — plus a wrong-action fast-fail that rejects an attack inside a single frame. Location is bound cryptographically: an HMAC-SHA256 token fusing student ID, GPS, a nonce and an expiry, validated independently at both the Flask issuer and the Rails consumer, with a haversine geofence.
The outcome
1.8% equal-error rate over 300 verification trials. Across 350 presentation attacks in seven categories: printed photo 99.3% blocked, wrong-action 99.6%, tablet replay 97.1%, phone replay 96.7%, virtual camera 94.4%, paper mask 92.5% — roughly 96% aggregate. Per-frame liveness runs in 32.5ms on an Apple M2 with no GPU. All 1,000 tokens validated; tamper, replay and forged-GPS attempts were rejected 100% of the time. A 14-day pilot recorded zero successful proxy attempts. Graded 92 — Distinction.