🔐

Row-Level Security (RLS)

Filtra filas por usuario en tus modelos semánticos: roles estáticos, dinámicos, USERPRINCIPALNAME() y jerarquías con PATH — con ejemplos reales.

Intermedio Avanzado
💭

¿Qué es Row-Level Security?

Filtrar filas según quién pregunta

Row-Level Security (RLS) es una capa de seguridad que aplica filtros DAX automáticamente sobre tus tablas en función del usuario que abre el informe. Aunque dos personas vean exactamente el mismo informe, cada una verá solo sus filas.

Ejemplo típico: una directora de ventas de Iberia ve solo datos de España y Portugal, mientras la directora global ve todo, usando el mismo informe.

Conceptos clave:

  • Rol: un conjunto de filtros DAX definido en el modelo. Se crea desde Power BI Desktop → Modelado → Administrar roles.
  • Asignación: en el Service, asignas usuarios o grupos de Microsoft Entra (antes Azure AD) a cada rol.
  • RLS no afecta al autor: quien edita el modelo siempre lo ve sin filtros (a menos que se haya asignado a un rol).
⚠️ Ojo con esto: RLS protege el modelo cuando el usuario consulta los datos, pero no esconde nombres de tablas, columnas ni medidas. Para eso necesitas OLS.
🧱

RLS estático

Un rol = un filtro fijo

El filtro del rol es una expresión DAX literal. Es la forma más sencilla y rápida. Requiere mantener un rol por cada combinación de permisos.

Ejemplo: rol "Ventas Iberia"

[Pais] IN { "España", "Portugal" }

Ejemplo: rol "Solo año actual"

YEAR([Fecha]) = YEAR(TODAY())

Cuándo usarlo:

  • Pocos perfiles claramente diferenciados (3–5 roles)
  • Permisos que cambian poco
  • No quieres mantener una tabla de seguridad
📌 Buena práctica: Asigna roles a grupos de seguridad de Microsoft Entra, no a usuarios individuales. Cuando alguien cambia de equipo, solo actualizas el grupo, no decenas de asignaciones manuales.
⚙️

RLS dinámico

Un solo rol que se adapta al usuario

En RLS dinámico mantienes una tabla de seguridad que relaciona usuarios con dimensiones, y el rol filtra usando funciones que identifican al usuario actual:

  • USERNAME() — devuelve el usuario en formato dominio o UPN según el origen
  • USERPRINCIPALNAME() — siempre devuelve el UPN (email@dominio). Es la recomendada.

Patrón clásico: tabla de seguridad por país

-- Tabla SecurityUsuarios
Email                       | Pais
ana@kawaiibi.com            | España
ana@kawaiibi.com            | Portugal
john@kawaiibi.com            | Reino Unido

Filtro del rol "Acceso por país" en DimPais:

[Pais] IN
    CALCULATETABLE(
        VALUES( SecurityUsuarios[Pais] ),
        SecurityUsuarios[Email] = USERPRINCIPALNAME()
    )

Con esto: un solo rol, una tabla mantenida fuera del modelo (idealmente en el origen) y permisos que se actualizan sin tocar el dataset.

💡 Tip kawaii: Marca la tabla de seguridad como oculta en el modelo y, si puedes, ponla en una relación uni-direccional hacia la dimensión correspondiente. Así los usuarios no la ven y el motor optimiza mejor las consultas. 🌸
🌳

RLS jerárquico (organigramas)

"Cada manager ve a su equipo, sin saber a quiénes lleva"

Para jerarquías padre-hijo (típicamente organigramas comerciales), DAX trae PATH y compañía. La idea: cada empleado tiene un ID y un ID del jefe; PATH reconstruye la cadena de mando.

Pasos:

  1. En la tabla de empleados, columna calculada:
    RutaJerarquica = PATH ( DimEmpleado[IDEmpleado], DimEmpleado[IDManager] )
  2. Filtro del rol en DimEmpleado:
    VAR EmpleadoActual =
        LOOKUPVALUE(
            DimEmpleado[IDEmpleado],
            DimEmpleado[Email], USERPRINCIPALNAME()
        )
    RETURN
        PATHCONTAINS( DimEmpleado[RutaJerarquica], EmpleadoActual )

Cada persona ve su propia fila y la de todos sus subordinados directos e indirectos. Sin mantener tablas auxiliares. ✨

🧪

Cómo probar RLS antes de publicar

En Power BI Desktop

  • Modelado → Administrar roles → crear el rol
  • Modelado → Ver como → elige el rol (y opcionalmente "Otro usuario" para simular un UPN concreto)
  • Si combinas varios roles para un mismo usuario, los filtros se aplican con OR — verás la unión

En el Service

  • Workspace → dataset → menú "..." → Seguridad → asignar usuarios/grupos a roles
  • Desde el mismo panel, "Test as role" simula la experiencia de un usuario asignado

Chequeo final antes de producción:

  • Probar con al menos un usuario representativo de cada rol
  • Verificar que los totales de tarjetas y gráficos cambian al cambiar de rol
  • Comprobar que USERPRINCIPALNAME() devuelve el UPN esperado (a veces difiere del email)
⚠️ Ojo: RLS solo se aplica cuando el contenido se publica en el Service y se consume con usuarios distintos al propietario. En Desktop, sin "Ver como", siempre verás todos los datos.
🚧

Limitaciones que debes conocer

Lo que RLS no hace (o hace con matices)

  • No oculta tablas ni columnas: para eso, OLS.
  • No funciona con "Analyze in Excel" si el usuario es Build owner: quien tiene permiso de build sobre el dataset puede saltarse RLS si lo conectas mal.
  • Datasets con conexión en vivo a AS / SSAS: el RLS lo gestiona el modelo Tabular del servidor, no Power BI.
  • Bidireccionales: si activas "Apply security filter in both directions" en relaciones bidireccionales, ten cuidado con el rendimiento.
  • Composite models con DirectQuery a otro dataset Power BI: RLS aplica del modelo origen, no del derivado.
📌 Patrón recomendado en empresas: tabla de seguridad mantenida en el origen (SQL/Fabric), grupos de Entra como destinatarios de roles, y un único rol dinámico por dimensión a controlar. Mantenible, auditable y escalable.
🚀 Siguiente paso: Si quieres ocultar también columnas y tablas (no solo filas), pasa a Object-Level Security (OLS). Y para complementar la protección al exportar, mira las Sensitivity Labels.