Work / Enterprise · Security / Facial Surveillance

CAM 01 · Live · Enterprise · Security

Watch the door.
Rotate the keys.
Sleep at night.

A production facial recognition surveillance system. Multi-database. AES-256 face encodings, Argon2 password hashes, keys that rotate themselves every 90 days. No human in the loop. No downtime when they roll over.

Built by Kaustuv Sharma · Under dmj.one
3Databases · auto-fallback
90 dKey rotation cadence
24 hGrace window per rollover
0.6Default match confidence
3 OSWin · Linux · macOS

Act I · The Problem

Most surveillance fails the second year.

The camera works. The model works. The launch demo works. Then a key expires, and nobody knows where it lives. A database goes down, and there's no fallback. A junior rotates a secret, and last quarter's footage decrypts to noise. Production-grade is not the recognition. It is everything around it.

Act II · The Foundation

One install.
Three real databases.

Pick the database your operations team already runs. The system detects what is available, falls back when it has to, and never asks the operator to choose at install time.

Priority Database Use case Status
i. PostgreSQL Production. Multi-tenant deployments, audit-heavy workloads, write-heavy logging. Recommended
ii. MySQL Production alternative for shops already standardised on MySQL or MariaDB. Supported
iii. SQLite Development laptop, single-camera kiosk, air-gapped pilot. Zero-config fallback. Default

Act III · The Key Lifecycle

Keys that look after themselves.

Every key the system uses is generated, encrypted, rotated and retired without a human on the keyboard. The PBKDF2-derived master key wraps everything else. Old data still decrypts during rollover. New data uses the new key the moment it is born.

  1. Day 0 First boot. key_manager.init() generates a fresh data-encryption key. Stored encrypted on disk by a master key derived with PBKDF2. No prompt. No human secret to lose.
  2. Day 1 to 89 Face encodings encrypted with Fernet (AES-128-CBC + HMAC-SHA256 under the AES-256 envelope). Passwords hashed with Argon2id. bcrypt → scrypt automatic fallback if Argon2 is missing on the host.
  3. Day 90 Rotation triggers. New key generated. force_rotation() available on demand. Old key stays valid for the next 24 hours: a grace period long enough for any in-flight write to settle.
  4. Day 91 All new writes use the new key. Existing rows can be re-encrypted from the UI in the background. Audit log records every step. Zero downtime.

Act IV · The Product

Four modules.
One verifiable install.

Module · core

Config, key manager, security primitives.

Configuration via env vars or a `.env` file. Rate limiting on the request path. Input sanitisation against SQL injection and XSS at every boundary.

src/core/{config,key_manager,security}.py

Module · database

Connection pool with auto-fallback.

One connection layer, three drivers. Health-checked at boot. Queries are parameterised. Schemas migrated by the manager itself, no manual SQL on first run.

src/database/{connection,manager}.py

Module · recognition

Live video processing engine.

Frame capture, detection, embedding, match. Default match threshold 0.6, configurable via `FR_MIN_CONFIDENCE`. Visitor logs include confidence per recognition.

src/recognition/processor.py

Surface · streamlit

One web app. Run anywhere.

`run.bat` on Windows. `run.sh` on Linux and macOS. Optional `install_service.sh` registers it as a systemd unit. Lives at http://localhost:8501.

app.py · run.bat · run.sh · install_service.sh

The Stack

Boring choices, on purpose. Built to outlast the launch demo.

  • Python 3.8+
  • Streamlit 1.28+
  • PostgreSQL · MySQL · SQLite
  • Fernet · AES-256
  • Argon2id · bcrypt · scrypt
  • PBKDF2 master key
  • pytest + coverage
  • GitHub Actions CI
  • systemd unit
  • MIT (attribution)

Act V · Proof

Production-grade, on the label and in the code.

CI · GitHub Actions

Pipeline at `.github/workflows/ci.yml` runs the full pytest suite on every push. Tests cover key management, security primitives, database connections and configuration loading.

Cross-platform launchers

`run.bat` for Windows, `run.sh` for Linux and macOS. `install_service.sh` registers a systemd unit so the recognition service comes up with the box.

Audit trail by default

Every security event written to the audit log: key rotations, failed matches, rate-limit trips, configuration changes. Nothing happens silently inside the system.

Re-encrypt without downtime

The 24-hour grace window means a rolled key never strands historical data. Optional one-click re-encryption migrates older rows to the current key from the UI.

If your surveillance still ships with a static secret in a `.env`, upgrade the foundation, not the camera.

I build production security software the way operations teams want it: rotated keys, real fallbacks, audit trails, and one launcher per OS. Hire dmj.one for the parts of security you cannot demo.