🛡️ CloakLLM
Cloak your prompts. Prove your compliance.
Every prompt you send to an LLM provider is visible in plaintext — names, emails, SSNs, API keys, medical records. CloakLLM intercepts, cloaks, and audits every call.
┌──────────────┐ ┌─────────────────────┐ ┌──────────────┐
│ Your App │───▶│ CLOAKLLM │───▶│ Claude/GPT │
│ │ │ │ │ /Gemini │
│ "Email │ │ "Email [PERSON_0] │ │ │
│ john@..." │ │ [EMAIL_0]..." │ │ Never sees │
│ │◀───│ │◀───│ real data │
└──────────────┘ └─────────────────────┘ └──────────────┘
│
┌─────────────┐
│ Hash-Chain │
│ Audit Log │
│ (EU AI Act) │
└─────────────┘
> **Also available for JavaScript/TypeScript:** `npm install cloakllm` — zero dependencies, OpenAI SDK integration. See [CloakLLM JS](https://github.com/cloakllm/CloakLLM-JS). | [Project Hub](https://github.com/cloakllm/CloakLLM)
⏰ Why Now?
EU AI Act enforcement begins August 2, 2026. Article 12 requires tamper-evident audit logs that regulators can mathematically verify. Non-compliance: up to 7% of global annual revenue.
Your current logging (logger.info()) won't survive an audit. CloakLLM provides:
- 🔒 PII Detection — Names, emails, SSNs, API keys, IPs, credit cards, IBANs via NER + regex
- 🎭 Context-Preserving Cloaking —
John Smith→[PERSON_0](the LLM still understands the prompt) - ⛓️ Tamper-Evident Audit Chain — Every event hash-linked. Any tampering breaks the chain.
- ⚡ One-Line Middleware — Drop-in protection for OpenAI SDK and LiteLLM (100+ providers)
🚀 Quick Start
Install
pip install cloakllm # core install: regex detection, tokenization, audit (no NER)
pip install cloakllm[detection] # + spaCy NER (PERSON/ORG/GPE) — recommended
pip install cloakllm[litellm] # with LiteLLM integration
python -m spacy download en_core_web_sm # NER model (needs [detection])
v0.12.0: spaCy moved to the
[detection]extra so the core install is dependency-free (which enables the leancloakllm-verifier). Without[detection], detection is regex-only and PERSON/ORG/GPE may be missed — install the extra to keep pre-0.12 behavior.
Option A: With OpenAI SDK (one line)
from cloakllm import enable_openai
from openai import OpenAI
client = OpenAI()
enable_openai(client) # Done. All calls are now cloaked.
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": "Email john@acme.com about Project X"}]
)
# Provider never sees "john@acme.com" — only "[EMAIL_0]"
# Response is automatically uncloaked before you see it
Option B: With LiteLLM (one line)
import cloakllm
cloakllm.enable() # Done. All LiteLLM calls are now cloaked.
import litellm
response = litellm.completion(
model="anthropic/claude-sonnet-4-20250514",
messages=[{"role": "user", "content": "Email john@acme.com about Project X"}]
)
# Provider never sees "john@acme.com" — only "[EMAIL_0]"
# Response is automatically uncloaked before you see it
Option C: Standalone
from cloakllm import Shield
shield = Shield()
# Cloak
cloaked, token_map = shield.sanitize(
"Send report to john@acme.com, SSN 123-45-6789"
)
# cloaked: "Send report to [EMAIL_0], SSN [SSN_0]"
# ... send cloaked prompt to any LLM ...
# Uncloak response
clean = shield.desanitize(llm_response, token_map)
Redaction Mode (irreversible)
from cloakllm import Shield, ShieldConfig
shield = Shield(ShieldConfig(mode="redact"))
redacted, _ = shield.sanitize("Email john@acme.com about Sarah Johnson")
# redacted: "Email [EMAIL_REDACTED] about [PERSON_REDACTED]"
# No token map stored — cannot be reversed
Entity Details (compliance metadata)
from cloakllm import Shield
shield = Shield()
sanitized, token_map = shield.sanitize("Email john@acme.com, SSN 123-45-6789")
# Per-entity metadata (no original text — PII-safe)
token_map.entity_details
# [
# {"category": "EMAIL", "start": 6, "end": 19, "length": 13, "confidence": 0.95, "source": "regex", "token": "[EMAIL_0]"},
# {"category": "SSN", "start": 25, "end": 36, "length": 11, "confidence": 0.95, "source": "regex", "token": "[SSN_0]"}
# ]
# Full report for dashboards
token_map.to_report()
# {"entity_count": 2, "categories": {...}, "tokens": [...], "mode": "tokenize", "entity_details": [...]}
Option D: CLI
# Scan text for sensitive data
python -m cloakllm scan "Email john@acme.com, SSN 123-45-6789"
# Verify audit chain integrity
python -m cloakllm verify ./cloakllm_audit/
# View audit statistics
python -m cloakllm stats ./cloakllm_audit/
⛓️ Tamper-Evident Audit Chain
Every cloaking event is recorded in a hash-chained append-only log:
{
"seq": 42,
"event_id": "a1b2c3d4-...",
"timestamp": "2026-02-27T14:30:00+00:00",
"event_type": "sanitize",
"model": "claude-sonnet-4-20250514",
"entity_count": 3,
"categories": {"PERSON": 1, "EMAIL": 1, "SSN": 1},
"tokens_used": ["[PERSON_0]", "[EMAIL_0]", "[SSN_0]"],
"prompt_hash": "sha256:9f86d0...",
"sanitized_hash": "sha256:a3f2b1...",
"entity_details": [
{"category": "PERSON", "start": 0, "end": 10, "length": 10, "confidence": 0.85, "source": "spacy", "token": "[PERSON_0]"},
{"category": "EMAIL", "start": 12, "end": 25, "length": 13, "confidence": 0.95, "source": "regex", "token": "[EMAIL_0]"},
{"category": "SSN", "start": 27, "end": 38, "length": 11, "confidence": 0.95, "source": "regex", "token": "[SSN_0]"}
],
"latency_ms": 4.2,
"prev_hash": "sha256:7c4d2e...",
"entry_hash": "sha256:b5e8f3..."
}
Chain verification:
python -m cloakllm verify ./cloakllm_audit/
# ✅ Audit chain integrity verified — no tampering detected.
If anyone modifies a single entry, every subsequent hash breaks:
Entry #40 ✅ → #41 ✅ → #42 ❌ TAMPERED → #43 ❌ BROKEN → ...
This is what EU AI Act Article 12 requires.
⚙️ Configuration
from cloakllm import Shield, ShieldConfig
shield = Shield(config=ShieldConfig(
# Detection
spacy_model="en_core_web_lg", # Larger model = better accuracy
detect_emails=True,
detect_phones=True,
detect_api_keys=True,
custom_patterns=[ # Your own regex patterns
("PROJECT_CODE", r"PRJ-\d{4}-\w+"),
("INTERNAL_ID", r"EMP-\d{6}"),
],
# Audit
log_dir="./compliance_audit",
log_original_values=False, # Never log original PII
# Middleware
skip_models=["ollama/", "local/"], # Don't cloak local model calls
))
LLM Detection (opt-in) — uses a local Ollama instance to catch semantic PII (addresses, medical info, etc.):
shield = Shield(config=ShieldConfig(
llm_detection=True, # Enable LLM-based detection
llm_model="llama3.2", # Ollama model to use
llm_ollama_url="http://localhost:11434", # Ollama endpoint
llm_timeout=10.0, # Timeout in seconds
llm_confidence=0.85, # Confidence score for LLM detections
))
Environment variables:
CLOAKLLM_LOG_DIR=./audit
CLOAKLLM_SPACY_MODEL=en_core_web_sm
CLOAKLLM_OTEL_ENABLED=true
CLOAKLLM_LLM_DETECTION=true
CLOAKLLM_LLM_MODEL=llama3.2
CLOAKLLM_OLLAMA_URL=http://localhost:11434
🔍 What Gets Detected
| Category | Examples | Method |
|---|---|---|
PERSON |
John Smith, Sarah Johnson | spaCy NER |
ORG |
Acme Corp, Google | spaCy NER |
GPE |
New York, Israel | spaCy NER |
EMAIL |
john@acme.com | Regex |
PHONE |
+1-555-0142, 050-123-4567 | Regex |
SSN |
123-45-6789 | Regex |
CREDIT_CARD |
4111111111111111 | Regex |
IP_ADDRESS |
192.168.1.100 | Regex |
API_KEY |
sk-abc123..., AKIA... | Regex |
IBAN |
DE89370400440532013000 | Regex |
JWT |
eyJhbGciOi... | Regex |
| Custom | Your patterns | Regex |
ADDRESS |
742 Evergreen Terrace | LLM (Local) |
DATE_OF_BIRTH |
1990-01-15 | LLM (Local) |
MEDICAL |
diabetes mellitus | LLM (Local) |
FINANCIAL |
account 4521-XXX | LLM (Local) |
NATIONAL_ID |
TZ 12345678 | LLM (Local) |
BIOMETRIC |
fingerprint hash | LLM (Local) |
USERNAME |
@johndoe42 | LLM (Local) |
PASSWORD |
P@ssw0rd123 | LLM (Local) |
VEHICLE |
plate ABC-1234 | LLM (Local) |
🗺️ Roadmap
- PII detection (NER + regex)
- Deterministic tokenization
- Hash-chain audit logging
- LiteLLM middleware integration
- OpenAI SDK middleware integration
- CLI tool
- Redaction / scrubbing mode
- Field-level PII metadata (entity_details)
- OpenTelemetry span emission (with auto-redaction)
- RFC 3161 trusted timestamping
- Signed audit snapshots
- MCP security gateway (tool validation, permission enforcement)
- Local LLM detection (opt-in, via Ollama)
- Sensitivity-based routing (PII → local model, general → cloud)
- Admin dashboard
- EU AI Act conformity report generator
📜 License
MIT
🤝 Contributing
PRs welcome. Highest-impact areas:
- Non-English NER — Hebrew, Arabic, Chinese PII detection
- De-tokenization accuracy — handling LLM paraphrasing
- OpenTelemetry integration — GenAI semantic conventions
- MCP security — tool validation middleware
Built for the EU AI Act deadline. Ships before the auditors do.
Release files for cloakllm 0.12.6
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| cloakllm-0.12.6.tar.gz | 305.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| cloakllm-0.12.6-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 466.9 kB
Release files / cloakllm-0.12.6.tar.gz
| Download URL | cloakllm-0.12.6.tar.gz |
|---|---|
| Size | 305.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3ed2015b45f29364fe149670aa3528b702da4d4bbdb69e287d799358ac82c717
|
|
BLAKE2b-256 checksum How to use checksums |
3da833ccd17b302d05534e56388fe93804f9a3e35a4b3f9effa399d6ec854622
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 20, 2026.
Transparency logRelease files / cloakllm-0.12.6-py3-none-any.whl
| Download URL | cloakllm-0.12.6-py3-none-any.whl |
|---|---|
| Size | 161.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
cdb94ff5f848d989e756efd9123f4ddc407a0bec7f3592d226a74646440045a2
|
|
BLAKE2b-256 checksum How to use checksums |
c708c3a266f8aad4ef8016e1583b85562858e08a2b56ffeb27fb8b25f0d9d35b
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 20, 2026.
Transparency log