[!IMPORTANT] PII masking is an optional feature, off by default. When enabled (pip install 'qwed[pii]'andmask_pii=True), it detects Personally Identifiable Information (PII) such as emails, card numbers and SSNs and replaces it with placeholders before the query is sent to the LLM provider. It reduces what the provider sees; it does not by itself make a system compliant with HIPAA, GDPR, PCI-DSS or any other regulation.
📋 Table of contents
- What is PII Masking?
- Why It Matters
- Installation
- Quick Start
- Supported PII Types
- Usage Examples
- Enterprise Use Cases
- How It Works
- Configuration
- Limitations
- FAQ
What is PII masking?
PII (Personally Identifiable Information) masking automatically detects and replaces sensitive data with placeholders before sending queries to LLM providers. Example:Why it matters
The problem
When you send queries to cloud LLM providers (OpenAI, Anthropic, etc.), your data passes through their servers:- 💳 Credit card numbers exposed
- 📧 Email addresses harvested
- 🔢 SSNs leaked
- 📞 Phone numbers stored
- 🏥 Medical data (protected health information)
The solution
QWED masks PII before sending to LLMs:- ✅ Detected PII is replaced before the provider call
- ✅ A record of what was masked in
evidence['pii_masked'] - ✅ A control you can use as part of your own HIPAA, GDPR or PCI-DSS programme; it does not make a system compliant on its own
Installation
Step 1: install the PII extra
PII masking requires Microsoft Presidio (optional dependency):Step 2: download the spaCy model
Presidio uses spaCy for NLP:Verify installation
Quick start
Python API
CLI
Supported PII types
QWED detects 9 types of PII using Microsoft Presidio:Detection examples
Usage examples
Example 1: healthcare
Scenario: Medical assistant built on an LLM- ✅ Detected identifiers (name, SSN, email) are replaced before the cloud call
- ✅ What was masked is recorded in the evidence
- ⚠️ Undetected PHI is still sent; masking alone does not make the workflow HIPAA compliant
Example 2: finance
Scenario: Fraud detection system- ✅ Detected card numbers are replaced before the LLM call
- ⚠️ PCI-DSS scope depends on your whole system, not on this setting
- ✅ Works with local LLMs (zero cloud exposure)
Example 3: legal (attorney-client privilege)
Scenario: Contract analysisHow it works
Architecture
Detection process
- Analyze: Presidio scans text for PII patterns
- Detect: Identifies entity types and positions
- Mask: Replaces with
<ENTITY_TYPE>placeholders - Send: Masked text goes to LLM
- Evidence: PII metadata saved for audit
One-way masking
QWED uses non-reversible masking:- ✅ Simple and secure
- ✅ No mapping tables to leak
- ✅ “Proving without revealing”
Configuration
Custom entity types
Only detect specific PII types:Disable for specific queries
Environment-based
Limitations
1. Detection accuracy
- False Positives: May mask non-PII (e.g., “john” as name)
- False Negatives: May miss obfuscated PII
- Language: English only (v2.2.0)
2. Performance
- Latency: Adds ~100-200ms per query
- Memory: Requires ~150MB for spaCy model
3. Context loss
Masked data loses semantic meaning:FAQ
Q: Does PII masking work with Ollama?
A: Yes! In fact, it’s perfect for Ollama:- ✅ LLM runs locally
- ✅ PII masked locally
- ✅ Zero cloud exposure
Q: What if Presidio isn’t installed?
A: Graceful error with install instructions:Q: Can I see what was masked?
A: Yes! Check the evidence:Q: Does it work with caching?
A: Yes! Cached results also include PII info.Q: What’s the performance impact?
A: Typically 100-200ms added latency. Negligible compared to LLM API call (~1-3s).Q: Is it secure?
A: Yes:- ✅ Runs locally (not a cloud service)
- ✅ Microsoft Presidio (production-tested at Microsoft)
- ✅ No data sent to QWED servers
- ✅ One-way masking (no reverse mapping)
Enterprise use cases
Healthcare: protected health information
Finance: card and account data
Legal: data privacy laws
Next steps
- Install:
pip install 'qwed[pii]' - Test:
qwed pii "your sensitive text" - Integrate: Add
mask_pii=Trueto your code - Audit: Check
evidence['pii_masked']to see what was masked