Privacy-First Vector Database for Sensitive Data
Project description
VectorShield ๐ก๏ธ
Privacy-Preserving RAG Middleware โ Stop PII from reaching your vector database.
What is VectorShield?
VectorShield is a backend middleware layer that sits between your application and your vector database. It automatically detects and redacts Personally Identifiable Information (PII) and Protected Health Information (PHI) before embeddings and documents are stored โ ensuring that raw sensitive data never reaches persistent storage.
Privacy is enforced at the data ingestion layer, not at the LLM output layer.
Your App โ VectorShield โ ChromaDB / Pinecone / Weaviate
โ
PII detected & redacted
Embeddings generated from original (semantic quality preserved)
Only sanitised text stored
The Core Problem It Solves
RAG systems retrieve and store documents in vector databases. If those documents contain names, phone numbers, SSNs, emails, or medical data, that information becomes permanently embedded in your vector store โ queryable, retrievable, and at risk. VectorShield intercepts this data before it ever lands.
Key Features
- Parallel PII detection + embedding โ Both run concurrently using
asyncio.gatherto minimise latency overhead - Semantic quality preserved โ Embeddings are generated from the original text before redaction; only sanitised text is stored
- Redis-backed caching โ PII detection results are cached to eliminate redundant processing of repeated text
- Pluggable architecture โ Swap out any component (embedder, vector store, cache, tracker) with your own implementation
- Zero vendor lock-in โ Works with OpenAI, Cohere, Sentence-Transformers, Pinecone, Weaviate, Qdrant, Memcached, and more
- 9 PII entity types out of the box (PERSON, PHONE, EMAIL, SSN, CREDIT_CARD, LOCATION, DATE_TIME, MEDICAL_LICENSE, PASSPORT)
- Metrics & experiment tracking โ Optional MLflow integration for latency, cache hit rate, and PII entity counts
- Async-first โ Built for FastAPI and high-throughput batch ingestion
Architecture
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
โ IngestionPipeline โ
โ โ
โ Document โ [Cache Check] โ
โ โโ HIT โ reuse clean_text โ
โ โโ MISS โ parallel processing: โ
โ โโ PII Detection โ
โ โโ Embedding โ
โ โ โ
โ Redaction โ clean_text โ
โ โ โ
โ VectorStore.add_vectors( โ
โ embedding=from original, โ โ semantic quality
โ document=clean_text โ โ privacy safe
โ ) โ
โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
Privacy guarantee: The embedding captures the full semantic meaning of the original text. The stored document contains only the redacted version. The raw PII is never written to disk.
Installation
pip install vectorshield
With optional extras:
# Redis caching support
pip install vectorshield[redis]
# MLflow experiment tracking
pip install vectorshield[mlflow]
# All optional dependencies
pip install vectorshield[all]
System requirements:
- Python 3.9+
- FastEmbed downloads BAAI/bge-small-en-v1.5 (~130MB) on first run
- ChromaDB requires SQLite 3.35+ (standard on Ubuntu 22.04+, macOS 12+)
Quickstart
import asyncio
from vectorshield import IngestionPipeline, Document
async def main():
# Initialise with defaults (memory cache + ChromaDB + FastEmbed)
pipeline = IngestionPipeline()
await pipeline.initialize()
# Process a document containing PII
doc = Document(
id="doc_001",
text="Please call John Smith at 555-867-5309 or email john@example.com",
metadata={"source": "hr_system", "category": "employee"}
)
result = await pipeline.process_document(doc)
print(result.clean_text)
# โ "Please call <PERSON> at <PHONE_NUMBER> or email <EMAIL_ADDRESS>"
print(result.pii_entities)
# โ ["PERSON", "PHONE_NUMBER", "EMAIL_ADDRESS"]
print(result.embedding_preview)
# โ [0.023, -0.014, 0.091, ...] (384-dim from original text)
await pipeline.shutdown()
asyncio.run(main())
Batch Processing
async def batch_example():
pipeline = IngestionPipeline()
await pipeline.initialize()
documents = [
Document(id="1", text="Patient Jane Doe, SSN: 123-45-6789, admitted 12 Jan 2024"),
Document(id="2", text="Invoice for Robert Johnson, card ending 4532 1234 5678 9012"),
Document(id="3", text="Meeting notes from Q4 planning โ no PII here"),
]
result = await pipeline.process_batch(documents)
print(f"Processed: {result['total_processed']}")
print(f"Time: {result['total_time_seconds']}s")
for r in result["results"]:
print(f"[{r['id']}] PII found: {r['pii_found']}")
await pipeline.shutdown()
Configuration
VectorShield ships with safe defaults. Override only what you need:
config = {
# Cache
"cache_backend": "redis", # "memory" | "redis" | "none"
"redis_host": "localhost",
"redis_port": 6379,
"cache_ttl": 3600,
# Embeddings
"embedding_model": "BAAI/bge-small-en-v1.5",
# Vector store
"vectorstore_backend": "chroma",
"vectorstore_path": "./my_data",
"vectorstore_collection": "documents",
# Processing
"parallel_processing": True,
"max_batch_size": 100,
# Tracking (optional)
"tracking_enabled": True,
"tracking_backend": "mlflow",
"mlflow_tracking_uri": "http://localhost:5000",
}
pipeline = IngestionPipeline(config=config)
Or load from a YAML file:
pipeline = IngestionPipeline()
# In CLI:
# vectorshield process -i docs.json -c config.yaml
Custom Components
VectorShield's pluggable architecture lets you integrate any backend.
Custom Embedder (OpenAI)
from openai import OpenAI
client = OpenAI(api_key="sk-...")
pipeline = IngestionPipeline(
embed_func=lambda text: client.embeddings.create(
input=text,
model="text-embedding-3-small"
).data[0].embedding
)
Custom Cache (Existing Redis Client)
import redis, json
r = redis.Redis(host="localhost")
pipeline = IngestionPipeline(
cache_get_func=lambda k: json.loads(r.get(k)) if r.get(k) else None,
cache_set_func=lambda k, v, ttl: r.setex(k, ttl or 3600, json.dumps(v)),
)
Custom Vector Store (Pinecone)
from pinecone import Pinecone
pc = Pinecone(api_key="...")
index = pc.Index("my-index")
pipeline = IngestionPipeline(
add_vectors_func=lambda ids, embs, docs, meta: index.upsert(
vectors=[(id_, emb, {"text": doc, **(m or {})})
for id_, emb, doc, m in zip(ids, embs, docs, meta or [{}]*len(ids))]
),
search_func=lambda emb, k, filters: [
{"id": m["id"], "document": m["metadata"]["text"], "score": m["score"]}
for m in index.query(vector=emb, top_k=k, filter=filters).matches
]
)
CLI Usage
# Process documents from a JSON file
vectorshield process -i documents.json -o results.json
# With config and stats
vectorshield process -i documents.json -c config.yaml --stats
# Read from stdin
echo '{"documents": [{"id": "1", "text": "Call me at 555-0100"}]}' | vectorshield process
# Check version
vectorshield version
Input JSON format:
{
"documents": [
{"id": "doc_1", "text": "Contact Alice Brown at alice@corp.com", "metadata": {"source": "email"}},
{"id": "doc_2", "text": "Quarterly revenue report โ no PII", "metadata": {"source": "finance"}}
]
}
Metrics & Monitoring
# Get metrics after processing
metrics = pipeline.get_metrics()
print(metrics["overview"])
# โ {"total_documents": 50, "successful": 49, "failed": 1, "success_rate": "98.00%"}
print(metrics["privacy"])
# โ {"total_pii_entities_redacted": 87, "unique_pii_types": ["PERSON", "EMAIL_ADDRESS", ...]}
print(metrics["performance"])
# โ {"avg_latency_ms": "142.35", "min_latency_ms": "98.12", "max_latency_ms": "312.44"}
print(metrics["caching"])
# โ {"cache_hits": 23, "cache_misses": 27, "cache_hit_rate": "46.00%"}
PII Entity Types
| Entity | Example Input | Redacted Output |
|---|---|---|
| PERSON | John Smith |
<PERSON> |
| PHONE_NUMBER | 555-867-5309 |
<PHONE_NUMBER> |
| EMAIL_ADDRESS | john@example.com |
<EMAIL_ADDRESS> |
| CREDIT_CARD | 4532 1234 5678 9012 |
<CREDIT_CARD> |
| US_SSN | 123-45-6789 |
<US_SSN> |
| LOCATION | London, UK |
<LOCATION> |
| DATE_TIME | 12 January 2024 |
<DATE_TIME> |
| MEDICAL_LICENSE | MD-12345 |
<MEDICAL_LICENSE> |
| US_PASSPORT | A12345678 |
<US_PASSPORT> |
PII detection is powered by Microsoft Presidio.
Limitations & Honest Caveats
VectorShield is designed to reduce PII exposure in vector databases, not to provide absolute guarantees. Be aware of the following:
- Detection is probabilistic. Presidio uses NLP models โ novel PII formats, obfuscated data, or non-English text may not be caught. No detection system is 100% accurate.
- Embeddings encode semantics. Vector embeddings generated from PII-containing text may carry some semantic information about that PII, even if the stored text is redacted. This is a known limitation of the "embed-then-redact" pattern.
- Metadata is not redacted. VectorShield does not inspect or sanitise the
metadatadict you attach to documents. Ensure PII is not passed in metadata fields. - Not a compliance tool. VectorShield is a technical privacy control, not a legal compliance framework. It does not constitute GDPR, HIPAA, or CCPA compliance on its own.
- English-centric. The default Presidio configuration performs best on English-language text.
Comparison with Alternative Approaches
| Approach | VectorShield | On-device Anonymisation | Local LLM | Access Control Only |
|---|---|---|---|---|
| PII stored in vector DB | โ No | โ No | โ ๏ธ Depends | โ Yes |
| Semantic quality preserved | โ Yes | โ ๏ธ Partial | โ Yes | โ Yes |
| Requires local GPU | โ No | โ No | โ Yes | โ No |
| Scales to cloud RAG | โ Yes | โ ๏ธ Limited | โ Hard | โ Yes |
| Pluggable / vendor-agnostic | โ Yes | โ No | โ No | โ Yes |
Project Structure
vectorshield/
โโโ __init__.py # Public API
โโโ ingest.py # Core IngestionPipeline
โโโ interfaces/
โ โโโ cache.py # CacheBackend ABC
โ โโโ embedder.py # Embedder ABC
โ โโโ vectorstore.py # VectorStore ABC
โ โโโ tracker.py # Tracker ABC
โโโ implementations/
โ โโโ cache/
โ โ โโโ memory.py # MemoryCache
โ โ โโโ redis.py # RedisCache + NoOpCache
โ โ โโโ generic.py # GenericCache (custom functions)
โ โโโ embedder/
โ โ โโโ fastembed.py # FastEmbedEmbedder (default)
โ โ โโโ generic.py # GenericEmbedder (custom functions)
โ โโโ vectorstore/
โ โ โโโ chroma.py # ChromaVectorStore (default)
โ โ โโโ generic.py # GenericVectorStore (custom functions)
โ โโโ tracker/
โ โโโ mlflow.py # MLflowTracker + NoOpTracker
โโโ config/
โ โโโ defaults.py # DEFAULT_CONFIG
โ โโโ loader.py # load_config(), YAML support
โโโ stats.py # MetricsCollector, IngestionMetrics
โโโ cli.py # vectorshield CLI
Development Setup
git clone https://github.com/yourusername/vectorshield.git
cd vectorshield
python -m venv venv
source venv/bin/activate # Windows: venv\Scripts\activate
pip install -e ".[dev]"
# Run tests
pytest tests/ -v
# Run linter
ruff check vectorshield/
Contributing
Contributions are welcome. Please open an issue first to discuss significant changes.
- Fork the repo
- Create a feature branch (
git checkout -b feature/your-feature) - Commit changes (
git commit -m "Add your feature") - Push to branch (
git push origin feature/your-feature) - Open a Pull Request
Citation
If you use VectorShield in academic work, please cite:
@software{vectorshield2025,
title = {VectorShield: Privacy-Preserving Middleware for RAG Vector Databases},
author = {Your Name},
year = {2025},
url = {https://github.com/yourusername/vectorshield}
}
License
MIT License โ see LICENSE for details.
Acknowledgements
- Microsoft Presidio โ PII detection and anonymisation engine
- FastEmbed โ Lightweight CPU-friendly embedding library
- ChromaDB โ Persistent local vector database
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 vectorshield-0.0.1.tar.gz.
File metadata
- Download URL: vectorshield-0.0.1.tar.gz
- Upload date:
- Size: 41.0 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
db2be7b1f3e34b3a50fbd08c65412df054ce4a6113e89e879874357be5c0c9c5
|
|
| MD5 |
83ec792baa06d03ccd90488979b389d3
|
|
| BLAKE2b-256 |
d8094e489aa50d0710f213d90bb7c648d8c56127da56d5e6fa6bc3e4aef82573
|
Provenance
The following attestation bundles were made for vectorshield-0.0.1.tar.gz:
Publisher:
python-publish.yml on baihelahusain/VectorShield
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
vectorshield-0.0.1.tar.gz -
Subject digest:
db2be7b1f3e34b3a50fbd08c65412df054ce4a6113e89e879874357be5c0c9c5 - Sigstore transparency entry: 1010614988
- Sigstore integration time:
-
Permalink:
baihelahusain/VectorShield@dbc6b9e3e78bbd04b7c5aee3bcb15e9443daedc8 -
Branch / Tag:
refs/tags/v0.0.1 - Owner: https://github.com/baihelahusain
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@dbc6b9e3e78bbd04b7c5aee3bcb15e9443daedc8 -
Trigger Event:
release
-
Statement type:
File details
Details for the file vectorshield-0.0.1-py3-none-any.whl.
File metadata
- Download URL: vectorshield-0.0.1-py3-none-any.whl
- Upload date:
- Size: 49.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6cc5649ddf22813211c055186f0d22efaa2074e704afafb9988408c0e77b520a
|
|
| MD5 |
90bb33f8855c290a7831a7f60ddfcd1d
|
|
| BLAKE2b-256 |
09a45293f85936cd28a4c2840fe7c635e472b37357926640d2800c5df6674483
|
Provenance
The following attestation bundles were made for vectorshield-0.0.1-py3-none-any.whl:
Publisher:
python-publish.yml on baihelahusain/VectorShield
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
vectorshield-0.0.1-py3-none-any.whl -
Subject digest:
6cc5649ddf22813211c055186f0d22efaa2074e704afafb9988408c0e77b520a - Sigstore transparency entry: 1010615023
- Sigstore integration time:
-
Permalink:
baihelahusain/VectorShield@dbc6b9e3e78bbd04b7c5aee3bcb15e9443daedc8 -
Branch / Tag:
refs/tags/v0.0.1 - Owner: https://github.com/baihelahusain
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-publish.yml@dbc6b9e3e78bbd04b7c5aee3bcb15e9443daedc8 -
Trigger Event:
release
-
Statement type: