Brand logo
HomeCloud ComputingSecuritySoftware DevelopmentAI ApplicationsStartupsGeneral
  1. Home
  2. /
  3. aiapplications
  4. /
  5. casecite-self-hosted-legal-ai-research-workspace

CaseCite in Production: An AI Applications Field Guide to Self-Hosted Legal Research Workflows

Demos of legal generative AI usually fail at the procurement stage rather than the prompting stage: counsel can see the answer quality, but compliance cannot see where the corpus ends up. CaseCite was shaped around that objection. It is a source-available, self-hosted legal research workspace, so the firm's uploads, the search index, the conversation history and the resulting analyses all remain on infrastructure the firm runs. The generative features reach external model providers — OpenAI, Anthropic or Gemini — only through the customer's own keys (BYOK), with no telemetry and no traffic back to the maintainers. Read what follows as an adoption brief for ItInsightsWorld's AIapplications readers: which surfaces exist, what crosses the network boundary, what the license permits, how a pilot is installed, and which assumptions need correcting.

Why the application layer, not the model, decides adoption

There is no novel model story here; the engineering interest is integration. Retrieval pairs semantic search with keyword (BM25) rescoring of candidates, and answers return inline citations back to the source — the practical requirement for a reviewer who must trace a claim to a paragraph. Eight tools sit behind one login and every one of them reads the same document corpus, so context is prepared once rather than reassembled per feature. For enterprise AI programs that is the pattern worth copying: a single grounded document layer serving many business surfaces.

The Eight tools, mapped to business tasks

SurfaceTask it ownsApplication notes
Research (/research)Chat over the firm's documentsSemantic retrieval with BM25 rescoring of candidates; inline citations back to source
Documents (/documents)Build and organize the corpusUpload, index and organize; import from Google Drive, OneDrive, Box, Dropbox, iManage, NetDocuments, Filevine or Clio by OAuth sync, or by a file picker where OAuth verification isn't needed
Contracts (/contracts)End-to-end contract reviewAnalyze an indexed contract or pasted text, chat with a single contract, compare 2–4 contracts clause-by-clause against a baseline, export a redline, a draft or the analysis itself
Drafting (/drafting)Generate grounded documentsGrounded in up to four documents selected from the Knowledge Base, with server-side text extraction and PDF conversion; for long documents such as 30-page agreements a target length can be set, the section plan is reviewed first, each section is drafted in its own context window against the full references, the whole is reconciled, and revisions are scoped to the sections they touch
Case view (/case/:id)Read an opinion interactivelyOpens a CourtListener opinion so the user can chat with it directly
Authority map (/case-citations)Trace authority across a setMaps the authorities cited across the selected documents
Judge intel (/judge-intel)Add behavioral contextPresents Judge analytics from CourtListener
Legal tools (/tools)Case-law operationsCase 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 context is configured, not hard-coded

No assumption about any practice area is built into the product. The user states what they practice, CaseCite drafts a profile of what matters in that practice, and the user edits and owns it (saved via Settings). That profile then travels along with every review, redline and draft as standing context — the cheapest form of prompt governance available, because it is one editable artifact instead of scattered tribal prompt fragments.

Every AI-generated answer, analysis and draft carries a notice to verify it against the source documents and current law before anyone relies on it. CaseCite is a research aid, not a substitute for a lawyer's judgment or for a citator.

Data egress: what actually leaves the deployment

Storage stays local. Inference does not, unless you make it. Using the AI features transmits content to third parties the user chooses:

  • 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 plus 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. Configuring only the first still sends document text to OpenAI for embedding. The full inventory of outbound flows and the ways to restrict them sits in docs/subprocessors.md.

License terms in operating language

CaseCite is licensed under the Elastic License 2.0 (LICENSE) and is described as “Source-available,” not OSI “open source.” The commercial boundary is narrow but firm:

  • Free to self-host for a firm's internal use.
  • Free to modify for your own deployment.
  • Not permitted to offer CaseCite to third parties as a hosted or managed service.
  • Not permitted to alter or remove licensing or copyright notices.

