Skip to content

Deployment

The reference instance runs at https://kyc-server-production.up.railway.app:

PieceDetail
kyc-serverBuilt from server/Dockerfile; auto-deploys on push to main
PostgreSQLManaged service, wired via a DATABASE_URL reference variable
Volume at /dataVault blobs, attestation key, archive staging, face models
DomainRailway-managed TLS

Migrations apply automatically on boot (Alembic). The first verification after a fresh deploy downloads the InsightFace models (~300 MB) to the volume — slow once, cached forever.

Set as platform secrets (Railway variables, K8s secrets, etc.) — never in git:

VariableRequirement
VAULT_MASTER_KEY32 bytes base64. Back up offline immediately — loss = unrecoverable vault, by design
BAQSHI_API_KEYSComma-separated; one key per consuming product
WEBHOOK_SIGNING_KEYShare with webhook consumers out-of-band
ANTHROPIC_API_KEYEnables Claude document inspection; with neither AI key set everything routes to manual review (fail-safe)
GEMINI_API_KEYEnables Gemini document inspection (GEMINI_MODEL, default gemini-2.5-flash; force a provider with DOCUMENT_AI_PROVIDER)
DATABASE_URLPostgres in production (postgres:// URLs are auto-normalized)
PUBLIC_BASE_URL, HANDOFF_WEB_URLMust match your public domain — they’re baked into QR/handoff URLs

Generate keys properly:

Terminal window
python -c "import os,base64; print(base64.b64encode(os.urandom(32)).decode())" # master key
python -c "import secrets; print('bk_live_' + secrets.token_urlsafe(32))" # API key

The server is one container + Postgres + a persistent disk:

Terminal window
docker build -t baqshi-kyc server/
docker run -p 8000:8000 -v kyc-data:/data \
-e DATABASE_URL=… -e VAULT_MASTER_KEY=… -e BAQSHI_API_KEYS=… \
-e PUBLIC_BASE_URL=https://kyc.example.com \
-e HANDOFF_WEB_URL=https://kyc.example.com/v \
baqshi-kyc

Requirements: Python 3.12 base (already in the Dockerfile — 3.14 lacks onnxruntime wheels), ~2 GB RAM for the face models, CPU-only is fine at moderate volume.

Local development:

Terminal window
cd server
python3.12 -m venv .venv && . .venv/bin/activate
pip install -e ".[dev,face]" # drop `,face` for a lighter install (fail-safe mode)
uvicorn app.main:app --reload # SQLite + auto-generated dev keys
  • TLS on a real domain; update the two URL variables
  • Master key backed up offline; consider KMS/HSM (see Keys)
  • ANTHROPIC_API_KEY or GEMINI_API_KEY set
  • CDN/WAF in front for volumetric protection (app-level limits are per-instance)
  • Postgres backups enabled (the DB is PII-light, but it holds the wrapped keys — losing it strands the vault as surely as losing the master key)
  • Archival job scheduled (Archival & erasure)
  • Monitoring wired (Monitoring)
  • Calibration run done (Fraud signals)