Middleware that prevents sensitive information leakage in RAG pipelines by analyzing the context assembly graph
Project description
RagContextGuard
Prevent sensitive information leakage in RAG pipelines.
RagContextGuard is a lightweight Python middleware that analyzes retrieved document chunks before they reach your LLM. It detects when innocent-looking chunks combine to reveal secrets.
Installation
pip install -e .
This installs rag-context-guard with its dependencies (pyyaml).
Quick Demo
Run the included demo to see RagContextGuard in action:
python demo.py
The demo simulates a RAG retrieval with 3 chunks — one combines financial data with an entity identifier, triggering a policy violation.
Running Tests
The project includes a comprehensive test suite. Run it to verify the installation:
python test_comprehensive.py
Expected output: [PASS] All tests passed! (9/9 tests). If you've added custom policies or modified the engine, run this to verify correctness.
How It Works
- Classifications: Each chunk carries one or more labels (e.g.,
"financial","pii","confidential"). These come from your existing metadata or an optional LLM classifier you provide. - Set Analysis: RagContextGuard checks whether the union of all chunk classifications satisfies any policy rule's
trigger.all_presentcondition. - Path Analysis: Multi-hop collusion detection finds when a shared classification bridges two otherwise-safe rules, creating a dangerous combination.
- Actions: Rules can
block(halt pipeline) orwarn(log only).
Policy Format
Policies are YAML files. Create your own or use the built-ins.
rules:
- name: financial_entity_reveal
description: "Block combining financial metrics with entity identifiers"
action: block # or "warn"
trigger:
all_present:
- financial
- entity_identifier
message: "Financial data combined with entity identifier — client financials exposed"
Matching: A rule fires when all classifications listed in trigger.all_present appear across the retrieved chunk set (any chunk, any order). A chunk may carry multiple classifications.
Usage
from rag_context_guard import GuardMiddleware, policies
# Use built-in policy
guard = GuardMiddleware(policies.DEFAULT)
# Or your custom file
# guard = GuardMiddleware("my_policy.yaml")
Chunk format
Each chunk is a dict with:
text(str): The document contentmeta(dict): At minimum, includeclassification(str or list) orclassifications(list)
Any extra metadata fields are ignored by the policy engine.
Built-in Policies
| Policy | Use case | Rules |
|---|---|---|
policies.DEFAULT |
General data leakage prevention | 7 |
policies.FINANCE |
Financial services confidentiality | 6 |
policies.HIPAA |
Protected Health Information (PHI) | 6 |
policies.GDPR |
EU personal data compliance | 6 |
from rag_context_guard import GuardMiddleware, policies
guard = GuardMiddleware(policies.FINANCE)
Optional: LLM-Based Classification
If your chunks lack pre-computed classification metadata, you can provide a classifier function that runs an LLM to tag chunks:
from rag_context_guard import GuardMiddleware
from langchain_ollama import OllamaLLM # pip install langchain-ollama
The classifier is called only for chunks without existing classifications.
Running Tests
The project includes a comprehensive test suite:
python test_comprehensive.py
Expected output: [PASS] All tests passed! (9/9 tests). If you've added custom policies or modified the engine, run this to verify correctness.
API Reference
GuardMiddleware
Main entry point.
GuardMiddleware(policy_path=None, classifier=None)
policy_path:BuiltinPolicyconstant or path to YAML file (default: built-in DEFAULT)classifier: Optional callable(str) -> str | list[str] | None
Methods:
analyze(chunks: List[dict]) -> AnalysisResultget_rules() -> List[PolicyRule]
AnalysisResult
Returned by analyze():
is_safe: bool—Trueif no block violationsviolations: List[Violation]— all blocking issueswarnings: List[Violation]— all warn-level issuessafe_subset: List[Chunk]— chunks not involved in any block violationrisk_explanation: str— human-readable summary
Violation
rule_name: strmessage: strtriggering_chunks: List[Chunk]action: Action(Action.BLOCKorAction.WARN)
Creating Custom Policies
Copy src/rag_context_guard/policies/example.yaml and adapt:
rules:
- name: healthcare_pii_exposure
action: block
trigger:
all_present: [healthcare, pii]
message: "Healthcare data combined with PII — exposure risk"
Then load it:
guard = GuardMiddleware("my_policy.yaml")
Project Structure
rag-context-guard/
├── src/rag_context_guard/
│ ├── guard.py # GuardMiddleware
│ ├── graph_analyzer.py # Policy evaluation engine
│ ├── policy.py # YAML policy loader
│ ├── models.py # Dataclasses (Chunk, Violation, AnalysisResult)
│ └── policies/ # Built-in YAML policies
│ ├── default.yaml
│ ├── finance.yaml
│ ├── hipaa.yaml
│ └── gdpr.yaml
├── demo.py # Example usage (no external LLM needed)
├── test_comprehensive.py # Full test suite
├── pyproject.toml # Dependency + build config
└── README.md
License
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file rag_context_guard-0.1.0.tar.gz.
File metadata
- Download URL: rag_context_guard-0.1.0.tar.gz
- Upload date:
- Size: 11.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e485de17050c1bf171e44e10573afc44dd9236937431fe84edba59adab255fc9
|
|
| MD5 |
736e0dee7051e18d76180204311480b8
|
|
| BLAKE2b-256 |
448564b59736d904920571c6157dfa06ded82b0272ab5aba6000f23d3ce0e9f6
|
File details
Details for the file rag_context_guard-0.1.0-py3-none-any.whl.
File metadata
- Download URL: rag_context_guard-0.1.0-py3-none-any.whl
- Upload date:
- Size: 10.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a673101a6d6bf209c3f6a032db0c8f98ed3f893717c32e714da60f2eaa8bd54b
|
|
| MD5 |
e5d50e418fc102e9fb0a4ca40e935667
|
|
| BLAKE2b-256 |
960bd01c7d07951a9b9135dc70856e1b0961661a735ef8108274171145d02878
|