Paid private installs, support contracts and hosted-SaaS licensing are covered in SUPPORT.md; the code is available through GitHub and the complete terms in LICENSE.

Step-by-step: installing a controlled pilot

Prerequisites checklist

  • Docker and Docker Compose are needed.
  • Use openssl to generate secrets.
  • Have an AI provider API key; OpenAI is the simplest start because it covers both chat and embeddings. It is optional at the server level, since each user can save a key.

The self-contained run, bundling Postgres, Redis and an HTTPS proxy

Use git to clone the CaseCite GitHub repository and enter the casecite directory, then copy .env.example to .env and prepare the three REQUIRED secrets; the placeholders in .env.example intentionally refuse to boot.

  1. Generate each secret with openssl rand -hex 32 for SECRET_KEY and AUDIT_HMAC_KEY, and openssl rand -hex 16 for ENCRYPTION_SALT, then copy the values into .env.
  2. In .env, set OPENAI_API_KEY — or leave it empty and save a key under Settings after signing in. Uncomment and set DOMAIN, POSTGRES_PASSWORD and REDIS_PASSWORD in the “Bundled production stack” section, where generation hints are provided and DOMAIN=localhost is acceptable for a local trial. CORS_ORIGINS and ALLOWED_HOSTS default from DOMAIN. Also set REGISTRATION_BOOTSTRAP_TOKEN with openssl rand -hex 16, because it is needed to create the first account.
  3. Set DISK_ENCRYPTION_ACKNOWLEDGED=true, which is required to boot. The acknowledged point is that the app encrypts BYOK keys and uploaded documents at the application layer with AES-256-GCM, while derived text such as vector chunks, chat history and analyses is stored in cleartext in the app, Postgres and Redis volumes — full-disk encryption of the host remains the user's responsibility.
  4. Start the full stack bundled with Postgres, Redis and Caddy using docker compose -f docker-compose.prod.yml up -d.

Running python3 scripts/setup_production.py --create-env --domain <host> performs steps 1–2 automatically, generating every secret and writing .env with mode 0600. Then open https://$DOMAIN, or https://localhost when DOMAIN=localhost.

On a localhost trial, Caddy redirects HTTP to HTTPS and serves a certificate from its own self-signed local CA, so 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 registered 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, colleagues are invited from Settings → Users, because self-service registration is off by default.

When deploying behind an existing reverse proxy such as Coolify or Traefik, use the root docker-compose.yml instead; it expects external Postgres and Redis and declares the persistent data volume. Read deploy/COOLIFY-SETUP.md and set TRUSTED_PROXIES to the proxy's subnet, otherwise client IPs collapse to one.

Configuration reference for the operations review

Required environment variables

The stack fails closed on startup if any required variable is missing or left as a placeholder.

VariableWhat it controls
SECRET_KEYJWT/CSRF signing key and root of at-rest encryption; create with openssl rand -hex 32 and never change after first run
ENCRYPTION_SALTAt-rest encryption salt; create with openssl rand -hex 16 and change only through the rotation procedure
AUDIT_HMAC_KEYAudit-log chain key, at least 32 characters; create with openssl rand -hex 32
POSTGRES_PASSWORDCredential for the bundled Postgres
REDIS_PASSWORDCredential for the bundled Redis
DOMAINPublic hostname, or localhost; CORS_ORIGINS and ALLOWED_HOSTS derive from it
DISK_ENCRYPTION_ACKNOWLEDGEDSet true to confirm that full-disk encryption of host volumes is yours; application-layer AES-256-GCM covers BYOK keys and document originals, while derived text is cleartext
REGISTRATION_BOOTSTRAP_TOKENNeeded to register the first admin account; create with openssl rand -hex 16

Not required to boot, but little works without them

VariableWhat it controls
OPENAI_API_KEY (or another provider key)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_TOKENCourtListener 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. A free token is available from CourtListener.

