Framework for redacting and revealing PII.
Project description
🕶️ VeilData
A lightweight framework for redacting and revealing Personally Identifiable Information (PII).
🧠 Why VeilData
Modern AI systems touch sensitive data every day.
VeilData makes it easy to redact, anonymize, and later restore information.
🚀 Quick Start
Installation
From PyPI
pip install veildata
Run from Docker
docker build -t veildata .
alias veildata="docker run --rm -v \$(pwd):/app veildata"
veildata redact data/input.csv --out data/redacted.csv
Running in Docker
docker build -t veildata .
docker run -it ghcr.io/veildata/veildata:latest
For Development
git clone https://github.com/VeilData/veildata.git
cd veildata
curl -LsSf https://astral.sh/uv/install.sh | sh
uv venv
uv sync
Quickstart Guide
Mark sensitive data
veildata redact input.txt
Example config.yaml
patterns:
EMAIL: "\\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Z|a-z]{2,}\\b"
Reveal previously redact data
veildata reveal redacted.txt
** Using Docker**
docker run --rm -v $(pwd):/app veildata redact input.txt --out redacted.txt
File Input/Output (CLI)
Redact a file, save the output, and keep a token store for reversibility:
veildata redact input.txt --output redacted.txt --store store.json
Reveal the file using the stored tokens:
veildata reveal redacted.txt --store store.json
Python SDK Examples
Regex-based Redaction
from veildata import Compose, RegexRedactor, TokenStore
# Create a shared TokenStore for reversible Redaction
store = TokenStore()
# Define your Redaction pipeline with the shared store
redactor = Compose([
RegexRedactor(r"[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,}", store=store), # email
RegexRedactor(r"\b\d{3}-\d{3}-\d{4}\b", store=store), # phone
])
text = "Contact John at john.doe@example.com or call 123-456-7890."
# --- redact the data ---
redacted_text = redactor(text)
print(redacted_text)
# -> Contact John at [REDACTED_1] or call [REDACTED_2].
# --- reveal it later ---
revealed_text = store.reveal(redacted_text)
print(revealed_text)
# -> Contact John at john.doe@example.com or call 123-456-7890.
spaCy Named Entity Recognition
# Requires `pip install veildata[spacy]`
from veildata.redactors.ner_spacy import SpacyNERRedactor
from veildata import TokenStore
# Shared token store for reversible revealing
store = TokenStore()
redactor = SpacyNERRedactor(
entities=["PERSON", "ORG"],
store=store
)
text = "Apple was founded by Steve Jobs in Cupertino."
redacted = redactor(text)
print(redacted) # -> [REDACTED_1] was founded by [REDACTED_2] in Cupertino.
BERT NER Redaction
# Requires `pip install veildata[bert]`
from veildata.redactors.ner_bert import BERTNERRedactor
from veildata import TokenStore
store = TokenStore()
redactor = BERTNERRedactor(
model_name="dslim/bert-base-NER",
store=store
)
text = "John Smith works at Google in New York."
redacted = redactor(text)
print(redacted) # -> [REDACTED_1] works at [REDACTED_2] in [REDACTED_3].
File Input/Output
from pathlib import Path
from veildata import Compose, RegexRedactor, TokenStore
# Setup redactor
store = TokenStore()
redactor = Compose([
RegexRedactor(r"\b\d{3}-\d{3}-\d{4}\b", store=store)
])
# Read from file
input_path = Path("input.txt")
if input_path.exists():
text = input_path.read_text()
# redact
redacted_text = redactor(text)
# Write to file
Path("redacted.txt").write_text(redacted_text)
# Save store for later revealing
store.save("store.json")
⚙️ CLI Configuration
spaCy PII Detection
ml:
spacy:
enabled: true
model: "en_core_web_lg"
pii_labels:
- PERSON
- ORG
- GPE
- LOC
- NORP
BERT-Style PII Detection
ml:
bert:
enabled: true
model_path: "models/pii-bert-base"
threshold: 0.5
label_mapping:
EMAIL: ["B-EMAIL", "I-EMAIL"]
PHONE: ["B-PHONE", "I-PHONE"]
SSN: ["B-SSN", "I-SSN"]
Hybrid Detection
When using --detect-mode hybrid:
- Run regex rules on text → produce spans with types
- Run ML/NLP engines (spaCy + BERT) → produce spans with types + scores
- Merge spans:
- If spans overlap with same type → keep the union
- If spans overlap with different types → configurable resolution
options:
detect_mode: hybrid # default: rules
hybrid:
prefer: ml # ml | rules | longest_span
🛠️ Continuous Integration
- CI: .github/workflows/ci.yml runs linting, formatting, build, and tests on every push or PR.
- Publish: .github/workflows/publish.yml auto-publishes to PyPI when a new v* tag or release is created.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file veildata-0.2.0.tar.gz.
File metadata
- Download URL: veildata-0.2.0.tar.gz
- Upload date:
- Size: 34.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c917a51ff2ea886eb3061cf0f6df1c2acc815a5bd01c6669887d2ef8f88ca5a4
|
|
| MD5 |
3fc7fb6a4e4e4759078eaf1fa429805f
|
|
| BLAKE2b-256 |
38e868f9d1d15bcf51c2363ec1a140a7320a5aad808264523be477023ef70c24
|
File details
Details for the file veildata-0.2.0-py3-none-any.whl.
File metadata
- Download URL: veildata-0.2.0-py3-none-any.whl
- Upload date:
- Size: 28.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
90ea94115f11236d186536d993a9cee4bd1a6906e1a103f4fa2aa1b89b27b1c9
|
|
| MD5 |
570ea074039fb9e00f5e1750f5072073
|
|
| BLAKE2b-256 |
4a7f8a86128f00d342d645b79f7adf4ffb936fe1f8bbc16d5bd985ac56b2263f
|