PII Gateway
Self-hosted API that redacts personal data from JSON and text via policy rules plus best-effort NLP.
- Python
- FastAPI
- Presidio
- Next.js
- PostgreSQL
- Docker
- APScheduler
Case study
In brief
Problem
Teams sending customer data to analytics, logs, or third-party tools need consistent redaction before it leaves their environment—not ad hoc scripts per pipeline.
Approach
Shipped a Docker-first FastAPI service with Microsoft Presidio for NLP detection, a mounted policy file for entity rules, and POST /v1/sanitize for live JSON and text.
Outcome
Optional scheduled jobs pull PostgreSQL exports and CSV or JSON inbox files. Undeclared structured fields still get scanned so nothing slips through by default.
Look closer
Stage
Proof
Self-hosted API that redacts personal data from JSON and text via policy rules plus best-effort NLP.
Proof
# PII Gateway — sample sanitize request
POST /sanitize HTTP/1.1
Host: localhost:8080
Content-Type: application/json
X-API-Key: pk_live_••••••••••••••••
{
"text": "Contact Jane Doe at [email protected] or +64 21 555 1234.",
"policy": "default"
}
---
HTTP/1.1 200 OK
Content-Type: application/json
{
"sanitized": "Contact <PERSON> at <EMAIL_ADDRESS> or <PHONE_NUMBER>.",
"entities": [
{ "type": "PERSON", "start": 8, "end": 16, "score": 0.91 },
{ "type": "EMAIL_ADDRESS", "start": 20, "end": 38, "score": 0.99 },
{ "type": "PHONE_NUMBER", "start": 42, "end": 58, "score": 0.97 }
],
"policy_version": "2026-03",
"latency_ms": 42
}
# batch ingest (scheduled)
# PostgreSQL export → CSV inbox → APScheduler job → S3 outboxArchitecture
C4 architecture — Context → Containers → Components (docs/c4/portfolio-map.json)
Architecture
- Person
- Software system
- External system