Skip to main content

Audit trail middleware for RAG pipelines in regulated industries

Project description

RAGCompliance

PyPI CI Python License

Audit trail middleware for RAG pipelines in regulated industries.

40 to 60 percent of RAG projects never reach production, not because the retrieval is bad but because compliance teams cannot sign off on a black box. RAGCompliance wraps any LangChain or LlamaIndex retrieval call and logs the full chain: query, retrieved chunks (with source URLs and similarity scores), LLM answer, and a SHA-256 signature tying them together. State lives in Supabase with row-level security per workspace. Drop-in, no chain rewrites.

Quickstart

pip install ragcompliance
pip install "ragcompliance[supabase,dashboard]"     # persistence + dashboard
pip install "ragcompliance[llamaindex]"             # optional LlamaIndex support

Copy .env.example to .env and fill in your values:

RAGCOMPLIANCE_SUPABASE_URL=https://your-project.supabase.co
RAGCOMPLIANCE_SUPABASE_KEY=your-service-role-key
RAGCOMPLIANCE_WORKSPACE_ID=your-workspace-id
RAGCOMPLIANCE_DEV_MODE=true   # logs to stdout in local dev

Run the SQL schemas once in your Supabase SQL editor:

-- paste supabase_schema.sql  (audit log table + RLS)
-- paste supabase_migration_billing.sql  (billing + usage RPC)

Usage (LangChain)

from ragcompliance import RAGComplianceHandler, RAGComplianceConfig

config = RAGComplianceConfig.from_env()
handler = RAGComplianceHandler(config=config, session_id="user-abc")

answer = chain.invoke(
    {"query": "What does section 4.2 of the contract say?"},
    config={"callbacks": [handler]},
)

Usage (LlamaIndex)

from llama_index.core import Settings
from llama_index.core.callbacks import CallbackManager
from ragcompliance import RAGComplianceConfig
from ragcompliance.llamaindex_handler import LlamaIndexRAGComplianceHandler

handler = LlamaIndexRAGComplianceHandler(
    config=RAGComplianceConfig.from_env(),
    session_id="user-abc",
)
Settings.callback_manager = CallbackManager([handler])

# Now any query engine runs under the audit handler.
response = query_engine.query("What does section 4.2 say?")

Every invocation writes an audit record like this:

{
  "id": "uuid",
  "session_id": "user-abc",
  "workspace_id": "my-workspace",
  "query": "What does section 4.2 of the contract say?",
  "retrieved_chunks": [
    {
      "content": "Section 4.2 defines indemnification...",
      "source_url": "https://storage/contract-v3.pdf",
      "chunk_id": "chunk-042",
      "similarity_score": 0.94
    }
  ],
  "llm_answer": "Section 4.2 covers indemnification obligations...",
  "model_name": "gpt-4",
  "chain_signature": "a3f8c2d1...",
  "timestamp": "2026-04-10T06:00:00Z",
  "latency_ms": 1240
}

Dashboard

pip install "ragcompliance[dashboard]"
uvicorn ragcompliance.app:app --reload

Open http://localhost:8000 for the audit dashboard. It ships with:

Endpoint Purpose
GET / HTML dashboard (stats cards + recent logs + export buttons)
GET /health Liveness probe
GET /api/logs Paginated audit records (JSON)
GET /api/logs/detail/{id} Single record
GET /api/logs/export.csv CSV export with filters
GET /api/logs/export.json JSON file export with filters
GET /api/summary Aggregate stats
GET /api/plans Available billing plans
POST /billing/checkout Start a Stripe Checkout session
POST /stripe/webhook Stripe event receiver (checkout, subscription, invoice)
GET /billing/subscription/{workspace_id} Current subscription + usage

Billing

Two plans:

Tier Price Queries / month Extras
Team $49 / mo 10,000 CSV/JSON export, email support
Enterprise $199 / mo Unlimited SSO, custom retention, SOC 2 on request

Start a checkout from your app:

import requests

r = requests.post(
    "https://your-dashboard.example.com/billing/checkout",
    json={"workspace_id": "my-workspace", "tier": "team"},
)
checkout_url = r.json()["checkout_url"]
# Redirect the user to checkout_url

Quota enforcement is soft by default (the chain logs a warning if the workspace is over its limit). Set RAGCOMPLIANCE_ENFORCE_QUOTA=true to hard-block instead.

Why RAGCompliance

Problem RAGCompliance
Compliance team cannot audit RAG decisions Full chain logged and signed
"Which document did the LLM use?" Source URL + chunk ID per retrieval
"Did the answer change over time?" SHA-256 signature per chain run
Multi-tenant SaaS Row-level security per workspace
Works with existing stack Drop-in callback for LangChain or LlamaIndex, no chain rewrites

Deploy

The dashboard is a single FastAPI app. The fastest path is Render's one-click from a repo:

  1. Create a new Web Service on https://render.com, pointing at this repo.
  2. Build command: pip install -e ".[supabase,dashboard,llamaindex]"
  3. Start command: uvicorn ragcompliance.app:app --host 0.0.0.0 --port $PORT
  4. Copy every variable from .env.example into Render's environment settings.
  5. After the service is live, update the Stripe webhook endpoint to https://<your-render-url>/stripe/webhook.

Fly.io, Railway, Cloud Run all work identically; the app is a stateless container.

Development

git clone https://github.com/dakshtrehan/ragcompliance
cd ragcompliance
python -m venv .venv && source .venv/bin/activate
pip install -e ".[dev,supabase,dashboard,llamaindex]"
pytest -v

Roadmap

  • LangChain callback handler
  • LlamaIndex callback handler
  • Dashboard export to CSV / JSON
  • Stripe billing + quota metering
  • Slack alerts for anomalous queries
  • SOC 2 report template generator
  • SSO (SAML / OIDC) on the dashboard

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

ragcompliance-0.1.0.tar.gz (23.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

ragcompliance-0.1.0-py3-none-any.whl (20.6 kB view details)

Uploaded Python 3

File details

Details for the file ragcompliance-0.1.0.tar.gz.

File metadata

  • Download URL: ragcompliance-0.1.0.tar.gz
  • Upload date:
  • Size: 23.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.12

File hashes

Hashes for ragcompliance-0.1.0.tar.gz
Algorithm Hash digest
SHA256 3cf2566e6aea1267a2119e36785c370753f1d04b25438b9a49631e7b40d1582a
MD5 f96560874bd1d91a9230cd3d04755c6a
BLAKE2b-256 38afa591a2d33a42f4915cc0ac3a4edc9733943c0ee42ead77912d5e5dec0a41

See more details on using hashes here.

File details

Details for the file ragcompliance-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: ragcompliance-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 20.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.12

File hashes

Hashes for ragcompliance-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7dd679d62a95b1e7e792fb468658dce8b3ee7b589d835ff7146fdd6874e2418d
MD5 d3e79a894fecefccaceee17f0668b08f
BLAKE2b-256 424370bda8e6678b32092d7e865edc7ab81054cb85ec425030a3d0b4bfa064e8

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page