From raw context to a redacted request
Install with python -m pip install pyveil, then run this complete example. Python 3.8+; no provider request.
import secrets
from pyveil import Channel, Veil
veil = Veil.high(secret=secrets.token_bytes(32), scope="support/session-42")
messages = [
{"role": "user", "content": "Email alice@example.com about ticket 42."},
]
safe = veil.redact_data(messages, channel=Channel.PROMPT_INPUT)
print(safe.data[0]["content"])
Output shape (the HMAC suffix varies):
Email [EMAIL:...] about ticket 42.
Pass safe.data to your SDK. Roles and ticket 42 survive; the original input is unchanged.
Reuse this redactor within a session. For stable placeholders across restarts, load a private key from your environment or secret manager.
Python quickstart and key handling →Only supported patterns are detected. Unknown names, addresses, images, and documents need a separate layer. See the detection board and limits.
One config. A real processed file.
python -m pip install pyveil==0.3.1
python -m pyveil init --example
python -m pyveil run
# Use --input /path/to/request.json
# instead of --example for your own file.
pyveil.json executable settings
.pyveil.key private local key
.pyveil-runs/<run-id>/
redacted.json actual processed data
receipt.json provenance, hashes, counts
The tutorial input is synthetic; processing uses the real installed redactor. No provider is called. Run twice for identical output bytes in separate directories. Install, run, reproduce, and handle failures.
Start with your integration
Installable provider helpers ship with pyveil. OpenAI Agents and LiteLLM wrappers are checkout recipes; each guide lists setup, keyless execution, and limits.
OpenAI Agents SDK
Redact initial input before Runner.run. Run the checkout example without an API key.
Setup and boundary →LiteLLM SDK and Proxy
Redact completion messages before dispatch. Compare the SDK wrapper and Proxy hook.
Setup and boundary →OpenAI, verified without a key
Inspect the exact redacted Responses API input and run a real SDK contract test without network usage.
Read →Claude, verified without a key
Redact Messages API content and verify its serialized request locally without consuming Claude credits.
Read →Ollama, local and memory-aware
Run a tested 4B model on a 16GB Mac and inspect the exact redacted prompt before local inference.
Read →Azure OpenAI, end to end
Load env or YAML, inspect the exact redacted prompt, then call the Azure v1 Responses API.
Read →Known names and domain IDs
Redact values your application already knows plus narrow customer, account, or project identifier patterns.
Read →Tool-call guard
Block auth headers, API keys, JWTs, private keys, and query secrets before model-controlled tools execute.
Read →MCP resource wrapper
Redact files, records, logs, and API payloads before returning MCP resource content to an agent.
Read →Memory write filter
Redact sensitive values before embedding and persisting long-lived agent memory.
Read →Logging filter
Attach a standard logging filter so records are redacted before handlers and external sinks.
Read →CLI preflight
Scan or redact files in local scripts and CI without adding runtime dependencies to your application.
Read →Guides for the question you are solving
Python LLM PII redaction
Protect prompts, provider payloads, tool calls, memory, and async web applications at the final local boundary.
Read the guide →MCP PII redaction
Redact tool results and resources, and block credentials before model-controlled MCP tools execute.
Read the guide →pyveil vs Presidio and DLP
Choose between a local boundary filter, NER, a guardrail suite, and enterprise DLP without inflated claims.
Compare approaches →Demo
The package keeps core behavior local, deterministic, and small: no network calls, no unmasking API, no third-party core dependency.