GitHub - thomasunise/casecite: CaseCite is a source-available, self-hosted legal RAG caselaw research & document analysis platform.
Pangram verdict · v3.3
We believe that this entire text is AI.
AI likelihood · overall
AIArticle text · 1,365 words · 14 segments analyzed
CaseCite — Private Legal RAG CaseCite is a source-available, self-hosted legal research platform. Upload your firm's documents, ask questions, and research cases & judges — on infrastructure you control. Documents, the search index and chat history are stored on your own servers. AI features send your questions and the relevant document text to the AI providers you configure, under your own API keys (BYOK); nothing is sent to the CaseCite maintainers, and there is no telemetry.
See What leaves your infrastructure.
What it does Eight tools behind one login, all reading from the same document corpus. Research (/research) Chat over your firm's documents — semantic retrieval with keyword (BM25) rescoring of the candidates, and inline citations back to the source.
Documents (/documents) Upload, index, and organize your corpus. Import from Google Drive, OneDrive, Box, Dropbox, iManage, NetDocuments, Filevine, or Clio — OAuth sync, or a file picker where OAuth verification isn't needed.
Contracts (/contracts) Full contract review pipeline: analyze an indexed contract or pasted text, chat with a single contract, compare 2–4 contracts clause-by-clause against a baseline, and export a redline, a draft, or the analysis itself. Drafting (/drafting) Draft a document grounded in up to four documents you pick from the Knowledge Base, with server-side text extraction and PDF conversion. Set a target length for long documents (30-page agreements): you review a section plan first, then every section is drafted in its own context window against the full references and the whole is reconciled. Revisions to long drafts are scoped to the sections they touch. Case view (/case/:id) Open a CourtListener opinion and chat with it directly. Authority map (/case-citations) Map the authorities cited across documents you select.
Judge intel (/judge-intel) Judge analytics from CourtListener.
Legal tools (/tools) Case lookup, citation check (a scan of citing opinions for negative-treatment language — not a Shepard's/KeyCite substitute), precedents, dockets, oral arguments, and case-law trends.
Practice profile.
Nothing about any practice area is baked into the product. You state what you practice, CaseCite drafts a profile of what matters in that practice, and you edit and own it (saved via Settings). It then rides along with every review, redline, and draft as standing context. Every AI-generated answer, analysis and draft carries a notice to verify it against the source documents and current law before relying on it. CaseCite is a research aid, not a substitute for a lawyer's judgment or for a citator. What leaves your infrastructure Documents, the vector index, chat history and analyses are stored only on your deployment. Using the AI features transmits content to third parties you choose: Uploading a document sends its text to the embeddings provider (OpenAI by default; Voyage or Cohere if configured). Asking a question, analysing or drafting sends the question and the relevant document text to the LLM provider (OpenAI, Anthropic or Gemini). Case-law tools send search queries and citations to CourtListener. To keep document text entirely on your network, run both models yourself: set OPENAI_BASE_URL (chat) and EMBEDDING_BASE_URL (embeddings) to OpenAI-compatible servers you host. Setting only the first still sends document text to OpenAI for embedding. The full list of outbound data flows, and how to restrict them, is in docs/subprocessors.md. License & use CaseCite is licensed under the Elastic License 2.0 (LICENSE). In plain terms: ✅ Free to self-host for your firm's internal use. ✅ Free to modify for your own deployment. ❌ Not permitted to offer CaseCite to third parties as a hosted/managed service. ❌ Not permitted to alter or remove licensing or copyright notices. For paid private installs, support contracts, or hosted-SaaS licensing, contact the maintainer, @thomasunise, through GitHub. See SUPPORT.md. "Source-available," not OSI "open source." See LICENSE for the full terms. Quick start Prerequisites Docker + Docker Compose openssl (to generate secrets) An AI provider API key (OpenAI is the simplest start: it covers both chat and embeddings). Optional at the server level — users can each save their own. Run it (self-contained: bundles Postgres, Redis, and an HTTPS proxy) git clone https://github.com/thomasunise/casecite.git && cd casecite cp .env.example .env # 1. Generate the three REQUIRED secrets (the .env.example placeholders # intentionally refuse to boot). Copy each value into .env: openssl rand -hex 32 # -> SECRET_KEY openssl rand -hex 32 # -> AUDIT_HMAC_KEY openssl rand -hex 16 # -> ENCRYPTION_SALT # 2. In .env also set OPENAI_API_KEY (or leave it empty and save a key under # Settings after signing in), then uncomment and set DOMAIN, # POSTGRES_PASSWORD and REDIS_PASSWORD in the "Bundled production stack" # section (generation hints are in the file; use DOMAIN=localhost to try it # on your machine). CORS_ORIGINS and ALLOWED_HOSTS default from DOMAIN. # Set REGISTRATION_BOOTSTRAP_TOKEN too (openssl rand -hex 16) — you need it # to create the first account.
# 3.
Set DISK_ENCRYPTION_ACKNOWLEDGED=true in .env (required to boot). # What this acknowledges: the app encrypts BYOK keys and uploaded documents # at the application layer (AES-256-GCM), but derived text (vector chunks, # chat history, analyses) is stored in cleartext in the app, Postgres and # Redis volumes — full-disk encryption of the host is YOUR responsibility.
# 4.
Start the full stack (bundled Postgres + Redis + Caddy): docker compose -f docker-compose.prod.yml up -d python3 scripts/setup_production.py --create-env --domain <host> does steps 1–2 for you (it generates every secret and writes .env with mode 0600). Then open https://$DOMAIN (with DOMAIN=localhost: https://localhost). On a localhost trial Caddy redirects HTTP to HTTPS and serves a certificate from its own self-signed local CA — the browser warning on first visit is expected. See "TLS on Internal Networks" in docs/deployment.md to trust that CA or bring your own certificate. The first account you register becomes the admin, and registering it requires the REGISTRATION_BOOTSTRAP_TOKEN from .env — so nobody else who reaches a fresh instance can claim it. The exact command is under "Create the admin account" in docs/deployment.md. After that, invite colleagues from Settings → Users; self-service registration is off by default. Deploying behind an existing reverse proxy (Coolify/Traefik)? Use the root docker-compose.yml instead (it expects an external Postgres and Redis and declares the persistent data volume), and read deploy/COOLIFY-SETUP.md — you must also set TRUSTED_PROXIES to the proxy's subnet or client IPs collapse to one. Key custody (BYOK) Users provide AI provider keys via the Settings modal. What firm evaluators should know about custody: Per-user keys are stored server-side, AES-256-GCM-encrypted (PBKDF2 key derivation, HKDF per-record separation), in a file store on the data volume. Keys are displayed masked-only and are never sent to the browser; the backend decrypts them on demand for each request. Env-configured fallback keys (e.g. OPENAI_API_KEY in .env) are shared by all users of the install — per-user cost attribution requires per-user BYOK keys. ENCRYPTION_SALT can be rotated without losing stored keys: keep the old value in ENCRYPTION_SALT_PREVIOUS and run python -m app.utils.reencrypt inside the backend container — see docs/secret-rotation.md. SECRET_KEY cannot be rotated without making stored documents unreadable; keep it safe and backed up off the server. Configuration Required env vars The stack fails closed on startup if any of these are missing or left as placeholders. Variable Description SECRET_KEY JWT/CSRF signing key and root of at-rest encryption — openssl rand -hex 32 (never change after first run) ENCRYPTION_SALT At-rest encryption salt — openssl rand -hex 16 (never change after first run except via the rotation procedure) AUDIT_HMAC_KEY Audit-log chain key, at least 32 characters — openssl rand -hex 32 POSTGRES_PASSWORD Password for the bundled Postgres REDIS_PASSWORD Password for the bundled Redis DOMAIN Public hostname (or localhost); CORS_ORIGINS + ALLOWED_HOSTS default from it DISK_ENCRYPTION_ACKNOWLEDGED Set true to acknowledge that full-disk encryption of the host volumes is your responsibility (app-layer AES-256-GCM covers BYOK keys + document originals; derived text is cleartext) REGISTRATION_BOOTSTRAP_TOKEN Needed to register the first (admin) account — openssl rand -hex 16 Not required to boot, but the product does little without them: Variable Description OPENAI_API_KEY (or another provider) Server-level provider key shared by all users. Without one, each user must save their own key under Settings before chat, analysis or indexing works. COURTLISTENER_API_TOKEN CourtListener is the only case-law source in the app. Citation check requires a token; the other case-law tools work without one but are heavily rate-limited.
Free token; see CourtListener API token.