Cómo enmascarar datos sensibles en Azure SQL (Data Masking)
Proteger datos personales como emails y numeros de tarjeta es un requisito basico de gobernanza de datos, y no siempre obliga a reescribir la aplicacion. Dynamic Data Masking en Azure SQL oculta columnas sensibles en los resultados de las consultas y muestra los valores reales solo a quien tiene permiso. Asi, un analista solo ve aXXX@XXXX.com mientras los datos de la tabla permanecen intactos.
Requisitos previos
- Una base de datos en Azure SQL Database (o SQL Server 2022) donde tengas permisos de administrador.
- Una herramienta de consulta como SQL Server Management Studio (SSMS) o Azure Data Studio.
- Conocimientos basicos de T-SQL (
CREATE TABLE,SELECT,ALTER TABLE).
Paso 1: Crear una tabla de ejemplo
Empecemos con una tabla de clientes que contiene datos sensibles. Ejecuta el siguiente script para crearla e insertar algunos registros:
CREATE TABLE dbo.Clientes (
ClienteID INT IDENTITY PRIMARY KEY,
Nome NVARCHAR(100),
Email NVARCHAR(100),
Telemovel VARCHAR(20),
Cartao VARCHAR(19)
);
INSERT INTO dbo.Clientes (Nome, Email, Telemovel, Cartao)
VALUES
(N'Ana Silva', 'ana.silva@email.pt', '912345678', '4111111111111111'),
(N'Bruno Costa', 'bruno.costa@email.pt', '936000111', '5500005555555559');
Paso 2: Aplicar mascaras a las columnas sensibles
Una mascara se define por columna con la clausula ADD MASKED WITH (FUNCTION = '...'). Cada funcion oculta los datos de una forma distinta. Vamos a enmascarar el email, el telefono y la tarjeta:
-- email(): mostra a 1.a letra e o dominio -> aXXX@XXXX.com
ALTER TABLE dbo.Clientes
ALTER COLUMN Email ADD MASKED WITH (FUNCTION = 'email()');
-- partial(): mostra apenas os ultimos 3 digitos -> XXXXXX678
ALTER TABLE dbo.Clientes
ALTER COLUMN Telemovel ADD MASKED WITH (FUNCTION = 'partial(0,"XXXXXX",3)');
-- default(): esconde o valor por completo -> XXXX
ALTER TABLE dbo.Clientes
ALTER COLUMN Cartao ADD MASKED WITH (FUNCTION = 'default()');
La funcion partial(prefijo, relleno, sufijo) es la mas flexible: el primer numero indica cuantos caracteres iniciales conservar, el texto entre comillas es el relleno visible y el ultimo numero cuantos caracteres finales conservar. Por su parte, default() aplica la mascara predeterminada del tipo — XXXX para texto, 0 para numeros y una fecha fija para fechas.
Paso 3: Crear un usuario para probar
Las mascaras no se aplican a los administradores (miembros de db_owner), por lo que no veras ningun efecto con tu propia cuenta. Para comprobarlo, crea un usuario sin privilegios y concedele solo permiso de lectura:
CREATE USER analista WITHOUT LOGIN;
GRANT SELECT ON dbo.Clientes TO analista;
Paso 4: Confirmar la mascara con EXECUTE AS
Puedes suplantar temporalmente a ese usuario para ver los datos exactamente como los veria el, sin cambiar de sesion:
EXECUTE AS USER = 'analista';
SELECT Nome, Email, Telemovel, Cartao FROM dbo.Clientes;
REVERT;
El resultado muestra los emails como aXXX@XXXX.com, el telefono terminando en sus ultimos digitos y la tarjeta totalmente oculta. Los datos en la base de datos siguen intactos: solo cambia la presentacion.
Paso 5: Conceder excepciones con UNMASK
Si un perfil concreto necesita ver los valores reales (por ejemplo, atencion al cliente), concedele el permiso UNMASK. Desde SQL Server 2022 y en Azure SQL puedes hacerlo tambien a nivel de columna:
-- Acesso total aos valores reais
GRANT UNMASK TO analista;
-- Ou apenas a uma coluna (granular, SQL Server 2022 / Azure SQL)
GRANT UNMASK ON dbo.Clientes(Email) TO analista;
Para retirar la excepcion mas adelante, usa REVOKE UNMASK .... Concede siempre el minimo que cada perfil necesita.
Verificar el resultado
Para listar todas las columnas enmascaradas y la funcion aplicada, consulta la vista de sistema sys.masked_columns:
SELECT t.name AS Tabela, c.name AS Coluna, c.masking_function AS Mascara
FROM sys.masked_columns AS c
JOIN sys.tables AS t ON c.object_id = t.object_id
WHERE c.is_masked = 1;
Deberias ver las tres columnas con su funcion de mascara. Si vuelves a ejecutar el SELECT con EXECUTE AS despues del GRANT UNMASK, los valores aparecen ahora sin mascara.
Conclusion
Con solo unas pocas lineas de T-SQL has protegido datos sensibles sin tocar la aplicacion ni duplicar tablas. El siguiente paso es definir tu estrategia de excepciones: quien necesita realmente UNMASK y en que columnas. Recuerda que el enmascaramiento es una capa de presentacion, no seguridad absoluta: combinalo siempre con control de accesos y, cuando sea posible, cifrado. Que columnas de tu base de datos merecen una mascara hoy?