Skip to content

froyo75/PIILLMShield

Repository files navigation

PIILLMShield logo

A PII-aware LLM proxy that transparently detects and redacts sensitive information before requests reach the LLM provider.


How It Works

  1. Anonymize: Before reaching the LLM provider, sensitive input from the client is parsed and replaced with opaque placeholders using the open-source Presidio framework. The request content is checked against your configured entity patterns and built-in presets.
  2. Forward: The anonymized request is forwarded to the upstream LLM provider.
  3. Deanonymize: When the response comes back, placeholders are replaced with the original values to preserve context.
Client  ──request──► PIILLMShield (127.0.0.1:8888)  ──redacted request──► LLM provider
Client  ◄──restored─ PIILLMShield (127.0.0.1:8888) ◄──response────────── LLM provider

Supported Providers

Provider Format
OpenAI messages format, choices[].delta streaming
OpenRouter / Mistral / vLLM OpenAI-compatible
Anthropic content_block_delta streaming
Gemini contents format, candidates[].parts streaming
Ollama native message.content

Detection Modes

Mode Description
DEFAULT All built-in recognizers (shipped with Presidio, based on the configured language)
HYBRID Built-in recognizers + custom recognizers
CUSTOM Only allowed built-in recognizers + custom recognizers

Detection methods:

  • Regex-Based: Pattern matching with custom regular expressions.
  • Wordlists: Deny-list matching for specific terms.
  • NLP-Based: Contextual entity recognition using spaCy for natural language processing.

Web UI

A web dashboard is available to manage providers, entities, and analyzer configuration. A simulator is also provided to test custom recognizers.

PIILMSHIELD UI

Statistics

PIILMSHIELD UI

  • Anonymized inputs: Total number of PII entities detected and replaced with placeholders across all requests.
  • Deanonymized OK: Number of LLM responses where all placeholders were successfully replaced back to their original values (input-level success).
  • Deanonymized failures: Number of LLM responses where some placeholders could not be replaced (e.g., the LLM modified or invented a placeholder that doesn't exist in memory).
  • Placeholders replaced: Total count of individual placeholders successfully swapped back to originals across all responses.
  • Placeholders failed: Total count of individual placeholders that remained unreplaced across all responses.

Installation

git clone https://github.com/froyo75/PIILLMShield.git
cd PIILLMShield

Backend

Create a new Python virtual environment, activate it, and install the dependencies:

python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

Download the spaCy NLP model (required for entity recognition):

# Default model (recommended for production, ~560MB)
python -m spacy download en_core_web_lg

# Lightweight alternative (faster, lower recall, ~12MB)
python -m spacy download en_core_web_sm

# Transformer model (best quality, slow on CPU, ~450MB)
python -m spacy download en_core_web_trf

Note: If using the spacy engine (default), only the model set in nlp_model (e.g., en_core_web_lg) is required. The tokenizer_model (e.g., en_core_web_sm) is only needed if you switch to the transformers engine.

Frontend

Build the UI from the ui directory:

cd ui
npm install
node scripts/gen-icons.mjs   # generate PWA icons
npm run build
cd ..

The built UI (ui/dist/) is served automatically by the Python backend.

Setup & Start

Use the provided .env.example file to create your .env configuration, then start the app.

cp .env.example .env

Start the shield proxy:

python main.py

The dashboard is now available at http://127.0.0.1:8888.

Connect Your LLM Client

Configure your favorite LLM client to use the proxy. The base URL depends on the client:

  • Most clients (Open WebUI, LibreChat, OpenAI SDK, etc.) set the base URL to http://127.0.0.1:8888 (/v1 is appended automatically).
  • Some clients (OpenCode with @ai-sdk/openai-compatible) set the base URL to http://127.0.0.1:8888/v1.

Example: OpenCode

{
  "$schema": "https://opencode.ai/config.json",
  "model": "pii-proxy/z-ai/glm-5.2",
  "provider": {
    "pii-proxy": {
      "npm": "@ai-sdk/openai-compatible",
      "name": "PII Proxy",
      "options": {
        "baseURL": "http://127.0.0.1:8888/v1"
      },
      "models": {
        "z-ai/glm-5.2": {}
      }
    }
  },
  "share": "disabled",
  "experimental": {
    "openTelemetry": false
  },
  "permission": {
    "edit": "ask",
    "bash": "ask",
    "webfetch": "ask",
    "tools": {
      "write": "ask",
      "patch": "ask"
    },
    "external_directory": "deny"
  }
}

Using Docker

Build and start the app using Docker Compose:

docker compose up -d

About

A PII-aware LLM proxy that transparently detects and redacts sensitive information (email addresses, phone numbers, credit card numbers, IBANs, company names, etc.).

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors