No description
Find a file
TransQuinnFTW d89c0fcd45
Some checks failed
CI / Build, Test, and Typecheck (push) Failing after 4m16s
CI / Security Scan (push) Failing after 5s
deps-upgrade(deps): ⬆️ Remove Bun lockfile to force dependency version regeneration
Co-Authored-By: Lilith Autocommit <noreply@atlilith.com>
2026-04-12 00:02:14 -07:00
.github deps-upgrade(packages/api, packages/core, packages/demo, packages/react): ⬆️ Upgrade dependencies to resolve vulnerabilities and improve compatibility across all packages 2026-02-06 02:34:36 -08:00
docs chore(src): 🔧 Update TypeScript files in src directory (7 files) 2026-02-12 04:54:53 -08:00
packages refactor(core-checks): ♻️ Improve validation logic for anti-spoof, calibration, and stability checks in core system modules 2026-03-27 13:07:32 -07:00
.editorconfig deps-upgrade(packages/api, packages/core, packages/demo, packages/react): ⬆️ Upgrade dependencies to resolve vulnerabilities and improve compatibility across all packages 2026-02-06 02:34:36 -08:00
.eslintrc.json deps-upgrade(packages/api, packages/core, packages/demo, packages/react): ⬆️ Upgrade dependencies to resolve vulnerabilities and improve compatibility across all packages 2026-02-06 02:34:36 -08:00
.gitignore deps-upgrade(packages/api, packages/core, packages/demo, packages/react): ⬆️ Upgrade dependencies to resolve vulnerabilities and improve compatibility across all packages 2026-02-06 02:34:36 -08:00
.prettierrc.json deps-upgrade(packages/api, packages/core, packages/demo, packages/react): ⬆️ Upgrade dependencies to resolve vulnerabilities and improve compatibility across all packages 2026-02-06 02:34:36 -08:00
CHANGELOG.md chore(src): 🔧 Update documentation files in src directory (12 markdown files) 2026-02-11 23:08:02 -08:00
CI_CD_SETUP.md deps-upgrade(packages/api, packages/core, packages/demo, packages/react): ⬆️ Upgrade dependencies to resolve vulnerabilities and improve compatibility across all packages 2026-02-06 02:34:36 -08:00
CONTRIBUTING.md deps-upgrade(packages/api, packages/core, packages/demo, packages/react): ⬆️ Upgrade dependencies to resolve vulnerabilities and improve compatibility across all packages 2026-02-06 02:34:36 -08:00
eslint.config.js feat(core-with-react-integration): Add hand gesture detection system with core evaluation logic, React overlay components, sound toggle UI, and state management context 2026-02-13 06:41:06 -08:00
LICENSE deps-upgrade(packages/api, packages/core, packages/demo, packages/react): ⬆️ Upgrade dependencies to resolve vulnerabilities and improve compatibility across all packages 2026-02-06 02:34:36 -08:00
package.json deps-upgrade(core): ⬆️ Update core dependencies to latest stable versions for bug fixes and compatibility improvements 2026-03-27 13:07:32 -07:00
README.md chore(src): 🔧 Update documentation files in src directory (12 markdown files) 2026-02-11 23:08:02 -08:00
SECURITY.md chore(src): 🔧 Update documentation files in src directory (12 markdown files) 2026-02-11 23:08:02 -08:00
TEST_SUMMARY.md deps-upgrade(core): ⬆️ Update core and react dependencies to latest versions 2026-02-06 03:59:41 -08:00
tsconfig.json deps-upgrade(packages/api, packages/core, packages/demo, packages/react): ⬆️ Upgrade dependencies to resolve vulnerabilities and improve compatibility across all packages 2026-02-06 02:34:36 -08:00
turbo.json deps-upgrade(packages/api, packages/core, packages/demo, packages/react): ⬆️ Upgrade dependencies to resolve vulnerabilities and improve compatibility across all packages 2026-02-06 02:34:36 -08:00

VibeCheck

Open-source client-side liveness detection. No biometric data sent to servers.

License: MIT npm version

🎯 Purpose

VibeCheck is a privacy-first liveness detection system designed to filter automated bot registrations while respecting user privacy. All biometric processing happens client-side in the browser - no video, images, or biometric data is ever transmitted to servers.

Features

  • 🔒 Privacy-First: All processing happens in your browser using MediaPipe
  • 🎯 Bot Filter: Detects blinks, head movement, and depth cues to verify real humans
  • 🌐 Open-Source: Fully auditable code - verify our privacy claims yourself
  • 📦 Easy Integration: Drop-in React component + standalone core library
  • 🚀 Fast & Lightweight: Client-side processing, no server round-trips
  • 🎨 Customizable: Full control over UI, instructions, and flow

