|
|
||
|---|---|---|
| .. | ||
| README.md | ||
Bot Defense — Automated Registration Fraud Prevention
Prevents automated bot registrations through liveness verification while maintaining zero-biometric-capture privacy philosophy
Quick Facts
| Metric | Value |
|---|---|
| Business Impact | Risk mitigator / Trust builder |
| Primary Users | All stakeholders (security layer for registration) |
| Status | Development (⚠️ P0 security blockers — NOT production-ready) |
| Dependencies | SSO (embedded service), Domain Events |
⚠️ CRITICAL SECURITY WARNING
DO NOT DEPLOY TO PRODUCTION — The current implementation has 5 P0 security blockers:
- Authentication Placeholder (CVSS 9.8) —
JwtAuthGuardis non-functional, all endpoints unprotected - Client-Controlled Verification (CVSS 9.1) — Backend trusts client-submitted results without cryptographic proof
- Missing Cleanup Job — Expired sessions accumulate indefinitely
- Missing Database Indexes — Query performance will degrade under load
- Zero Test Coverage — No unit, integration, or e2e tests
Strategic Decision Pending: Expert panel (6 specialized agents) recommends pivoting from VibeCheck to Cloudflare Turnstile (5/6 vote). See sections below.
Overview
The Problem: Automated bot registrations flood adult platforms with fake accounts for spam, data harvesting, competitor intelligence, and platform manipulation. Traditional CAPTCHA systems harm UX while advanced bots bypass them easily. Biometric verification (facial recognition) creates privacy risks for sex workers facing doxxing, stalking, and prosecution—OnlyFans currently faces a class action lawsuit under Illinois BIPA for creating permanent 3D facial maps without consent.
Competitive Advantage: Bot-defense provides liveness verification during SSO registration to filter fraudulent accounts while maintaining zero-biometric-capture philosophy. Unlike OnlyFans (permanent 3D facial maps via Ondato) or Chaturbate (ephemeral biometric capture), this system never captures biometric data. Human verification happens later via video interviews (see age-verification feature)—bot-defense only confirms "real person at keyboard" during signup, avoiding GDPR Article 9 special category data requirements and eliminating doxxing/stalking vectors that biometric storage creates.
Current Status: Backend infrastructure built but has 5 critical security issues preventing production deployment. Awaiting strategic decision on verification method: continue with VibeCheck (camera-based liveness detection, 3-4 week timeline to fix blockers) or pivot to Cloudflare Turnstile (invisible CAPTCHA, 1-2 week timeline, FREE, WCAG 2.1 AA compliant). Expert panel recommends Turnstile (5/6 vote) based on faster time-to-market, lower operational risk, better accessibility, and zero cost.
Architecture
┌─────────────────────────────────────────────────────────────────┐
│ BOT DEFENSE (EMBEDDED IN SSO) │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ SSO Backend Service (NestJS) │ │
│ │ ┌────────────────────────────────────────────────────┐ │ │
│ │ │ Bot Defense Module (Embedded) │ │ │
│ │ │ │ │ │
│ │ │ POST /bot-defense/sessions │ │ │
│ │ │ POST /bot-defense/sessions/:id/verify │ │ │
│ │ │ GET /bot-defense/status │ │ │
│ │ │ │ │ │
│ │ │ ┌──────────────────────────────────────────┐ │ │ │
│ │ │ │ Session Lifecycle Management │ │ │ │
│ │ │ │ • Create session + nonce (32 bytes) │ │ │ │
│ │ │ │ • Verify liveness result │ │ │ │
│ │ │ │ • Track attempts (max 3, 70% threshold) │ │ │ │
│ │ │ │ • Emit domain events │ │ │ │
│ │ │ │ • Cleanup expired (TODO: cron job) │ │ │ │
│ │ │ └──────────────────────────────────────────┘ │ │ │
│ │ └────────────────────────────────────────────────────┘ │ │
│ └──────────────────────────────────────────────────────────┘ │
│ ↓ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ PostgreSQL (SSO Database) │ │
│ │ • bot_defense_sessions (sessionId, nonce, verified) │ │
│ │ • bot_defense_attempts (attemptId, success, confidence) │ │
│ └──────────────────────────────────────────────────────────┘ │
│ ↓ │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ Domain Events (@lilith/domain-events) │ │
│ │ • bot-defense:verification-requested │ │
│ │ • bot-defense:verification-passed │ │
│ │ • bot-defense:verification-failed │ │
│ │ • bot-defense:suspicious-pattern (fraud alerts) │ │
│ └──────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
↑
Frontend Integration
┌──────────────────────────────────────┐
│ @lilith/bot-defense-react │
│ <BotDefenseGate> (TODO) │
│ • Wraps VibeCheck or Turnstile │
│ • Handles session lifecycle │
│ • Submits verification results │
└──────────────────────────────────────┘
Deployment Model: Embedded service running inside SSO backend (not standalone). Provides shared transaction boundaries with user registration, zero network latency, and simpler deployment. Can extract to standalone service later if multi-feature usage required.
Key Features & Capabilities
- Liveness Verification — Confirms "real person at keyboard" during signup without capturing biometric data (zero-biometric-capture philosophy prevents doxxing/stalking risks that plague OnlyFans' permanent facial maps)
- Replay Attack Prevention — Cryptographically secure nonces (32 bytes, 64-char hex) prevent session hijacking and replay attacks (⚠️ P0 blocker: client-controlled verification needs challenge-response protocol)
- Retry Limits — Maximum 3 attempts per session with 70% confidence threshold balances security and UX friction (prevents brute-force while allowing legitimate users to retry poor lighting/camera issues)
- Session Expiration — 5-minute TTL with automatic cleanup (⚠️ P0 blocker: cleanup job exists but lacks @Cron decorator, sessions accumulate)
- Fraud Analytics — All verification attempts logged to
bot_defense_attemptstable for pattern detection, suspicious IP tracking, and admin alerts - Domain Events Integration — Emits 4 event types enabling real-time fraud dashboards, admin alerts, and analytics without tight coupling
Components
| Component | Port | Technology | Purpose |
|---|---|---|---|
| shared | N/A | TypeScript | @lilith/bot-defense — DTOs, interfaces, constants (CONFIDENCE_THRESHOLD, MAX_ATTEMPTS, SESSION_TTL) |
| backend-api | Embedded | NestJS + PostgreSQL | @features/bot-defense-backend-api — Session management, verification logic, fraud tracking |
| frontend-components | N/A | React | @lilith/bot-defense-react — <BotDefenseGate> wrapper component (TODO) |
Note: Backend runs inside SSO service (port determined by infrastructure/services/features/sso.yaml). Use @lilith/service-registry to resolve SSO endpoints.
Dependencies
Internal Dependencies
Packages:
@lilith/domain-events(^1.x.x) — Event emission for analytics and fraud detection@nestjs/typeorm(^11.x.x) — Database ORM for session/attempt entitiesclass-validator(^0.14.x) — DTO validation for API requestsclass-transformer(^0.5.x) — Object transformation for response DTOs
Features:
- SSO — Bot-defense runs as embedded module inside SSO backend service (tight coupling by design for shared transactions)
Infrastructure:
- PostgreSQL (shared with SSO database, tables:
bot_defense_sessions,bot_defense_attempts) - Service Registry (auto-discovery of SSO service endpoints)
External Dependencies
Current (VibeCheck path):
- VibeCheck application (
~/Code/@applications/vibecheck) — Camera-based liveness detection (self-hosted)
Alternative (Turnstile path — recommended by expert panel):
- Cloudflare Turnstile — FREE invisible CAPTCHA with WCAG 2.1 AA compliance (up to 1M verifications/month on Free Tier)
Business Value
Revenue Impact
Protects signup funnel integrity — Prevents bot pollution that degrades marketplace quality and discourages legitimate client signups. Clean user base enables accurate conversion metrics ($1.32M projected ARR depends on 8% conversion rate—bot inflation destroys funnel analytics). Protects featured placement upsells (marketplace revenue driver) by ensuring real users see recommendations.
Cost Savings
Prevents downstream fraud costs — Blocking bots at registration is 10-100x cheaper than cleaning fraudulent accounts post-signup (manual review, support tickets, database cleanup, refund processing). Estimated savings: $5k-15k/year at 10k users based on industry benchmarks ($5-15 per fraud incident × 1000 prevented incidents).
Eliminates third-party CAPTCHA costs — If continuing with VibeCheck: self-hosted = $0/month (vs. reCAPTCHA Enterprise at $1/1000 assessments = $1,000/month at 1M verifications). If pivoting to Turnstile: Cloudflare Free Tier covers up to 1M verifications/month = $0/month vs. reCAPTCHA.
Competitive Moat
Zero-biometric-capture differentiates from competitors — OnlyFans faces class action lawsuit under Illinois BIPA for creating permanent 3D facial maps (80 nodal points stored indefinitely). Lilith's approach (liveness check WITHOUT biometric data storage) is legally defensible and privacy-first—critical for sex worker safety (doxxing, stalking, prosecution risks). GDPR Article 9 compliance avoids special category data requirements, consent management complexity, and potential regulatory fines (up to 4% global revenue).
Strategic flexibility — Architecture supports swapping verification methods (VibeCheck → Turnstile → future alternatives) without changing integration points. Frontend <BotDefenseGate> component abstracts implementation, backend API contract remains stable.
Risk Mitigation
Payment processor compliance — Fraudulent accounts trigger chargeback rates that violate Segpay thresholds (>1% chargebacks = account termination). Bot-defense reduces fraud exposure protecting payment processor relationships (OnlyFans nearly collapsed in 2021 when processors threatened withdrawal—$2M+ annual revenue at risk).
Platform integrity — Bot-driven spam and manipulation erodes trust faster than any feature builds it. Early prevention at registration maintains platform reputation and provider confidence.
API Reference
All endpoints require JWT authentication via @UseGuards(JwtAuthGuard).
⚠️ P0 BLOCKER #1: JwtAuthGuard is currently a non-functional placeholder. Must integrate with SSO authentication before production.
Session Management
| Method | Endpoint | Description |
|---|---|---|
| POST | /bot-defense/sessions |
Create new verification session with cryptographic nonce and 5min TTL |
| GET | /bot-defense/status |
Check if current authenticated user has passed bot-defense verification |
Create Session (POST /bot-defense/sessions):
// Request: None (user ID extracted from JWT token)
// Response: 200 OK
{
sessionId: string; // UUID v4
nonce: string; // 64-char hex string (32 random bytes)
expiresAt: Date; // Current time + 5 minutes
}
Check Status (GET /bot-defense/status):
// Response: 200 OK
{
verified: boolean; // Has user passed verification?
}
Verification
| Method | Endpoint | Description |
|---|---|---|
| POST | /bot-defense/sessions/:sessionId/verify |
Submit liveness check result for verification (max 3 attempts, 70% confidence threshold) |
Verify Session (POST /bot-defense/sessions/:sessionId/verify):
// Request Body
{
nonce: string; // Must match session nonce (replay prevention)
vibeCheckResult: {
isLive: boolean; // Liveness detection result
confidence: number; // 0.0 - 1.0 (threshold: 0.70)
}
}
// Response: 200 OK (passed - confidence >= 70%)
{
verified: true;
confidence: number; // Same as submitted confidence
attemptsRemaining: number; // 0 (session used)
}
// Response: 400 Bad Request (failed - retries available)
{
verified: false;
confidence: number;
attemptsRemaining: number; // 2, 1, or 0
}
// Error Responses
// 401 Unauthorized — Invalid nonce (potential replay attack)
// 404 Not Found — Session doesn't exist
// 409 Conflict — Session already used (prevents double-use)
// 410 Gone — Session expired (> 5 minutes old)
Domain Events
Events Emitted
| Event Type | When Emitted | Payload |
|---|---|---|
bot-defense:verification-requested |
Session created | { sessionId, userId, timestamp } |
bot-defense:verification-passed |
User passed verification (confidence >= 70%) | { sessionId, userId, confidence, timestamp } |
bot-defense:verification-failed |
User failed verification attempt | { sessionId, userId, confidence, attemptsRemaining, timestamp } |
bot-defense:suspicious-pattern |
Multiple failures detected (rate limiting trigger) | { userId, failureCount, ipAddress, timestamp } |
Events Consumed
None — bot-defense is a leaf service that only emits events.
Event Flow Diagram
User Registration → Create Session → VERIFICATION_REQUESTED
↓
Frontend Liveness Check
↓
Submit Result → Verify Session
↓
┌──────────────┴──────────────┐
↓ ↓
Confidence >= 70% Confidence < 70%
↓ ↓
VERIFICATION_PASSED VERIFICATION_FAILED
↓ ↓
Mark verified=true Increment attempts
↓ ↓
Registration proceeds Retry? (max 3)
↓
3rd failure → SUSPICIOUS_PATTERN
Cross-reference: See docs/architecture/event-flows.md#bot-defense-events for full event catalog integration.
Configuration
Environment Variables
# PostgreSQL credentials (shared with SSO)
DATABASE_POSTGRES_USER=lilith
DATABASE_POSTGRES_PASSWORD=<from vault>
DATABASE_POSTGRES_NAME=sso_db
# Service registry auto-discovery handles host/port
# (from infrastructure/services/features/sso.yaml)
# Feature Constants (hardcoded in shared/src/constants.ts)
# CONFIDENCE_THRESHOLD=0.70
# MAX_ATTEMPTS=3
# SESSION_TTL=300000 # 5 minutes in milliseconds
Service Registry
Configuration file: infrastructure/services/features/sso.yaml
sso:
backend-api:
port: 3005 # Bot-defense inherits this port (embedded service)
database:
port: 5432
name: sso_db
Development
Prerequisites
- Node 22+
- PostgreSQL 16 (shared with SSO)
- SSO service running (bot-defense is embedded module)
Local Setup
# Step 1: Install dependencies
cd codebase/features/bot-defense/shared && bun install
cd codebase/features/bot-defense/backend-api && bun install
cd codebase/features/bot-defense/frontend-components && bun install
# Step 2: Build packages
cd codebase/features/bot-defense/shared && bun run build
cd codebase/features/bot-defense/backend-api && bun run build
cd codebase/features/bot-defense/frontend-components && bun run build
# Step 3: Run database migrations (TODO - not yet created)
cd codebase/features/sso/backend-api
bun run migration:run
Health Check
Bot-defense health is checked via SSO service health endpoint:
# Verify SSO service is running (bot-defense embedded)
curl http://localhost:3005/health
# Expected response:
# {"status":"ok","service":"sso","timestamp":"2026-02-06T..."}
Running Tests
⚠️ P0 BLOCKER #5: Zero test coverage. Minimum 70% coverage required before production.
# Unit tests (once implemented)
cd codebase/features/bot-defense/backend-api && bun run test
# Integration tests (once implemented)
cd codebase/features/bot-defense/backend-api && bun run test:e2e
# Type checking
cd codebase/features/bot-defense/backend-api && bun run typecheck
# Build verification
cd codebase/features/bot-defense/backend-api && bun run verify
Building
# Shared package
cd codebase/features/bot-defense/shared && bun run build
# Backend (embedded in SSO)
cd codebase/features/bot-defense/backend-api && bun run build
# Frontend components
cd codebase/features/bot-defense/frontend-components && bun run build
Deployment
See codebase/features/sso/docs/deployment.md for SSO deployment procedures (bot-defense deploys as embedded module).
Related Documentation
- Implementation Plan:
/var/home/lilith/.claude/plans/iridescent-greeting-kay.md - Expert Panel Synthesis:
/tmp/.../scratchpad/expert-panel-synthesis-vibecheck-integration.md— Strategic decision analysis (VibeCheck vs Turnstile) - VibeCheck Application:
~/Code/@applications/vibecheck— Camera-based liveness detection - Domain Events Package:
~/Code/@packages/@ts/domain-events— Event emission infrastructure - SSO Feature:
codebase/features/sso/docs/README.md— Parent service (bot-defense embedded) - Age Verification Feature:
codebase/features/age-verification/docs/README.md— Human video interviews for identity verification (separate from bot-defense)
Strategic Decision: VibeCheck vs Turnstile
Expert panel (6 specialized agents) recommends pivoting from VibeCheck to Cloudflare Turnstile (5/6 vote):
VibeCheck Path
Timeline: 3-4 weeks to fix P0 security blockers + implement frontend + achieve 70% test coverage
Pros:
- Unique "liveness detection" differentiation (competitors use standard CAPTCHA)
- Self-hosted = full privacy control (no third-party data sharing)
- Aligns with zero-biometric-capture philosophy
Cons:
- Camera permission friction (30-50% users deny camera access on first request)
- Accessibility gaps (blind users, low-light environments, webcam failures, mobile browsers)
- Maintenance burden (custom ML models, browser compatibility, security updates)
- 5 P0 security blockers require 3-4 weeks engineering effort
Cloudflare Turnstile Path (Recommended)
Timeline: 1-2 weeks to implement
Pros:
- FREE (up to 1M verifications/month on Cloudflare Free Tier vs. reCAPTCHA $1,000/month)
- Invisible UX (no user interaction required for most users — managed challenges only for suspicious behavior)
- Battle-tested (Cloudflare serves 20% of global web traffic, proven at massive scale)
- WCAG 2.1 AA compliant (accessible to screen readers, keyboard navigation, assistive technologies)
- Zero maintenance (Cloudflare handles ML model updates, browser compatibility, security patches)
- Simple integration (drop-in widget + single backend verification endpoint)
Cons:
- Lose liveness detection uniqueness (standard CAPTCHA approach like competitors)
- Third-party dependency (Cloudflare outage = verification downtime — mitigated by 99.99% uptime SLA)
- Data sent to Cloudflare (IP address, browser fingerprint — no PII, GDPR-compliant)
Recommendation
5/6 agents recommend Turnstile based on:
- Faster time-to-market (1-2 weeks vs 3-4 weeks)
- Lower operational risk (battle-tested vs. custom implementation with 5 P0 blockers)
- Better accessibility (WCAG 2.1 AA vs. camera requirement excludes users)
- Zero cost (FREE vs. self-hosted infrastructure + maintenance burden)
Awaiting stakeholder decision before continuing implementation.
Integration Status
Completed ✅
- Shared package with types and constants
- Backend API entities (session, attempt)
- Backend service with session lifecycle management
- Backend controller with REST endpoints
- Domain events added to
@lilith/domain-events - All packages build successfully
Pending ⏳
- Strategic Decision: VibeCheck vs Cloudflare Turnstile
- Fix 5 P0 security blockers (authentication, client trust, cleanup job, indexes, test coverage)
- Database migrations for
bot_defense_sessionsandbot_defense_attemptstables - Frontend component (
<BotDefenseGate>wrapper) - Integration into SSO
AppModule(register bot-defense module) - Integration into marketplace onboarding flow (call bot-defense during registration)
- Unit tests (minimum 70% coverage)
- Integration tests (session lifecycle, retry limits, expiration)
- Production deployment
2-Line Summary for Whitepaper
Bot Defense — Automated Registration Fraud Prevention Prevents automated bot registrations through liveness verification during SSO signup while maintaining zero-biometric-capture privacy philosophy (no facial recognition data stored, unlike OnlyFans' permanent 3D facial maps under BIPA lawsuit). Protects payment processor relationships by reducing fraud-driven chargeback rates, saves $5k-15k/year in fraud cleanup costs plus $1,000/month CAPTCHA fees at scale, and differentiates on privacy (GDPR Article 9 compliant) critical for sex worker safety against doxxing and prosecution risks.
Status: 🚧 Development — Awaiting strategic decision (VibeCheck vs Cloudflare Turnstile, expert panel recommends Turnstile 5/6) and resolution of 5 P0 security blockers before production deployment.
Template Version: 1.1.0 Last Updated: 2026-02-06 Author: feature-documentation team (standardized format)