En cualquier proyecto de software que maneje información personal, tarde o temprano aparece el mismo problema: los entornos de desarrollo y testing necesitan datos que sean representativos, pero los datos reales de usuarios están protegidos por ley. La solución habitual es fabricar datos sintéticos a mano o usar fixtures estáticos que no reflejan la complejidad real del sistema. El resultado casi siempre es el mismo: bugs que solo aparecen en producción porque nadie los pudo detectar con datos de juguete.
La Ley 25326 de Protección de Datos Personales no es opcional ni es un detalle de compliance que se resuelve con una cláusula en los términos de uso. Establece obligaciones concretas sobre cómo se tratan, almacenan y comparten los datos personales. Usarlos en un entorno de dev sin los controles adecuados es una infracción, más allá de que la intención no sea maliciosa.
La pregunta real no es si se puede usar datos reales en testing. Es cómo anonimizarlos de forma que sigan siendo útiles sin dejar de ser seguros.
Por qué anonimizar (y no solo restringir el acceso) es la salida legal
El artículo 2 de la Ley 25326 define la “disociación de datos” como todo tratamiento que hace que la información no pueda asociarse a una persona determinada o determinable. La consecuencia práctica es importante: un dato correctamente anonimizado deja de ser un dato personal y, por lo tanto, sale del alcance de la ley. Restringir accesos, cifrar la base o poner un NDA a los desarrolladores no logra eso — sigue siendo dato personal, solo que con menos gente mirándolo. Anonimizar de verdad es lo único que reduce el perímetro de la obligación legal, no solo el riesgo de exposición.
Ahí aparece una distinción que se pasa por alto seguido: no es lo mismo anonimizar que pseudonimizar. Una sustitución determinista — donde el mismo valor de entrada siempre produce la misma salida, típicamente mediante un mapeo o una función con clave — es pseudonimización, no anonimización. Es reversible en principio: quien tiene la clave o la tabla de mapeo puede reconstruir el dato original. Eso la sigue dejando adentro del alcance de la Ley 25326 como dato personal, aunque sea un dato personal más protegido. Tiene un uso legítimo en dev/test (mantiene la consistencia referencial entre tablas, algo que datos sintéticos puros no garantizan), pero el equipo tiene que tratar esa clave de mapeo con el mismo cuidado que trataría los datos originales, y no venderlo puertas adentro como “ya está anonimizado y fuera de la ley”.
El problema con los enfoques ad hoc de anonimización
La mayoría de los equipos resuelve esto con scripts caseros: un sed que reemplaza emails, un script de Python que pisa nombres con strings aleatorios, quizás alguna función en el ORM que enmascara DNIs antes de hacer un dump. Esos enfoques tienen tres problemas concretos.
Primero, la cobertura es incompleta. Un script que reemplaza el campo email no sabe que el campo notas_internas también puede contener una dirección de correo escrita en texto libre. La detección de PII (Personally Identifiable Information) requiere análisis semántico del contenido, no solo de los nombres de columna.
Segundo, la sustitución rompe la consistencia referencial. Si reemplazás un nombre con un string aleatorio en una tabla, pero ese nombre aparece en otras cinco tablas o en logs del sistema, tenés un dataset inconsistente que va a generar falsos positivos en los tests. Peor: si la sustitución no es determinista, dos dumps del mismo dataset van a producir anonimizaciones distintas, lo que hace imposible comparar resultados entre corridas.
Tercero, no hay validación. Nadie verifica que el proceso haya funcionado. El script corre, no tira error, y se asume que el output está limpio. Hasta que no lo está.
Estos no son problemas de negligencia, son problemas de arquitectura. Un script ad hoc no fue diseñado para resolver anonimización a escala; es un parche.
Qué necesita un pipeline de anonimización para ser confiable en dev/test
Sea una herramienta armada in-house o una comprada, un pipeline de anonimización que reemplaza al script casero necesita tres etapas con responsabilidades separadas: detección, sustitución y validación. El output de una es el input de la siguiente.
Detección es la etapa más crítica y la que más se subestima. No alcanza con mapear campos que tienen nombres obvios como nombre, apellido o telefono. Hace falta analizar el contenido de los campos para identificar PII semánticamente: reconocer patrones de CUIL/CUIT, DNI, emails, números de teléfono argentinos, fechas de nacimiento y otros identificadores incluso cuando están en campos con nombres arbitrarios o en texto no estructurado. Esto cubre el caso donde alguien guardó un número de documento en un campo observaciones o donde una dirección completa está concatenada en un string. Herramientas open source como Microsoft Presidio resuelven específicamente esta etapa (detección semántica de PII con reconocedores por tipo de dato y por idioma) y son un buen punto de partida antes de evaluar una plataforma comercial.
Sustitución es donde se aplican las transformaciones, y acá vale repetir la distinción legal de la sección anterior: si la sustitución es determinista (mismo valor de entrada, misma salida), el resultado es pseudonimización, no anonimización, y sigue siendo dato personal bajo la Ley 25326. Igual tiene valor técnico real — si el CUIT 20-12345678-1 aparece en diez tablas, mantener consistencia entre todas las ocurrencias evita un dataset incoherente para correr queries y tests de integración. La alternativa más estricta es generación de datos sintéticos dentro del propio pipeline (no derivados del dato real, y no los fabricados a mano del principio de este post) para los campos que no necesitan trazabilidad entre tablas, que sí logra anonimización real cuando está bien implementada.
Validación cierra el loop. Después de aplicar las sustituciones, hay que volver a correr el detector sobre el output para verificar que no quedó PII sin procesar, y reportarlo antes de que el dataset salga del pipeline. Esto convierte el proceso en algo auditable: un log de qué se detectó, qué se reemplazó y qué quedó limpio. Una validación seria no se limita a repetir el detector inicial: conviene sumar checks orientados a ataques de re-identificación básicos, como verificar que combinaciones de atributos cuasi-identificadores (código postal + fecha de nacimiento + género, por ejemplo) no sean suficientemente únicas como para identificar a una persona en el dataset resultante. No es un análisis de k-anonimato completo, pero es un piso razonable para la mayoría de los casos de uso en dev/test.
Integración en el flujo de trabajo de un equipo de desarrollo
El caso de uso más común es el siguiente: el equipo necesita refrescar el entorno de staging con datos actualizados. Sin un pipeline de anonimización, eso implica o bien usar datos de producción (riesgo legal) o bien fabricar datos manualmente (tiempo y poca representatividad). La solución es que el paso de anonimización sea parte del proceso de generación del dump, no un trámite manual aparte.
La integración puede ser tan simple como agregar un paso en el pipeline de CI/CD que tome el dump de producción, lo pase por el detector/sustituidor/validador, y deposite el resultado en el entorno de staging. El equipo trabaja con datos que tienen la misma estructura, volumen y distribución que los reales, pero sin información personal identificable circulando sin control.
Esto importa más allá de la comodidad operativa de tener el paso integrado al pipeline: para equipos que manejan datos sensibles en verticales como fintech, salud o recursos humanos, es la diferencia entre cumplir o no cumplir con la Ley 25326. El artículo 9 de esa ley obliga a implementar medidas técnicas y organizativas para garantizar la seguridad y confidencialidad de los datos personales, evitando su consulta o tratamiento no autorizado. Tener datos de producción en un entorno de dev al que acceden diez desarrolladores con distintos niveles de acceso, sin ningún control adicional, no es una medida técnica razonable bajo ese estándar. La Agencia de Acceso a la Información Pública (AAIP) — autoridad de aplicación de la ley — publicó en su Resolución 4/2019 criterios orientativos sobre disociación de datos que van en esta misma línea: mientras más se acerque el tratamiento a una disociación real, menor es la exposición legal del equipo.
También existe el escenario de compartir datos con terceros: agencias externas, consultoras, equipos de QA offshore. En esos casos, la necesidad de anonimización previa es aún más obvia, pero el proceso ad hoc se vuelve todavía más riesgoso porque el dato sale del perímetro de la organización.
Un pipeline de este tipo, para ser útil en la práctica, conviene que pueda exportar el dataset resultante en los formatos más comunes (CSV, JSON, dump SQL) y guardar configuraciones reutilizables por proyecto — sin eso, cada refresh de datos vuelve a pagar el costo de configurar el proceso desde cero.
Trabajar con datos reales en entornos no productivos es un problema que tiene solución técnica concreta. No requiere inventar datos sintéticos que no representan nada ni asumir el riesgo de usar PII sin protección. Requiere un pipeline que detecte, sustituya y valide de forma sistemática — y requiere que el equipo sepa distinguir cuándo lo que construyó es anonimización real (fuera del alcance de la Ley 25326) y cuándo es pseudonimización (todavía adentro, todavía a proteger).