If you use the root docker-compose.yml with an external database and Redis instead of the bundled stack, set DATABASE_URL, REDIS_URL, CORS_ORIGINS and ALLOWED_HOSTS directly, and set DB_SSL=require for a managed database.

Optional environment variables

VariableDefaultPurpose
ANTHROPIC_API_KEY—Claude access
VOYAGE_API_KEY—Voyage AI legal embeddings
OPENAI_BASE_URL—OpenAI-compatible endpoint for chat, using a self-hosted model or gateway
EMBEDDING_BASE_URL—OpenAI-compatible endpoint for embeddings; pair it with OPENAI_BASE_URL to keep document text on your network
VECTOR_DBchromaUse chroma locally, or pinecone to store document text with Pinecone
TRUSTED_PROXIES127.0.0.1Reverse-proxy IP or CIDR; required behind a proxy
REQUIRE_MFAfalseRequire every password account to enrol TOTP MFA
SESSION_ABSOLUTE_TIMEOUT_HOURS and SESSION_IDLE_TIMEOUT_MINUTES8 / 120Session lifetime and idle timeout
ALLOW_REGISTRATIONfalseAllow self-service sign-up after the first account
SENDGRID_API_KEY—Enables password-reset emails; change-password works without SendGrid

The .env.example file documents every setting above.

Key custody under BYOK

  • Users provide AI provider keys through the Settings modal. Per-user keys are stored server-side, encrypted with AES-256-GCM using PBKDF2 key derivation and HKDF per-record separation, in a file store on the data volume.
  • Keys display masked-only and are never sent to the browser; the backend decrypts them on demand for each request.
  • Environment-configured fallback keys, such as OPENAI_API_KEY in .env, are shared by all users of the install, so 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 (docs/secret-rotation.md). SECRET_KEY cannot be rotated without making stored documents unreadable, so it must be kept safe and backed up off the server.

Security and governance facts reviewers ask for

  • Password sign-in uses PBKDF2-SHA256 and supports optional or mandatory TOTP MFA plus recovery codes; password reset is available by email, and change-password is available in the app.
  • JWT access tokens use rotating refresh tokens in httpOnly cookies, with JTI revocation in Redis (required in production) and a “sign out everywhere” action.
  • Sessions are capped at 5 per user, with an 8-hour absolute lifetime and an idle timeout.
  • Role-based permissions (require_permission) are adjustable per role by an admin.
  • Every document, chat and analysis can be scoped per user, and also per matter.
  • CSRF double-submit cookies are HMAC-signed; per-IP rate limiting and account lockout are enabled.
  • AES-256-GCM at-rest encryption protects uploaded originals, API keys, connector tokens and MFA secrets; the vector index and database depend on disk encryption provided by the user.
  • CSP, HSTS, X-Frame-Options and Permissions-Policy headers are set.
  • The audit log uses HMAC-SHA256 chain hashing and is verified at startup and on demand.
  • CaseCite holds no security certification (SOC 2, ISO 27001, HIPAA). SECURITY.md describes what it does and does not do and how to report a vulnerability; ROADMAP.md lists known gaps.

Connector caveats and the single case-law dependency

The sync API imports one folder (folder_id), or, with an explicit sync_all, the whole account. The UI has no folder picker yet, and “Sync Now” imports the whole connected account after a second confirmation that says so, so use the file pickers to bring in selected files. Clio's listing is account-wide, which means Clio cannot sync a single folder.

Filevine uses one firm-wide API key, so it remains off until FILEVINE_ENABLED=true, and then it is available only to admins. The iManage and NetDocuments connectors are implemented against the vendors' published APIs but have not been validated against a live tenant — test them in your environment before relying on them. Microsoft and Google connections request read-only scopes, and connections made before this release keep their broader grant until reconnected.

