Sign inSign up

noxway/privacy-guard

By noxway

•Updated 7 months ago

DSGVO/GDPR PII scanner & anonymizer for German text — regex-based, no ML inference at runtime

Image
Security
0

1.9K

noxway/privacy-guard repository overview

⁠privacy-guard

PyPI Python License: MIT Tests PyPI Publish Docker Publish Docker Hub

GDPR/DSGVO-compliant PII anonymisation for LLM workflows.

privacy-guard reliably detects personal data in German-language text, replaces it with stable placeholders, and enables clean restoration after processing. No ML-inference overhead at runtime for most detectors — clear results, API-ready.

privacy-guard hero

Highlights

  • 🔒 Compliance-first: protect sensitive data before it reaches external LLMs
  • ⚡ Runtime-friendly: regex/rule-based detectors without a heavy inference stack
  • 🔁 Deterministic: stable placeholders plus lossless restoration
  • 🐳 Deploy-ready: Python package and FastAPI/Docker available out of the box

⁠Why privacy-guard?

  • Protects sensitive data before sending it to external models
  • Replaces PII with deterministic placeholders such as [NAME_1], [IBAN_1]
  • Restores original values via ScanResult.restore()
  • Resolves overlapping matches with priority logic (e.g. SECRET > IBAN > SOCIAL_SECURITY > EMAIL > …)
  • Supports Python-package and FastAPI/Docker operation

⁠Detected PII Types

TypeExampleMethod
NAMEDr. Anna SchmidtspaCy NER (de_core_news_sm)
IBANDE89 3704 0044 0532 0130 00Regex + ISO 7064 check digit
CREDIT_CARD4111 1111 1111 1111Regex + Luhn algorithm
PERSONAL_IDC22990047Regex — Personalausweis & Reisepass (same format)
SOCIAL_SECURITY12 345678 X 123Regex — Rentenversicherungsnummer
KVNRT123456780Regex + §290 SGB V modified-Luhn check digit
TAX_ID12 345 678 903Regex + mod-11 check digit (§ 139b AO)
VAT_IDDE123456789Regex — Umsatzsteuer-Identifikationsnummer
PHONE+49 89 12345678Regex — DACH formats
EMAIL[email protected]Regex
ADDRESSHauptstraße 12, 79100 FreiburgRegex built from data files
LICENSE_PLATEB-AB 1234, HH-XY 12ERegex — Kfz-Kennzeichen inkl. E/H-Suffix
DRIVER_LICENSEMU010185A1Regex + Kontext-Fenster (±200 Zeichen)
SECRETAWS key, GitHub PAT, …100+ pattern rules (TOML)
URL_SECRET?token=abc123def456Regex — query parameter values

Overlap priority: SECRET = URL_SECRET > IBAN = CREDIT_CARD = SOCIAL_SECURITY = KVNR > PERSONAL_ID = TAX_ID = VAT_ID = EMAIL = DRIVER_LICENSE > PHONE = LICENSE_PLATE > ADDRESS > NAME

Public figures are excluded from masking by default via an internal whitelist (~1,000 entries).

⁠Installation

⁠Python Package
pip install privacy-guard-scanner

The name detector requires a spaCy model:

pip install "de_core_news_sm @ https://github.com/explosion/spacy-models/releases/download/de_core_news_sm-3.8.0/de_core_news_sm-3.8.0-py3-none-any.whl"
# or:
python -m spacy download de_core_news_sm
⁠API Stack (local)
pip install -e ".[api]"
uvicorn api.main:app --reload --port 8000

⁠Quickstart (Python)

from privacy_guard import PrivacyScanner

scanner = PrivacyScanner()

result = scanner.scan(
    "Bitte überweise 500 EUR an Hans Müller, "
    "IBAN DE89 3704 0044 0532 0130 00. "
    "Rückfragen an [email protected] oder +49 89 123456."
)

print(result.anonymised_text)
# Bitte überweise 500 EUR an [NAME_1], IBAN [IBAN_1]. Rückfragen an [EMAIL_1] oder [PHONE_1].

