Skip to main content
Causeloop is a multi-tenant SaaS platform. This page describes the major components, how a request flows through them, and how tenant data stays isolated at every layer.

High-level components


Component descriptions

Frontend — Next.js (app.causeloop.ai)

The product UI is a Next.js application authenticated via WorkOS AuthKit. After exchanging the WorkOS access token for a platform JWT, the frontend communicates exclusively with the backend API and a WebSocket for realtime updates. Key routes:

Backend API — FastAPI (api.causeloop.ai)

The backend is a FastAPI application serving all product functionality under /v1. It is stateless and horizontally scalable. Key responsibilities:
  • Auth token issuance and verification
  • The deterministic engine pipeline (below) — clustering, criticality, hazard fitting, alerting
  • Business logic for issues, patterns, predictions, recommendations, clusters, and connectors
  • AI orchestration (dispatching extraction/root-cause/narration jobs to the LLM Router)
  • Tenant isolation via database RLS
  • Async job coordination via Kafka stubs (Celery-based workers in production)
  • Rate limiting (1,000 requests per minute per tenant by default)
Stack:

LLM Router — AI providers

The LLM Router dispatches AI analysis tasks — attribute extraction, root-cause narration, recommendation drafting — to the configured provider. Pattern detection itself is not one of them: clustering, criticality, and hazard fitting are deterministic math (the engine pipeline below), and LLMs are never allowed to produce a score, probability, date, or dollar figure. Every LLM-derived field is labeled with an origin, and low-confidence extractions abstain into the review queue instead of guessing (see Abstention & the review queue). Providers are tried in order:
  1. Anthropic — Claude models (ANTHROPIC_API_KEY)
  2. OpenAI — GPT-4o / GPT-4o-mini (OPENAI_API_KEY)
  3. Mock — Deterministic offline fallback (no keys required)
If both ANTHROPIC_API_KEY and OPENAI_API_KEY are absent, the API falls back to the mock provider automatically. Analysis results are plausible but not real.

Database — PostgreSQL with Row-Level Security

All product data lives in PostgreSQL 16. Multi-tenancy is enforced at the database layer using Row-Level Security (RLS):
  • Every tenant table has a workspace_id column.
  • Before executing any query, the API binds app.current_workspace_id on the session.
  • RLS policies reject reads and writes that do not match the bound workspace ID.
  • The application role (causeloop_app) does not have BYPASSRLS; a superuser role is kept separate for migrations only.
This means even a bug in the application layer cannot leak one tenant’s data to another.

Connectors and Ingestion

Connectors pull issues into a workspace from external tools. They operate in two modes:
  • Poll — the backend fetches issues from the external API on a configurable schedule (poll_interval_seconds).
  • Webhook (inbound push) — the external tool POSTs events to POST /ingest/{connector_token}, verified by HMAC signature.
Sync runs are tracked with start/end timestamps, record counts, and error details, accessible via GET /connectors/{id}/sync-runs.

The engine pipeline — deterministic, one run at a time

POST /engine/runs is the single entry point for turning ingested issues into patterns, predictions, and financials. There is no separate “model training” step — one run executes the whole pipeline, stage by stage, and every stage’s counters/durations land in the run’s manifest: Every run produces a manifest (snapshot_hash, event_log_cursor, configs{kind→hash}, models{embed, extract_llm, rca_llm}, seeds, code version) and a stability report (leiden_dsu_agreement, churn per pattern). POST /engine/runs/{id}/replay re-executes a prior run against the pinned manifest and returns {identical: bool, diff_summary} — the mechanism a CI gate uses to prove the pipeline is reproducible before every release. See Event log & provenance for how run outputs trace back to inputs.

WebSocket Gateway — Realtime channel

The backend exposes a WebSocket endpoint at /v1/stream. Authenticated clients connect with their platform JWT as a query parameter (?token=<jwt>). The gateway pushes typed event envelopes to all sockets belonging to the same tenant:
Event types that reach the browser: activity.created, issue.updated, pattern.updated, prediction.alert, recommendation.created, and job.updated (for async job progress).

Request and auth flow

1

User signs in via WorkOS AuthKit

The Next.js frontend delegates authentication to WorkOS AuthKit (@workos-inc/authkit-nextjs) — email/password or Google OAuth, hosted at /sign-in and /callback. On success, WorkOS issues a signed RS256 access token to the browser session.
2

Exchange for a platform token

The frontend calls POST /v1/auth/exchange with the WorkOS access token as subject_token. The backend verifies the token against WorkOS’s JWKS endpoint (RS256), then runs admission: the identity must resolve to an existing membership, an accepted invitation, or (only when the workspace explicitly opts into domain JIT) a verified-domain match. Exchange never creates a user as a side effect otherwise — an unprovisioned identity gets a 403 and an auth.login.denied audit event. On admit, it issues a short-lived HS256 Bearer token bound to the resolved workspace.
3

API calls with Bearer token

All subsequent requests include the Bearer token in the Authorization header. Middleware resolves the token to {user_id, workspace_id, role, scopes} and binds the RLS session variable before any query runs.
4

Realtime updates via WebSocket

The frontend upgrades to a WebSocket connection at /v1/stream?token=<jwt>. The gateway verifies the token identically to the REST path, then pushes events for that tenant as they occur.

Deployment topology

In production, each logical layer runs as an independent set of replicas behind a load balancer: For local development, docker-compose.yml runs the API, PostgreSQL, and Caddy (reverse proxy) as a single-box stack.

Quickstart

Sign in and see your first insights in 10 minutes.

Deploy & Security

Self-hosting, environment variables, and security controls.