🕶️ 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.
Metadata
Release files for veildata 0.2.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| veildata-0.2.0.tar.gz | 34.2 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| veildata-0.2.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 62.6 kB
Release files / veildata-0.2.0.tar.gz
| Download URL | veildata-0.2.0.tar.gz |
|---|---|
| Size | 34.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
c917a51ff2ea886eb3061cf0f6df1c2acc815a5bd01c6669887d2ef8f88ca5a4
|
|
BLAKE2b-256 checksum How to use checksums |
38e868f9d1d15bcf51c2363ec1a140a7320a5aad808264523be477023ef70c24
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|
Release files / veildata-0.2.0-py3-none-any.whl
| Download URL | veildata-0.2.0-py3-none-any.whl |
|---|---|
| Size | 28.3 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
90ea94115f11236d186536d993a9cee4bd1a6906e1a103f4fa2aa1b89b27b1c9
|
|
BLAKE2b-256 checksum How to use checksums |
4a7f8a86128f00d342d645b79f7adf4ffb936fe1f8bbc16d5bd985ac56b2263f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.1.0 CPython/3.13.7
|