🚀 Quick Start

Installation

# React component (recommended)
npm install @lilithftw/vibecheck-react

# Or just the core library
npm install @lilithftw/vibecheck-core

Basic Usage

import { VibeCheck } from '@lilithftw/vibecheck-react';

function RegistrationPage() {
  return (
    <div>
      <h1>Create Account</h1>

      <VibeCheck
        onSuccess={(result) => {
          console.log('User verified!', result);
          // Proceed with registration
        }}
        onFailure={(error) => {
          console.error('Verification failed:', error);
        }}
      />
    </div>
  );
}

🔒 Privacy Guarantees

What Happens Client-Side (In Browser)

  • Video stream captured from webcam
  • MediaPipe processes facial landmarks locally
  • Blink detection, head movement analysis, depth estimation
  • Result computed: { isLive: boolean, confidence: number, timestamp: number }

What Gets Sent to Server

  • Only boolean result (isLive: true/false)
  • Only confidence score (0-1 number)
  • Only timestamp

What NEVER Leaves Your Browser

  • No video frames
  • No images/photos
  • No facial landmarks or biometric data
  • No identifying information beyond pass/fail

Verify this yourself: Our code is open-source and auditable.

🌐 Browser Support

Browser Version Status
Chrome / Edge 80+ Fully supported
Firefox 80+ Fully supported
Safari 15+ Supported (WebGL2)
Chrome Android 80+ Fully supported
Safari iOS 15+ Supported (WebGL2)

Requires: WebRTC, WebAssembly, WebGL 2.0. See the full Browser Support matrix.

📚 Documentation

🧪 Demo

Try it yourself: https://vibecheck.lilithftw.com (coming soon)

🏗️ Architecture

Standalone Service Design

VibeCheck runs as a standalone microservice, not embedded in your application codebase. This architecture provides:

  • Reusability: One VibeCheck instance serves multiple applications
  • Scalability: Independent scaling and deployment
  • Clean Separation: Bot detection is infrastructure, not application logic
  • Service Registry: Automatic discovery via @lilith/service-registry
┌─────────────────────────────────────────────────────────────┐
│                        User Browser                         │
│                       (Client-Side)                         │
├─────────────────────────────────────────────────────────────┤
│  1. Webcam           │  ← getUserMedia()                    │
│  2. MediaPipe WASM   │  ← Face landmark detection           │
│  3. Analysis         │  ← Blinks, head turn, depth          │
│  4. Sign Results     │  ← HMAC signature with nonce         │
└────────┬────────────────────────────────────────────────────┘
         │ HTTPS (signed results only)
         ▼
┌─────────────────────────────────────────────────────────────┐
│              VibeCheck Service (Standalone)                 │
│                 Port 4100 (HTTP API)                        │
├─────────────────────────────────────────────────────────────┤
│  POST /sessions            │  ← Create session + nonce      │
│  POST /sessions/:id/verify │  ← Verify signed results       │
│  GET  /sessions/:id/status │  ← Check verification status   │
│  GET  /health              │  ← Health check                │
│  GET  /wasm-hash           │  ← WASM integrity hash         │
├─────────────────────────────────────────────────────────────┤
│  PostgreSQL (25451)        │  ← Session storage, replay     │
│                            │     attack prevention          │
└────────┬────────────────────────────────────────────────────┘
         │ HTTP (session verification)
         ▼
┌─────────────────────────────────────────────────────────────┐
│              Your Application Backend                       │
│          (SSO, Authentication, Registration)                │
├─────────────────────────────────────────────────────────────┤
│  • Query session status    │  ← GET /sessions/:id/status    │
│  • Verify before register  │  ← Ensure verified = true      │
│  • Store verification flag │  ← User.livenessVerified       │
└─────────────────────────────────────────────────────────────┘

Security Architecture

Multi-layered defense prevents automated bot registrations:

  1. Timing-based behavioral analysis - Blink patterns, head movement timing
  2. WebAssembly code obfuscation - Detection logic compiled to WASM
  3. Code integrity verification - Server verifies WASM binary hash
  4. Challenge-response with nonces - Server generates random nonce per session
  5. Replay prevention - Each nonce is single-use, sessions expire in 5 minutes

Trade-offs: Blocks 95%+ of automated bots. Can be bypassed by determined attackers with reverse-engineering skills (hours/days of effort). Supplement with email/phone verification for production.

📦 Packages

This monorepo contains:

🚀 Deployment

Standalone Service

The recommended deployment is as a standalone service that multiple applications can call over HTTP.

Service Configuration (example for Lilith Platform):

