jsonmask
Masking y redacción de datos sensibles en dicts, JSON y logs — simple, configurable y listo para integrarse en pipelines y aplicaciones Python.
🦉 Parte del Ecosistema Búho Zurdo
jsonmask es una herramienta open-source desarrollada por Búho Zurdo, enfocada en la protección de datos sensibles con la misma lealtad y precisión que caracterizan a nuestro ecosistema.
¿Qué es jsonmask?
jsonmask es una librería Python para detectar y enmascarar información sensible dentro de:
- Estructuras de datos Python (dict/list)
- Archivos JSON y NDJSON
- Mensajes de logging
Está pensada para integrarse fácilmente en aplicaciones, scripts y pipelines CI/CD donde quieras prevenir que PII, tokens o cualquier dato confidencial se filtre a logs, dumps o salidas externas.
Principales objetivos
- ✅ Enmascarado declarativo por reglas (paths, patrones, entropía)
- ✅ Integración plug-and-play con el sistema
logging - ✅ Presets para PII comunes
- ✅ CLI para procesar archivos JSON/NDJSON
- ✅ Salida segura y configuraciones aptas para uso en CI
🚀 Instalación
pip install jsonmask
Para desarrollo:
git clone https://github.com/buhozurdo/jsonmask.git
cd jsonmask
pip install -e ".[dev]"
📖 Uso Rápido
API Básica
from jsonmask import mask, Masker
# Datos con información sensible
data = {
"user": {"name": "Ana", "email": "ana@example.com"},
"token": "eyJhbGciOiJIUzI1..."
}
# Definir reglas de enmascarado
rules = [
{"path": "user.email", "strategy": "redact"},
{"path": "token", "strategy": "hash"}
]
# Enmascarar
masked = mask(data, rules=rules)
print(masked)
# {
# "user": {"name": "Ana", "email": "****"},
# "token": "3a7bd3f..." # valor hasheado
# }
Masker Reutilizable (Recomendado para producción)
from jsonmask import Masker
masker = Masker.from_rules(rules)
masked = masker.mask(data)
# Reutilizar para múltiples datos
for record in records:
clean_record = masker.mask(record)
🔐 Integración con Logging
Filtro de Masking para Logs Estándar
import logging
from jsonmask import Masker, MaskingFilter
rules = [
{"path": "request.headers.authorization", "strategy": "partial"},
{"path": "user.email", "strategy": "redact"}
]
masker = Masker.from_rules(rules)
handler = logging.StreamHandler()
handler.addFilter(MaskingFilter(masker))
logger = logging.getLogger("app")
logger.addHandler(handler)
# Los datos sensibles serán enmascarados automáticamente
logger.info("Request", extra={"request": {"headers": {"authorization": "Bearer abc123"}}})
Masking para Logs Estructurados (JSON)
from jsonmask import Masker, StructuredLogMasker
rules = [
{"path": "user.email", "strategy": "redact"},
{"path": "credentials.api_key", "strategy": "hash"}
]
masker = Masker.from_rules(rules)
log_masker = StructuredLogMasker(masker)
# Enmascarar entrada de log estructurado
log_entry = {
"level": "info",
"message": "User logged in",
"user": {"email": "test@example.com"}
}
masked_entry = log_masker.mask_log_entry(log_entry)
# Enmascarar string JSON directamente
json_log = '{"user": {"email": "test@example.com"}}'
masked_json = log_masker.mask_json_string(json_log)
⌨️ CLI
# Procesar archivo JSON
jsonmask mask --input data.json --rules rules.yml --output masked.json
# Procesar NDJSON desde stdin
cat data.ndjson | jsonmask mask --rules rules.yml --ndjson > masked.ndjson
# Generar reporte de campos enmascarados
jsonmask mask -i data.json -r rules.yml -o out.json --report report.json
# Validar archivo de reglas
jsonmask validate -r rules.yml
# Listar estrategias disponibles
jsonmask list-strategies
# Generar archivo de ejemplo de reglas
jsonmask generate-rules -o example_rules.yml
📋 Formato de Reglas
Archivo YAML
rules:
- path: "user.email"
strategy: "redact"
replace_with: "****"
- path: "cards.*.number"
strategy: "partial"
keep_start: 4
keep_end: 4
mask_char: "*"
- path: "headers.authorization"
strategy: "regex"
pattern: "Bearer\\s+(.+)"
replace_with: "Bearer ****"
- path: "token"
strategy: "entropy"
entropy_min: 3.5
Soporte de Paths
| Tipo | Ejemplo | Descripción |
|---|---|---|
| Notación punto | user.email |
Acceso a campos anidados |
| Wildcard | cards.*.number |
Cualquier clave en ese nivel |
| Índices | items[0].id |
Índice específico en lista |
| Wildcard índice | items[*].secret |
Todos los elementos de lista |
🎯 Estrategias de Enmascarado
| Estrategia | Descripción | Opciones |
|---|---|---|
redact |
Reemplaza con placeholder | replace_with |
replace |
Reemplaza con valor literal | replace_with |
hash |
SHA256 con prefijo | hash_prefix_length, hash_prefix |
partial |
Mantiene inicio/fin | keep_start, keep_end, mask_char |
regex |
Aplica regex | pattern, replace_with |
entropy |
Detecta alta entropía | entropy_min, replace_with |
📦 Presets PII
from jsonmask import Masker
from jsonmask.presets import get_preset, combine_presets
# Usar preset individual
email_rules = get_preset("email")
# Combinar presets
rules = combine_presets("email", "credit_card", "token")
masker = Masker.from_rules(rules)
Presets disponibles: email, credit_card, token, ssn, password, phone, pii (todos)
📊 Generación de Reportes
from jsonmask import mask
data = {"email": "test@example.com", "password": "secret"}
rules = [
{"path": "email", "strategy": "redact"},
{"path": "password", "strategy": "redact"}
]
masked, report = mask(data, rules=rules, generate_report=True)
print(report.to_dict())
# {
# "total_fields_checked": 2,
# "total_fields_masked": 2,
# "masked_fields": [...]
# }
⚡ Rendimiento
Maskercompila reglas para ejecución repetida- Recorrido iterativo para evitar stack overflow
- Recomendaciones para alta carga:
- Usar sampling (procesar 1 de N mensajes)
- Pre-filtrado por keys relevantes
- Ejecutar en hilo/proceso separado
🛠️ Buenas Prácticas
- Prefiere reglas por
pathen lugar de solo regex para disminuir falsos positivos - Usa
Maskerreutilizable en servicios de larga vida - Versiona tu archivo
rules.ymly revísalo con el equipo de seguridad - En CI, ejecuta
jsonmaskantes de publicar artefactos con datos
🗺️ Roadmap
- Modo "learning" para reducir falsos positivos
- Integración nativa con
structlogyLoguru - Plugin pre-commit y GitHub Action
- Exportadores para Fluentd/Logstash
- JSONPath full support
- Extensiones en C para hotspots de rendimiento
🧪 Tests
# Ejecutar tests
pytest
# Con cobertura
pytest --cov=src/jsonmask --cov-report=term-missing
# Solo tests específicos
pytest tests/test_masker.py -v
🤝 Contribuir
¡Las contribuciones son bienvenidas! Por favor, lee CONTRIBUTING.md para más detalles.
- Fork del repositorio
- Crear branch
feature/xxx - Añadir tests y documentación
- Crear Pull Request
📄 Licencia
MIT — ver LICENSE para más detalles.
👤 Mantenedor
Proyecto parte del ecosistema Búho Zurdo 🦉
Metadata
Release files for buhozurdo-jsonmask 0.1.10
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| buhozurdo_jsonmask-0.1.10.tar.gz | 19.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| buhozurdo_jsonmask-0.1.10-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 43.5 kB
Release files / buhozurdo_jsonmask-0.1.10.tar.gz
| Download URL | buhozurdo_jsonmask-0.1.10.tar.gz |
|---|---|
| Size | 19.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
eca195bb1024063a80f53ef3042cbe086ebe28a81d8094592b2a93a3a87b1503
|
|
BLAKE2b-256 checksum How to use checksums |
a7618add57208005b2428f16b217bc1300af792c3749528efdba804ebc30ad9a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 2, 2026.
Transparency logRelease files / buhozurdo_jsonmask-0.1.10-py3-none-any.whl
| Download URL | buhozurdo_jsonmask-0.1.10-py3-none-any.whl |
|---|---|
| Size | 23.7 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
f32af2c6e1d7b92778041dc976ad8799a596fd550ee2462ded2125aae230f705
|
|
BLAKE2b-256 checksum How to use checksums |
fb20b4fc4f8ce07f3337338db5575342fbe2dae1441d84f17430f15475e10b35
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Aug 2, 2026.
Transparency log