(+351) 21 24 10006  ·  info@bconcepts.pt
Carnaxide, Lisboa

Cómo implementar row-level security en Lakehouse: paso a paso

João Barros 25 de October de 2026 6 min de lectura

Vamos a implementar row-level security en Lakehouse para controlar qué filas puede ver cada usuario o equipo. Esta técnica es útil para cumplir requisitos de seguridad y privacidad sin duplicar datos ni crear múltiples tablas por cliente. Al filtrar a nivel de fila, mantienes una única fuente de la verdad (por ejemplo, una tabla Delta) y aplicas políticas de acceso de forma centralizada y auditable.

Prerequisitos

  • Cuenta con acceso a Microsoft Fabric y permiso para crear tablas en el Lakehouse.
  • Una tabla Delta existente con columna de seguridad (p. ej.: tenant_id, region u owner_id). Idealmente la columna tiene valores normalizados (p. ej.: T001, T002) y la tabla tiene desde cientos hasta millones de filas.
  • Acceso al SQL analytics endpoint o a un notebook con PySpark/SQL.
  • Conceptos básicos de SQL y permisos en el Fabric. Si tienes un equipo pequeño, recorre la lista de roles y identifica quién tendrá role_admins.

Paso 1: Elegir la columna de control y crear una tabla de mapeo

Identifica la columna que define visibilidad (por ejemplo tenant_id). Esta columna debe ser estable y eficiente para joins (indexable o particionable). Crea una tabla de mapeo que relacione usuarios/grupos con los valores permitidos. Esta tabla funciona como la lista de control de acceso (ACL) y permite gestionar permisos sin alterar la tabla principal.

CREATE TABLE IF NOT EXISTS security.mapping_users_tenants (
  user_id STRING,
  tenant_id STRING
);

-- Exemplo de inserção
INSERT INTO security.mapping_users_tenants VALUES
('alice@contoso.com','T001'),
('bob@contoso.com','T002'),
('group_sales','T001');

Ejemplo práctico: si tu organización tiene 50 tenants y 200 usuarios, la tabla de mapping típicamente tendrá algunas centenas de filas. Mantén timestamps o columnas de auditoría si necesitas rastrear cuándo se cambió un mapeo.

Paso 2: Crear una view segura que filtre por usuario

Crea una view que use el contexto del usuario (CURRENT_USER o función equivalente) para filtrar la tabla Delta principal por tenant_id. Así, los usuarios consultan la view en lugar de la tabla directa. Las views hacen la política explícita y fácil de auditar.

CREATE OR REPLACE VIEW secure.v_orders AS
SELECT o.*
FROM lakehouse.orders o
JOIN security.mapping_users_tenants m
  ON o.tenant_id = m.tenant_id
WHERE m.user_id = CURRENT_USER();

Notas: CURRENT_USER() suele devolver el UPN (p. ej.: alice@contoso.com). Si usas grupos, adapta la lógica para comprobar pertenencia a grupos (vía una tabela_groups o una función que expanda grupos). En entornos con miles de consultas, confirma que la view tiene un rendimiento aceptable — un join por tenant_id es típicamente O(N) sobre la partición relevante y suele ser rápido cuando las tablas están particionadas adecuadamente.

Paso 3: Probar la view con usuarios simulados

Si no puedes cambiar identidades en el entorno de prueba, puedes sustituir CURRENT_USER() por un valor literal o crear views de prueba. Prueba con varios escenarios: un usuario con acceso a un tenant, otro con acceso a varios tenants, y uno sin accesos. Cuenta las filas esperadas: por ejemplo, si orders tiene 10.000 filas y el tenant T001 tiene 1.250 filas, alice debe ver exactamente esas 1.250 filas.

-- Teste substituindo CURRENT_USER()
SELECT * FROM secure.v_orders WHERE 1=1; -- como alice configurarás CURRENT_USER() no ambiente

-- Alternativa para testes
CREATE OR REPLACE VIEW secure.v_orders_test AS
SELECT o.*
FROM lakehouse.orders o
JOIN security.mapping_users_tenants m
  ON o.tenant_id = m.tenant_id
WHERE m.user_id = 'alice@contoso.com';

Ejecuta tests automatizados: por ejemplo, un conjunto de 10 queries que validen conteos y muestras (SELECT COUNT(*) y SELECT TOP 10). Documenta los resultados esperados para regresión.

Paso 4: Restringir accesos directos a la tabla base

Es importante impedir que los usuarios lean directamente la tabla Delta. Revoca permisos de SELECT en la tabla base y concede solo al equipo de administradores; da permiso de SELECT solo en la view segura. Sin este paso, un usuario privilegiado podría eludir la view.

-- Revogar acesso geral
REVOKE SELECT ON TABLE lakehouse.orders FROM PUBLIC;
-- Conceder apenas a admins
GRANT SELECT ON TABLE lakehouse.orders TO role_admins;
-- Conceder acesso à view a utilizadores
GRANT SELECT ON VIEW secure.v_orders TO PUBLIC;

Verifica siempre los permisos con consultas administrativas (por ejemplo, SHOW GRANTS). Para auditoría, registra quién tiene el rol role_admins; idealmente limita ese rol a menos de 5 administradores.

Paso 5: Automatizar actualizaciones del mapping (opcional)

Para entornos dinámicos, crea un proceso ETL/ELT que actualice security.mapping_users_tenants desde Azure AD u otro sistema de identidad. Un notebook simple con PySpark puede sincronizar cambios diariamente a la 01:00, tardando típicamente 1–5 minutos para tablas de algunas miles de filas.

# Exemplo PySpark para atualizar mapping (esquema mínimo)
mapping_df = spark.read.format('delta').load('/mnt/security/mapping_users_tenants')
# Código para obtener datos de identidad y escribir de vuelta
new_df.write.format('delta').mode('overwrite').save('/mnt/security/mapping_users_tenants')

Considera usar actualizaciones incrementales en lugar de overwrite si tienes muchos registros. Registra cambios y envía alertas cuando un mapping crítico cambie (por ejemplo, eliminación de acceso de un administrador).

Verificar el resultado

Para confirmar que la row-level security funciona: 1) Inicia sesión como usuario A y ejecuta SELECT en la view secure.v_orders — solo deberías ver filas del tenant de A; valida con COUNT(*). 2) Intenta SELECT directo en lakehouse.orders con el mismo usuario — debe ser denegado. 3) Prueba con otro usuario/grupo para garantizar aislamiento. Haz tests de carga básicos (por ejemplo 50 queries concurrentes) para asegurar que la view no se convierte en un cuello de botella.

Conclusión

Con una columna de control, una tabla de mapping y views filtradas consigues implementar row-level security en Lakehouse de forma simple, auditable y escalable. Próximos pasos: integrar con Azure AD para gestión automática de grupos, usar políticas dinámicas basadas en roles, e incluir tests automatizados con cuentas de prueba. Consejo: documenta los mapeos, registra cambios y prueba regularmente para evitar fugas de datos.