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 untilv1.0.0.
| 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) |
┌─────────────────────────┐ ┌──────────────────────────┐
│ 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 behindBIGED_ENABLED
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.
- 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)
# 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 devOpen http://localhost:3000.
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 |
# 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 -dThe stack includes Caddy for automatic HTTPS termination — edit deploy/Caddyfile for your domain.
Do not deploy with default secrets.
docker-compose.ymlfalls back tochangeme/change-in-productionifDB_PASSWORDandAUTH_SECRETare unset. Set both before exposing to the network.
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 — 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.
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.
See SECURITY.md for the disclosure policy and supported versions.
Apache License 2.0 — see LICENSE.