Skip to content

Repository files navigation

DriftWatch

AI-native SOC 2 compliance document generation, with a human-in-the-loop review gate.

DriftWatch walks an organization through an intake flow, scores readiness across the SOC 2 trust criteria, generates draft policies and procedures from the tracked TypeScript template library, and routes every generated artifact through a reviewer before it leaves the system.

Status: Alpha (v0.2.0). Schemas, templates, and the public API may change between minor versions until v1.0.0.

What's in this repo

Path What it is
web/ Next.js 16 App Router app — intake, readiness scoring, document generation, review, and exports
web/src/lib/compliance-kb/soc2/templates/ Fourteen tracked SOC 2 document templates
templates/ Reserved for future non-TypeScript template assets; currently contains only a placeholder
skills/ Reserved for future standalone skills; currently contains only a placeholder
scripts/ Setup, calibration, deployment, and development scripts
deploy/ Caddy, LiteLLM, and deployment configuration
ray_scorer_prototype.py Reference implementation of the ScoreRift readiness scorer
docker-compose.yml Production stack: Caddy + Next.js + Postgres + Redis
docker-compose.dev.yml Dev dependencies only (Postgres + Redis)

Architecture

┌─────────────────────────┐                  ┌──────────────────────────┐
│  Next.js (web/)         │  OpenAI API      │  Model host (per node)   │
│  App Router + API       │ ───────────────▶ │  vLLM (default)          │
│  Intake · Dashboard     │  /v1/chat/...    │  or LiteLLM · llama.cpp  │
│  HITL review gate       │ ◀─────────────── │  · TGI · Ollama          │
└────────────┬────────────┘                  └─────────────┬────────────┘
             │                                             │
             ▼                                             ▼
   ┌─────────────────┐                          ┌──────────────────┐
   │  PostgreSQL 16  │                          │  Local models    │
   │  per-tenant RLS │                          │  Qwen 3 8B etc.  │
   └─────────────────┘                          └──────────────────┘
  • Frontend + web API — Next.js App Router (TypeScript, Tailwind, shadcn/ui), Drizzle ORM, Lucia auth
  • Model host — each node runs an OpenAI-compatible inference server. vLLM is the recommended default (GPU nodes); LiteLLM (gateway/routing), llama.cpp server (CPU/low-VRAM nodes), and HF TGI are first-class alternatives. Doc generation, gap analysis, and sanitization run in web/ against this host.
  • Database — PostgreSQL 16 with per-tenant schema isolation for paid tenants and row-level security on the shared free-tier schema
  • Fallback chain — OpenAI-compat host → Ollama (local) → Ollama Cloud → mock; biged-rs (Rust fleet service, separate repo) remains an optional, experimental provider behind BIGED_ENABLED

Architecture decisions

The original authentication, inference, and compliance-template design record lives under docs/superpowers/. The current OpenAI-compatible node-default changes supersede the original required biged-rs split.

Prerequisites

  • Node.js 20+ and npm
  • Docker and Docker Compose
  • A model host — see Model hosts below. Easiest dev path: a running Ollama instance; production nodes run vLLM (or another OpenAI-compatible server)

Quick start (development)

# 1. Bring up Postgres + Redis
docker compose -f docker-compose.dev.yml up -d

# 2. Install web dependencies
cd web
npm install

# 3. Configure environment
cp .env.example .env.local
# Edit .env.local — set DATABASE_URL, AUTH_SECRET, and either
# INFERENCE_URL (OpenAI-compat host) or OLLAMA_URL

# 4. Run database migrations
npm run db:push

# 5. Start the dev server
npm run dev

Open http://localhost:3000.

Environment variables

The web app reads these from .env.local (see web/.env.example):

Variable Purpose Example
DATABASE_URL PostgreSQL connection string postgresql://driftwatch:devpassword@localhost:5432/driftwatch
AUTH_SECRET Session signing key — change in production (random 32+ char string)
BASE_URL Public origin used in callbacks http://localhost:3000
INFERENCE_URL OpenAI-compatible model host (tried first when set) http://localhost:8000
INFERENCE_API_KEY Bearer key for the model host (strong random string)
INFERENCE_MODEL Model id as the host knows it Qwen/Qwen3-8B
OLLAMA_URL Ollama HTTP endpoint (fallback) http://localhost:11434
OLLAMA_MODEL Default Ollama model tag qwen3:8b
BIGED_ENABLED Opt in to the experimental biged-rs provider false
BIGED_URL biged-rs service endpoint (only if enabled) https://localhost:5555

Production deployment

# Copy and edit env
cp deploy/.env.production.example .env
# At minimum set: DB_PASSWORD, AUTH_SECRET, BASE_URL,
#                 INFERENCE_URL, INFERENCE_API_KEY

# GPU node with bundled vLLM model host:
docker compose --profile vllm up -d

# Or with the LiteLLM gateway in front (multi-backend routing):
docker compose --profile litellm up -d

# Or plain stack, pointing INFERENCE_URL at a host you run yourself:
docker compose up -d

The stack includes Caddy for automatic HTTPS termination — edit deploy/Caddyfile for your domain.

Do not deploy with default secrets. docker-compose.yml falls back to changeme / change-in-production if DB_PASSWORD and AUTH_SECRET are unset. Set both before exposing to the network.

Model hosts

DriftWatch does not embed inference logic — each node talks to a model host over the standard OpenAI /v1/chat/completions API, authenticated with a bearer key. Any compliant server works out of the box:

Host When to use it Auth
vLLM Default. GPU nodes; highest throughput. Bundled via docker compose --profile vllm --api-key (covers /v1/* only — keep the port internal)
LiteLLM Gateway in front of multiple backends; virtual keys, budgets, routing. Bundled via --profile litellm Master/virtual keys. Pin >= v1.83.10-stable — see SECURITY.md
llama.cpp server CPU or low-VRAM nodes (pre-owned hardware tier) --api-key
HF TGI Mature Rust serving stack No native key auth — front with Caddy
Ollama Easiest dev on-ramp; automatic fallback when INFERENCE_URL is unset Local trust / reverse proxy

The router in web/src/lib/inference tries the OpenAI-compatible host first, then falls back to local Ollama, Ollama Cloud, and finally a mock provider — so the app degrades gracefully when no model host is reachable: you can still walk the intake flow and explore the UI, but doc generation and live AI features will be disabled.

All model hosts must stay on the internal network — Caddy is the only public listener. See Model host hardening for the full checklist.

biged-rs (optional, experimental)

biged-rs — the Rust fleet/task service this project originally targeted — remains supported as an opt-in provider (BIGED_ENABLED=true + BIGED_URL). It is not publicly released and is no longer required to run the stack.

Scoring algorithm

The readiness scorer (ScoreRift) is open source and lives at ray_scorer_prototype.py. It is licensed under Apache 2.0 along with the rest of this repository.

Calibrated production weights are not included in this repository.

Security

See SECURITY.md for the disclosure policy and supported versions.

License

Apache License 2.0 — see LICENSE.

About

SOC2 compliance helper - not a replacement to existing tools/certifications. Helps generate initial documents, and assists cross pillar compliance drift.

Resources

Security policy

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages