Overview
The PII Filter Service is a FastAPI sidecar that wraps the openai/privacy-filter model. When enabled, the Gurubase backend POSTs each user’s raw question to the sidecar before any downstream processing. The redacted text is then used for summary generation, vector search, memory retrieval, and persistence, so the raw question never reaches embeddings, prompts, or the memory store. This is complementary to regex-based PII Masking:- PII Masking applies operator-defined regex patterns to questions, file attachments, and indexed data sources.
- PII Filter Service runs a machine-learning model that detects PII spans (names, emails, dates, and similar) in user questions only, without per-pattern configuration.
503 rather than processed with unfiltered text.
Build and run the sidecar
The sidecar ships in the Gurubase backend repository undersrc/pii-filter-service/. It is a single Dockerfile with two flavors selected
at build time.
GET /health reports ok: true.
Sidecar configuration
Endpoints
Sample request:
Custom fine-tuned models
The model directory must follow the HuggingFacefrom_pretrained layout
(config.json, model.safetensors or pytorch_model.bin, tokenizer.json,
tokenizer_config.json, special_tokens_map.json) and must derive from
openai/privacy-filter so the architecture matches. Copy the checkpoint to the
host, then start the container with PII_FILTER_MODEL_PATH set to that path.
GET /health then reports model_path: /models/custom instead of <default>.
Wire the backend to the sidecar
Set the following environment variables on the Gurubase backend so the backend can reach the sidecar:
When the backend runs in Docker on the same host as a sidecar reached over an
SSH tunnel, use
http://host.docker.internal:8003 so the container resolves the
forwarded port.
Enable filtering
Two toggles control whether the filter actually runs. Both are reached via the Django admin on the self-hosted deployment.- Global default:
Settings.pii_filter_enabled(defaultfalse). - Per-guru override:
GuruType.pii_filter_enabled. Whennull(the default), the guru falls back to the global value. Setting it totrueorfalseoverrides the global default for that guru.
PII_FILTER_BASE_URL is set, every user
question is passed through POST /filter before the backend runs summary
generation, vector search, memory retrieval, or persistence.
If the resolved toggle is on but PII_FILTER_BASE_URL is empty, or the
sidecar returns an error, times out, or is unreachable, the backend returns
HTTP 503 with the message PII filtering is currently unavailable. Please try again shortly.
Operational notes
-
The filter is applied once per question at the earliest entry point, so
the
/api/v1path and the websummaryview both incur one sidecar roundtrip rather than two. - Empty or whitespace-only inputs are returned unchanged without calling the sidecar.
-
The sidecar binds to its own localhost by default. Expose it only on a
private network shared with the backend, or use an SSH tunnel during
development:
-
For local development, a compose file is provided at
src/pii-filter-service/.dev/docker-compose.yml. -
macOS hosts cannot use the GPU image; Apple Silicon GPUs are not NVIDIA. Use
the CPU image locally and the GPU image only on Linux with the NVIDIA
drivers and
nvidia-container-toolkitinstalled.