Building a Privacy Filter Before Your LLM API Call
Design a privacy filter that scans, redacts, or blocks sensitive input before every LLM request — architecture, failure modes, and testing.
Building a privacy filter before your LLM API call means inserting a dedicated preprocessing step that scans assembled prompt text for PII and secrets, applies your policy (allow, redact, or block), and only then forwards the sanitized payload to the model provider—with consistent logging, failure handling, and tests so sensitive data cannot bypass the gate through chat history, RAG chunks, or tool outputs. The privacy filter is not a single regex; it is a module with clear inputs, outputs, and ownership in your request path.
What the privacy filter covers
A production privacy filter should process everything the model will see:
| Input source | Risk | Include in scan |
|---|---|---|
| Latest user message | High | Yes |
| Prior chat turns | High | Yes (history compounding) |
| RAG retrieved chunks | High | Yes |
| System prompt variables | Medium | Yes |
| Tool/function outputs | High | Yes |
| Few-shot examples (dynamic) | Medium | Yes |
Missing one branch creates a bypass. See LLM Data Leakage for real-world paths.
Architecture
┌─────────────────────┐
│ Assemble context │
│ (user+RAG+tools) │
└──────────┬──────────┘
│
▼
┌─────────────────────┐
│ Privacy filter │
│ POST pii-secrets │
└──────────┬──────────┘
│
┌────────────────┼────────────────┐
▼ ▼ ▼
BLOCK REDACT ALLOW
(unsafe) (suspicious) (safe)
│ │ │
▼ ▼ ▼
User error redacted_text raw text
│ │ │
└────────────────┴────────────────┘
│
▼
┌─────────────────────┐
│ LLM provider API │
└─────────────────────┘
IdenticAPI endpoint: POST /api/v1/security/pii-secrets — documented in PII & Secrets Detection docs. Product overview: PII & Secrets Detection.
Core API contract
Request:
{
"text": "<full assembled prompt string>",
"redact": true
}
Response fields used by the filter:
verdict—safe|suspicious|unsafefindings— categories and offsetsredacted_text— whenredact: truerequest_id— audit correlation
Policy mapping (recommended):
| Verdict | Action | LLM payload |
|---|---|---|
safe | Allow | Original text |
suspicious | Redact | redacted_text |
unsafe | Block | No LLM call |
Secrets (unsafe) should not rely on redaction alone—see How to Prevent API Keys from Leaking into AI Prompts.
Implementation sketch
Pseudocode applicable to Node.js or Python services:
def privacy_filter(assembled_prompt: str) -> tuple[str, str]:
result = scan_pii_secrets(assembled_prompt, redact=True)
action = resolve_privacy_action(result.verdict)
if action == "block":
raise SecretsDetectedError(result.request_id)
if action == "redact" and result.redacted_text:
return result.redacted_text, result.request_id
return assembled_prompt, result.request_id
Full code: PII Detection in Python, PII Detection in Node.js.
Assembling context safely
Order of operations:
- Fetch RAG chunks from vector store
- Load sanitized chat history from your DB (store redacted versions if possible)
- Concatenate with clear delimiters (
--- user ---,--- context ---) - Run one scan on the full string (or scan components then merge—document either approach)
- Pass output to LLM client
Re-scan when tools append new content mid-turn before a follow-up model call.
Redaction vs tokenization
The API provides placeholder redaction ([EMAIL], [API_KEY]). If you need reversible tokens for internal tools, add a vault layer—compare approaches in PII Redaction vs Masking vs Tokenization.
Failure modes
| Failure | Symptom | Mitigation |
|---|---|---|
| Scanner timeout | Slow chat | Set timeouts; fail closed or queue |
| Scanner 503 | Outage | Fail closed for regulated apps |
| Partial scan (chunk only) | History leak | Scan full assembled prompt |
| Client-side only filter | API bypass | Enforce server-side |
| Logging before filter | Secrets in logs | Move filter before logger |
Document your fail closed vs fail open choice in runbooks.
Testing the filter
Synthetic fixtures:
safe: "What are your business hours?"
suspicious: "Email me at user@example.com"
unsafe: "Key: sk-test_abcdefghijklmnopqrstuvwxyz123456"
Integration tests:
- Assert LLM mock never receives raw string on
unsafe - Assert
redacted_textused onsuspicious - Assert
request_idlogged
Use PII Checker for exploratory cases.
Observability
Log structured events:
{
"event": "privacy_filter",
"request_id": "req_abc123",
"verdict": "suspicious",
"action": "redact",
"finding_categories": ["email", "phone"]
}
Dashboard metrics: scans per minute, block rate, top categories. Avoid logging prompt bodies in production.
Combining with other guards
Privacy filter addresses sensitive data. Pair with:
- Prompt injection screening for malicious instructions
- Output moderation for unsafe completions
- Agent action guard for tool policies
Order suggestion: injection scan → privacy filter → LLM → output moderation.
Limitations
- Regex detectors miss obfuscated PII
- 32,000-character limit requires splitting large contexts thoughtfully
- Filter does not classify legal basis for processing personal data
- Redaction may reduce answer quality for identity-specific queries—route those to authenticated tools
Review quarterly with PII and Secrets Leakage Checklist.
Related reading
Frequently asked questions
What is an LLM privacy filter?
A dedicated preprocessing module that scans assembled prompt text for PII and secrets, applies allow/redact/block policy, and only then forwards sanitized text to the model provider—with audit logging and defined failure behavior.
What inputs must the privacy filter include?
User messages, chat history, RAG chunks, tool outputs, and dynamic system prompt variables—everything the model will see in a single turn or assembled request.
What API does IdenticAPI provide for privacy filters?
POST /api/v1/security/pii-secrets with redact true for preprocessing. Map safe to allow, suspicious to redact using redacted_text, and unsafe to block without calling the LLM.
Does a privacy filter replace prompt injection detection?
No. Privacy filters address sensitive data. Prompt injection detection addresses malicious instructions. Many production stacks run both before the model call.
What happens if the privacy filter times out?
Define fail closed or fail open behavior in advance, set HTTP timeouts on scanner calls, alert on elevated error rates, and test outage behavior in staging.
Related reading
- How to Redact PII Before Sending Data to an LLM
Redact or mask sensitive data before it reaches an LLM. Learn preprocessing patterns, placeholder strategies, and when t…
- How to Detect PII in Text with an API
Use a PII detection API to scan user input, logs, and LLM context. Request format, response fields, verdict semantics, a…
- PII Detection in Node.js
Integrate PII and secrets detection in Node.js — server-side API calls, redaction options, and placement in Express or N…