CourtListener is the only case-law source in the app, feeding Legal tools, Judge intel, Case view and the case-law side of the strategy engine. The app starts without a token, but the case-law half of the product is not usable with one missing: citation check hard-fails, because validate_citation refuses to run and returns a “token required” error that names where to set the token (_check_token in backend/app/services/courtlistener_client.py), while every other CourtListener call falls back to anonymous access, which is rate-limited hard enough that research features become unusable under any real load. A free token can be obtained from CourtListener and then set as COURTLISTENER_API_TOKEN in .env, saved instance-wide as an admin through Settings → API Keys, or POSTed to /api/v1/admin/integrations/courtlistener. The stored token overrides the .env value at runtime without a restart.

Case walkthrough: mapping one review cycle onto the features

The sequence below is a capability mapping for an evaluation team, not a measured client result; the product documentation describes functions rather than performance outcomes.

  • Corpus assembly. The team indexes its material through Documents, pulling existing files from Google Drive or OneDrive, or from Box, Dropbox, iManage, NetDocuments, Filevine or Clio where OAuth sync is acceptable; where that verification isn't feasible, the file picker covers the same need.
  • Practice framing. The reviewer states the practice area, CaseCite drafts the profile, and the reviewer edits it — after which that profile is present in every later review, redline and draft.
  • Research pass. Questions go to /research, where candidates are rescored by BM25 alongside semantic retrieval and answers arrive with inline citations, so each assertion can be traced before use.
  • Deal review. A contract under negotiation is analysed or chatted with in isolation, then compared against the standard clause-by-clause in a 2–4 set, and the analysis, redline or draft is exported.
  • Long-form drafting. A brief or agreement is drafted against up to four Knowledge Base documents; for a 30-page agreement the target length and section plan are approved first, sections are drafted in separate context windows and reconciled, and later revisions touch only the relevant sections.
  • Litigation posture. /judge-intel surfaces Judge analytics, /case/:id allows direct questioning of a CourtListener opinion, and /case-citations maps the authorities cited across the selected set.
  • Verification gate. Citation check scans citing opinions for negative-treatment language as a triage screen, not as a Shepard's or KeyCite replacement; final reliance stays with the lawyer and the citator.

Common misconceptions to correct before procurement

  • “Self-hosted means no third-party AI calls.” Storage is local, but embeddings and generation still transmit content to configured providers unless both OPENAI_BASE_URL and EMBEDDING_BASE_URL point at models you host.
  • “Source-available equals open source.” It is “Source-available,” not OSI “open source,” and Elastic License 2.0 bars offering the software to third parties as a hosted or managed service.
  • “The citation check is a citator.” It scans citing opinions for negative-treatment language and is not a Shepard's/KeyCite substitute.
  • “One server key gives us chargeback reporting.” Environment keys are pooled across users; per-user attribution needs per-user BYOK keys.
  • “The tamper-evident log is a certification.” The HMAC-SHA256 chain is an integrity mechanism, and no SOC 2 or ISO 27001 attestation is held.
  • “Everything is clickable on day one.” Matters, strategy briefs and Azure AD SSO are reachable over the API with no UI exposed yet.

API-only capabilities still in preview

These are implemented and reachable over the API, but the frontend does not expose them; treat them as preview:

  • Matters (/api/v1/matters) manage matter records, membership, and sharing of documents and chats between members. Creating matters and changing membership requires the matters.manage permission.
  • Strategy briefs (/api/v1/strategy) search each proposition on CourtListener, read candidate opinions, and keep a citation only when a verbatim quote can be located in the real opinion text; unsupported citations are dropped rather than shown.
  • Azure AD SSO performs backend token exchange only, with no sign-in button; SAML, generic OIDC and SCIM are not supported.

Everything else in the tool table, plus user administration and the audit log (Settings, admins only), has a UI.