print(result.mapping)
# {'[NAME_1]': 'Hans Müller', '[IBAN_1]': 'DE89 3704 0044 0532 0130 00', ...}

llm_answer = "Vielen Dank, [NAME_1]. Die Daten zu [IBAN_1] sind verarbeitet."
print(result.restore(llm_answer))
# Vielen Dank, Hans Müller. Die Daten zu DE89 3704 0044 0532 0130 00 sind verarbeitet.

⁠Configuring the Scanner

from privacy_guard import PiiType, PrivacyScanner

scanner = PrivacyScanner(extra_whitelist_names=["Erika Musterfrau"])
scanner.disable_detector(PiiType.NAME)
scanner.enable_detector(PiiType.NAME)

result = scanner.scan("Contact: [email protected]")

Filtering specific findings:

from privacy_guard import PiiType

secrets = [f for f in result.findings if f.pii_type == PiiType.SECRET]
for finding in secrets:
    print(finding.rule_id, finding.text, finding.confidence)

⁠Web UI

The API server includes a built-in HTMX interface — no separate process, no CDN dependencies.

img.png

uvicorn api.main:app --reload
# → http://localhost:8000
⁠Login

An admin account with password admin is created by default (change via UI_ADMIN_PASSWORD). After login three tabs are available:

TabDescription
Live TestEnter text, select detectors, run a scan — view original and anonymised text side by side
HistoryAll your own scans (admins see all users); click a row to see finding details
DashboardOverall statistics, PII-type bar chart, scans-per-day line chart (Chart.js)

Admins additionally see the API Keys tab.

⁠API Key Management (Admin)

Use the 🔑 API Keys tab to create and revoke any number of API keys:

  1. Enter a name → Generate key
  2. Copy the full key (pg_…) — it is shown only once
  3. Only the SHA-256 hash is stored; the prefix (pg_xxxxxxxxx…) remains visible
  4. Keys can be revoked individually at any time

The key set via the API_KEY environment variable remains valid in parallel (backwards compatibility).

⁠REST API (Docker)

docker run -p 8000:8000 noxway/privacy-guard:latest

Or via Compose:

docker compose up
⁠Endpoints
MethodPathDescription
GET/healthLiveness check
POST/scanFull scan (findings + mapping + anonymised text)
POST/anonymizeReturn anonymised text only
⁠Request Body
{
  "text": "Hans Müller, IBAN DE89370400440532013000",
  "detectors": ["IBAN", "EMAIL"],
  "whitelist": ["Hans Müller"]
}
⁠Example with curl
curl -X POST http://localhost:8000/scan \
  -H "Content-Type: application/json" \
  -d '{"text": "Contact: [email protected], IBAN DE89370400440532013000", "detectors": ["EMAIL", "IBAN"]}'

With API key authentication:

curl -X POST http://localhost:8000/scan \
  -H "Content-Type: application/json" \
  -H "X-API-Key: pg_…" \
  -d '{"text": "[email protected]"}'

⁠Configuration

VariableDefaultDescription
API_KEYemptyIf set, X-API-Key must be sent with every request (env-var key or DB key)
CORS_ORIGINS*Comma-separated origins, e.g. https://app.example.com
UI_DB_PATHui.dbPath to the SQLite database (users, scans, API keys)
UI_ADMIN_PASSWORDadminPassword for the automatically created admin account

Example:

services:
  api:
    image: noxway/privacy-guard:latest
    ports:
      - "8000:8000"
    environment:
      API_KEY: my-secret-key
      CORS_ORIGINS: https://app.example.com
      UI_DB_PATH: /data/ui.db
      UI_ADMIN_PASSWORD: secure123
    volumes:
      - ui_data:/data

volumes:
  ui_data:

⁠Roadmap Ideas

  • Improved entity recognition for DACH address variants
  • Optional audit logging for compliance reports
  • Extended multilingual support beyond German
  • Check-digit validation for Personalausweis/Reisepass

⁠License

MIT. See LICENSE⁠.

Tag summary

Content type

Image

Digest

sha256:099d42d01…

Size

175.9 MB

Last updated

7 months ago

docker pull noxway/privacy-guard