1. Problemática
Debido a las nuevas leyes y normas de protección de datos como la ley de GDPR, las organizaciones empiezan a dar mayor importancia a la seguridad de sus datos. Ya no solo importa quién accede o no a los datos, también importa quién puede o no acceder a datos personales de clientes, empleados, etc. En definitiva, aquellos datos que son considerados sensibles.
Es necesario encontrar una manera de que, sin poder leer datos personales, los usuarios de los datos puedan seguir realizando sus tareas de análisis. Es decir, seguir teniendo una visión completa de sus métricas, limitando solo el acceso al detalle.
En el pasado esto era imposible debido a que un registro podía mostrarse o no mostrarse, no había punto intermedio. Aquí es donde entra el enmascaramiento de datos.
El enmascaramiento de datos consiste en ocultar datos personales como nombres, direcciones, números de teléfono etc. de un registro de forma que sea imposible identificar la persona a la que pertenece.
Un ejemplo puede ser un analista de datos de un banco. El analista necesita saber para realizar sus tareas que una tarjeta de X tipo que lleva Y años contratada ha realizado una compra a determinado negocio, pero sus tareas no requieren saber el nombre y dirección del titular de la tarjeta. Es decir, necesita analizar los datos sin identificar a la persona.
Azure ofrece muchas opciones para aplicar el enmascaramiento de principio a fin. Este documento pretende sintetizar y orientar sobre cómo deben resolverse las necesidades que una organización pueda tener cuando pretende utilizar Power BI junto con Azure.
Gracias a nuestros amigos de Stratebi, nos envían este nuevo hack:
2. Descripción del entorno de pruebas
Todas las pruebas se han realizado con los siguientes recursos:
· Base de Datos: Pool SQL dentro de Azure Synapse
· PowerBi Desktop
· Servicio PowerBi
· Aplicación para interacción directa con la BBDD: DBeaver.
*Todos los recursos de Azure se encuentran en el mismo Tenant.
3. Anonimización a nivel de bbdd
A nivel de Base de Datos Azure SQL nos ofrece de forma nativa opciones de enmascaramiento de datos, podemos enmascarar cualquier columna de cualquier tabla con una sentencia de este estilo:
ALTER TABLE [nombre de la tabla] ALTER COLUMN [nombre de la columna] MASKED WITH (FUNCTION = '[función de enmascaramiento]');
Ejemplo:
ALTER TABLE xxxx.c_address ALTER COLUMN StreetAddress nvarchar(MAX) COLLATE SQL_Latin1_General_CP1_CI_AS MASKED WITH (FUNCTION = 'partial(1, "xxxxx", 5)');
Las ventajas de esto son:
· Al poder elegir cualquier función para el enmascaramiento en lugar de una predefinida podemos cumplir con exactitud las necesidades de nuestro proyecto en concreto, y podemos elegir funciones que impacten lo menor posible en el rendimiento de las queries.
· Se puede decidir aplicar el enmascaramiento en cualquier momento, aunque las columnas ya tengan datos insertados, evitando tener que reprocesar los datos.
Al aplicar enmascaramiento a una columna, la base de datos enmascara los datos por defecto para todos los usuarios.
Para dar permisos de desenmascaramiento a un usuario/rol utilizamos una sentencia de este estilo:
GRANT UNMASK ON [nombre de la tabla]([nombre de la columna]) TO [nombre del usuario/rol];
Ejemplo:
GRANT UNMASK ON "xxxx"."c_address"(StreetAddress) TO USUARIO_NOLIMITADO;
4. Integración con azure Active Directory
Al igual que podemos dar permisos de desenmascaramiento a usuarios/roles de la propia base de datos, podemos hacer lo mismo con usuarios que se autentiquen con sus credenciales de Azure Active Directory. El único requisito es establecer un administrador del Directorio Activo para la base de datos en Azure:
Con respecto a la asignación de privilegios en sí, como se ve en los siguientes ejemplos, las sentencias no cambian:
· Ejemplo con usuarios de Active Directory
--Concesión de permisos de acceso sobre la base de datos usuario de Azure
CREATE USER [usuarioconprivilegios@xxxx.coutlook.onmicrosoft.com] FROM EXTERNAL PROVIDER;
--Permiso sobre el esquema en el que está la tabla
GRANT SELECT ON SCHEMA :: xxxx.c TO [usuarioconprivilegios@xxxx.coutlook.onmicrosoft.com];
GRANT VIEW DEFINITION ON SCHEMA :: xxxx.c TO [usuarioconprivilegios@xxxx.coutlook.onmicrosoft.com];
-- Sentencia para desenmascarar datos
GRANT UNMASK ON "xxxx"."c_address"(StreetAddress) TO [usuarioconprivilegios@xxxx.coutlook.onmicrosoft.com];
· Ejemplo con grupos de Active Directory
--Grupo de Azure AD que verá los datos desenmascarados
--Añado el grupo ya existente en Azure, a la BBDD
CREATE USER [Grupo N1] FROM EXTERNAL PROVIDER;
--Acceso al esquema en el que está la tabla de este ejercicio.
GRANT SELECT ON SCHEMA :: xxxx TO [Grupo N1];
GRANT VIEW DEFINITION ON SCHEMA :: xxxx TO [Grupo N1];
-- Sentencia para desenmascarar datos
GRANT UNMASK ON "xxxx"."c_address"(StreetAddress) TO [Grupo N1];
--Grupo de Azure AD que verá los datos enmascarados
--Adición del grupo ya existente en Azure, a la BBDD
CREATE USER [Grupo N2] FROM EXTERNAL PROVIDER;
--Acceso al esquema en el que está la tabla. No se dan privilegios de desenmascaramiento
GRANT SELECT ON SCHEMA :: xxxx TO [Grupo N2];
GRANT VIEW DEFINITION ON SCHEMA :: xxxx TO [Grupo N2];
Como se ve en la captura de pantalla. Un usuario miembro de ‘Grupo N1’ puede ver los datos en claro, mientras que un usuario miembro de ‘Grupo N2’ los ve enmascarados:
En ningún momento se ha tenido que añadir a los miembros de manera individual a la base de datos, esto simplifica mucho la incorporación de miembros nuevos a los equipos ya que todas las gestiones se hacen en Azure, quedando la gestión de la seguridad en la base de datos totalmente automatizada.
Cabe destacar que gracias a todas las opciones de inicio de sesión disponibles, los usuarios siempre podrán usar sus credenciales de Azure AD independientemente del software que usen para interactuar con la Base de Datos:
5. Integración con PowerBI
La integración con PowerBi se puede obtener de dos maneras, dependiendo de cómo obtengamos los datos:
· Con modo Direct Query: Es la manera más limpia de trabajar y la que desarrollaremos en este punto. Requiere que los dataset conecten en modo Direct Query y que PowerBi y la base de datos estén en el mismo Tenant.
· Con modo Import: Requiere tener dos usuarios en la base de datos (uno con privilegios para desenmascarar los datos y otro sin privilegios) que PowerBi use para obtener datos. Los dataset/informes deberán duplicarse para usar los distintos usuarios y las Áreas de trabajo también deberán duplicarse para dar acceso a los diferentes usuarios. Este método solo se debe usar si nuestros dataset deben conectar en modo Import.
Desarrollamos el primer método:
1. Siguiendo con el ejemplo del punto 4, añadimos nuestros usuarios al Workspace de PowerBI que vamos a utilizar para la prueba:
2. En PowerBi Desktop, creamos el informe conectando en modo Direct Query y lo subimos al servicio de PowerBi.
3. En el servicio de PowerBi configuramos las credenciales del dataset para que los usuarios conecten al origen usando su identidad de PowerBi (que es la misma que tienen en Azure, que es la que está conectando a la base de datos).
Como podemos comprobar en las siguientes capturas de pantalla, los usuarios acceden al mismo informe y al conectar este por Direct Query usando su identidad, hereda todos los privilegios que hay configurados en la base de datos:
De esta manera hemos configurado los privilegios una sola vez en el origen, y hemos mantenido nuestro Workspace limpio con un solo informe + dataset que desarrollar/mantener. Además, todo el peso del desenmascaramiento recae sobre la base de datos.
6. Problemas conocidos/observaciones
El principal problema de aplicar el enmascaramiento de esta manera en la base de datos es que los usuarios pueden utilizar filtros para “adivinar” el valor real de un campo enmascarado. Esto aplica cuando se interactúa directamente con los datos mediante sentencias SQL, y cuando se consultan informes de PowerBi que conectan en modo Direct Query. Por ejemplo, un usuario podría hacer un BETWEEN para averiguar el salario de un empleado.
· Interacción directa con los datos:
· En el caso de PowerBi:
o Modo Import:
o Modo Direct Query:
El modo Import importa los datos enmascarados, y después les aplica el filtro
El modo Direct Query hace un WHERE StreetAddress LIKE ‘%Yosemite%’ y permite al usuario terminar adivinando el valor real.
Otros comentarios interesantes sobre el enmascaramiento:
· Se puede decidir enmascarar/desenmascarar un campo en cualquier momento, aunque la tabla tenga datos à No hace falta recargar.
· Se puede elegir con qué función se enmascaran los datos. Podemos elegir funciones sencillas para mejorar rendimiento de los refrescos, etc. No estamos obligados a usar una función concreta.
· Se pueden dar permisos para que un usuario desenmascare solo algunas columnas àNo estamos obligados a que puedan desenmascarar todas o ninguna.
· Los enmascaramientos se pueden configurar desde Synapse en el portal de Azure. De hecho, los enmascaramientos configurados directamente en la base de datos aparecen en el portal automáticamente. Además, el portal nos sugiere automáticamente campos que podrían necesitar enmascaramiento.
7. Conclusiones
Las bases de datos disponibles en Azure ofrecen opciones de enmascaramiento más que suficientes para prácticamente cualquier necesidad. Además, gracias a todas las opciones de conexión/inicio de sesión que ofrecen, integración con Azure AD, etc. nos permiten proteger los datos al nivel más bajo, impidiendo que en algún punto los usuarios puedan ver en claro datos que no deben.
Con respecto a PowerBi, consideramos que la mejor opción es aprovechar la integración con AD en dataset que conecten en modo Direct Query. Esta es la manera más limpia de trabajar de cara al desarrollo y mantenimiento de los dataset e informes que dependan de ellos, y de cara a la gestión de los Workspace en el servicio de PowerBi. La única desventaja de usar el modo Direct Query es que si hay cualquier incidencia en el DWH los informes podrían dejar de funcionar. Con modo Import si tenemos incidencia simplemente pausamos el refresco de PowerBi hasta resolverla.
Usar dataset que conectan en modo Import y aprovechar el enmascaramiento es posible si se establecen buenas normas de desarrollo y gestión para evitar conflictos como:
· Aplicar una corrección en la versión enmascarada de un dataset y olvidar aplicarla en la versión en claro.
· Añadir a un usuario a la versión incorrecta de un Workspace.
· Subir la versión en claro de un dataset al Workspace enmascarado.
8. Enlaces Interesantes
A continuación, algunos enlaces interesantes relacionados con el tema tratado:
· Secure sensitive data with Dynamic Data Masking in Synapse - YouTube
· Dynamic data masking - Azure SQL Database | Microsoft Docs
· Power BI Desktop Parameters, Part2 Dynamic Data Masking (DDM) (biinsight.com)
· Using DirectQuery for datasets and Analysis Services (preview) - Power BI | Microsoft Docs
· Azure SQL Database with DirectQuery - Power BI | Microsoft Docs