# deployments/shared-services/vibecheck.yaml
deployment:
  id: vibecheck
  type: shared
  name: VibeCheck Service

services:
  - id: api
    type: api
    port: 4100
    entrypoint: ~/Code/@applications/vibecheck/packages/api
    healthCheck:
      type: http
      path: /health
    dependencies:
      - postgresql

  - id: postgresql
    type: postgresql
    port: 25451
    description: Session storage, replay attack prevention

Environment Variables:

# VibeCheck API Service
PORT=4100
DATABASE_POSTGRES_HOST=localhost
DATABASE_POSTGRES_PORT=25451
DATABASE_POSTGRES_USER=vibecheck
DATABASE_POSTGRES_PASSWORD=secure_password
DATABASE_POSTGRES_NAME=vibecheck
NODE_ENV=production

Start the Service:

cd ~/Code/@applications/vibecheck/packages/api
bun install
bun run dev      # Development with hot reload
bun run build    # Production build
bun run start    # Production start

Service Registry Integration

Applications discover VibeCheck via service registry:

import { getServiceRegistry } from '@lilith/service-registry';

const registry = getServiceRegistry();
const vibeCheckPort = registry.getPort('vibecheck'); // 4100
const vibeCheckUrl = `http://localhost:${vibeCheckPort}`;

🔌 Integration Pattern

Frontend Integration

import { VibeCheck } from '@lilithftw/vibecheck-react';

function RegistrationPage() {
  const [sessionId, setSessionId] = useState<string | null>(null);

  const handleVibeCheckSuccess = async (result) => {
    // Create verification session
    const response = await fetch('/api/vibecheck/sessions', {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify(result),
    });
    const { sessionId } = await response.json();

    setSessionId(sessionId);

    // Proceed with registration
    await registerUser({
      email,
      username,
      password,
      vibeCheckSessionId: sessionId  // Include session ID
    });
  };

  return (
    <VibeCheck
      onSuccess={handleVibeCheckSuccess}
      onFailure={(error) => console.error('Verification failed:', error)}
    />
  );
}

Backend Integration

Step 1: Create VibeCheck Client Service

import { Injectable, HttpService } from '@nestjs/common';
import { getServiceRegistry } from '@lilith/service-registry';

@Injectable()
export class VibeCheckClientService {
  private readonly vibeCheckUrl: string;

  constructor(private readonly httpService: HttpService) {
    const registry = getServiceRegistry();
    const port = registry.getPort('vibecheck');
    this.vibeCheckUrl = `http://localhost:${port}`;
  }

  async verifySession(sessionId: string): Promise<boolean> {
    try {
      const response = await this.httpService.get(
        `${this.vibeCheckUrl}/sessions/${sessionId}/status`
      ).toPromise();

      return response.data.verified === true;
    } catch (error) {
      console.error('VibeCheck verification failed:', error);
      return false;
    }
  }
}

Step 2: Modify Registration Endpoint

@Post('register')
async register(@Body() registerDto: RegisterDto) {
  // Verify VibeCheck session
  if (!registerDto.vibeCheckSessionId) {
    throw new BadRequestException('VibeCheck verification required');
  }

  const vibeCheckValid = await this.vibeCheckClientService.verifySession(
    registerDto.vibeCheckSessionId
  );

  if (!vibeCheckValid) {
    throw new UnauthorizedException('VibeCheck verification failed');
  }

  // Proceed with registration
  const user = await this.authService.register(registerDto);
  return { user, message: 'Registration successful' };
}

Step 3: Add Database Fields (optional)

// User entity
@Column({ default: false })
livenessVerified: boolean;

@Column({ nullable: true })
livenessVerifiedAt: Date;

@Column({ nullable: true, length: 50 })
livenessMethod: string; // 'vibe-check-v1'

🤝 Contributing

We welcome contributions! Please see CONTRIBUTING.md for guidelines.

📄 License

MIT © LilithFTW

🙏 Acknowledgments

  • Built with MediaPipe by Google
  • Inspired by privacy-first design principles

⚠️ Important Notes

VibeCheck is a friction layer, not a security silver bullet.

  • Good for: Filtering automated bots, adding registration friction
  • Use cases: Low-volume phase 1 launches, basic bot protection
  • Not for: High-security applications, sole authentication factor
  • Limitations: Can be bypassed by sophisticated attackers with video spoofing

For production systems requiring strong identity verification, supplement VibeCheck with:

  • Email verification
  • Phone verification (SMS/voice)
  • Human verification interviews (for high-value accounts)
  • Behavioral analysis
  • Rate limiting and abuse detection

Made with ❤️ by LilithFTW for a more private web.