Repository map for the technical reviewer

  • backend/ contains app/, where main.py runs the FastAPI app with middleware and health endpoints, config.py uses Pydantic settings, routers/ hold API routers, and services/ contain the RAG pipeline, ChromaDB/Pinecone abstraction, multi-provider embeddings, JWT auth, Matter strategy briefs and the CourtListener API; middleware/ handles security and CSRF, migrations/ contains Alembic migrations.
  • frontend/ contains src/ with App.tsx, per-domain API clients, page views, Zustand stores, shared components and modals, and the app shell layout.
  • scripts/ include backup and restore, production setup, key rotation and the NOTICE generator.
  • docs/ cover deployment, data flows, secret rotation, incident response and ADRs.
  • Dockerfile builds one unified image for frontend and backend; docker-compose.prod.yml bundles Caddy, Postgres, Redis and backend; docker-compose.yml targets use behind an existing proxy such as Coolify or Traefik with external Postgres and Redis; docker-compose.dev.yml supports local development.

Action recommendations for AI application owners

  1. Fix the egress policy first: are provider calls to OpenAI, Anthropic or Gemini under BYOK acceptable, or does the pilot require local chat plus local embeddings through the two base URL settings?
  2. Write the acceptance test around verifiability — inline citations to source, plus the standing rule that every answer, analysis and draft is checked against source documents and current law.
  3. Treat the practice profile as controlled content: assign an owner, review the generated draft, and archive the edited version as the firm's context baseline.
  4. Scope the pilot to one high-friction workflow, typically contract comparison in a 2–4 set or long-document drafting, before opening the case-law surfaces.
  5. Issue per-user BYOK keys from day one if chargeback matters; otherwise record explicitly that the server key cost is pooled.
  6. Back up SECRET_KEY off-server and rehearse the ENCRYPTION_SALT rotation procedure before go-live, since SECRET_KEY cannot be rotated safely.
  7. Validate the iManage and NetDocuments connectors in your own tenant, and keep Filevine enablement to admins via FILEVINE_ENABLED=true.
  8. Obtain the free CourtListener token before user acceptance testing; without it, citation check fails outright and the rest is rate-limited.
  9. Read SECURITY.md and ROADMAP.md with risk owners and log in writing that no SOC 2, ISO 27001 or HIPAA certification is claimed.
  10. Set TRUSTED_PROXIES, session limits and REQUIRE_MFA to your internal standard during the pilot rather than after it.

FAQ

Does CaseCite send our documents to the vendor?

No. There is no telemetry and nothing is sent to the CaseCite maintainers; content moves only to the AI and case-law providers you configure.

Can document text stay entirely inside our network?

Yes, by running both models yourself: set OPENAI_BASE_URL for chat and EMBEDDING_BASE_URL for embeddings to OpenAI-compatible servers you host. Setting only the chat endpoint still sends text to OpenAI for embedding.

Can we resell it to clients as a managed service?

No. Elastic License 2.0 permits internal self-hosting and modification, but not offering CaseCite to third parties as a hosted or managed service; paid private installs, support contracts and hosted-SaaS licensing run through SUPPORT.md.

What is the minimum stack to start?

Docker and Docker Compose, openssl for secret generation, and an AI provider API key — OpenAI is the simplest start because it covers chat and embeddings. The bundled stack already includes Postgres, Redis and Caddy, and the setup script automates secret creation and .env writing.

Which features are UI-complete today?

The Eight listed tools, plus user administration and the audit log. Matters, strategy briefs and Azure AD SSO are API-only and marked preview.

Is citation check enough for filing?

No. It scans citing opinions for negative-treatment language and is explicitly not a Shepard's/KeyCite substitute; verification against current law remains the lawyer's task.

Contributions are welcome for the source-available product — see CONTRIBUTING.md, with contributions licensed under ELv2. Questions on this evaluation brief can be sent to the IT Insights editorial desk at contact@itinsights.com.

By James Hartley, IT Insights — ItInsightsWorld, AIapplications

Brand logo

IT Insights

Cloud & Infrastructure Practice Media for Enterprise Technology Decision-Makers

Cloud ComputingSecuritySoftware DevelopmentAI ApplicationsStartupsGeneralAI Data News Global

© 2026 IT Insights.

Cookie Notice

We use cookies to improve your experience and analyze website traffic. Read our Privacy Policy to learn more.