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

Cómo implementar Row-Level Security en SQL Server

João Barros 05 de July de 2026 5 min de lectura

Row-Level Security (RLS) en SQL Server permite que cada usuario vea solo las filas de una tabla que le corresponden, sin duplicar tablas ni cambiar el código de las aplicaciones. Es una pieza central de la gobernanza de datos, porque la regla de acceso queda guardada en la propia base de datos y se aplica automáticamente a cualquier consulta — venga de un informe en Power BI, de una API o de SQL Server Management Studio. En este paso a paso vas a crear una política de RLS desde cero y comprobarla con usuarios diferentes.

Requisitos previos

  • SQL Server 2016 o superior, o una base de datos en Azure SQL Database.
  • Una herramienta de consulta, como SQL Server Management Studio (SSMS) o Azure Data Studio.
  • Permisos para crear tablas, funciones y políticas de seguridad (por ejemplo, el rol db_owner en una base de datos de pruebas).
  • Conocimientos básicos de T-SQL, como CREATE TABLE y SELECT.

La idea detrás de RLS es simple y se apoya en dos piezas: una función de predicado, que decide si una fila es visible, y una política de seguridad, que aplica esa función a una tabla. Vamos a construir las dos.

Paso 1: Crear una tabla de ejemplo

Empezamos con una tabla de ventas donde cada fila pertenece a un comercial. La columna SalesRep guarda el nombre del usuario dueño de la fila; es esa columna la que la política usará para filtrar.

CREATE TABLE dbo.Sales
(
    SaleId   INT IDENTITY PRIMARY KEY,
    SalesRep SYSNAME,
    Product  NVARCHAR(50),
    Amount   DECIMAL(10,2)
);

INSERT INTO dbo.Sales (SalesRep, Product, Amount) VALUES
    ('ana',   'Teclado', 120.00),
    ('bruno', 'Monitor', 240.00),
    ('ana',   'Rato',     45.00);

Paso 2: Crear usuarios para probar

Para ver RLS en acción necesitamos usuarios diferentes. Creamos dos usuarios sin login — bastan para la demostración — y les damos permiso de lectura sobre la tabla.

CREATE USER ana WITHOUT LOGIN;
CREATE USER bruno WITHOUT LOGIN;

GRANT SELECT ON dbo.Sales TO ana, bruno;

Paso 3: Crear la función de predicado

La regla de acceso vive en una función en línea con valor de tabla (inline table-valued function). Devuelve el valor 1 cuando la fila debe aparecer para el usuario. En este ejemplo, una fila es visible si el valor de SalesRep es igual al nombre del usuario actual, obtenido con USER_NAME(). Guardamos la función en un schema propio, llamado Security, por organización y buenas prácticas.

CREATE SCHEMA Security;
GO

CREATE FUNCTION Security.fn_vendasPorComercial(@SalesRep AS SYSNAME)
    RETURNS TABLE
WITH SCHEMABINDING
AS
    RETURN SELECT 1 AS resultado
    WHERE @SalesRep = USER_NAME() OR USER_NAME() = 'dbo';
GO

La cláusula WITH SCHEMABINDING es obligatoria para funciones usadas en RLS. La condición extra USER_NAME() = 'dbo' garantiza que el administrador sigue viendo todas las filas, algo práctico para tareas de gestión y mantenimiento.

Paso 4: Crear la política de seguridad

Solo falta conectar la función a la tabla. Una SECURITY POLICY con un FILTER PREDICATE aplica la función a la columna SalesRep de la tabla dbo.Sales. Con STATE = ON, la política queda activa de inmediato.

CREATE SECURITY POLICY Security.VendasFiltro
    ADD FILTER PREDICATE Security.fn_vendasPorComercial(SalesRep)
    ON dbo.Sales
    WITH (STATE = ON);

Un FILTER PREDICATE oculta las filas en las lecturas (SELECT, UPDATE, DELETE). También existe el BLOCK PREDICATE, que impide que un usuario inserte o cambie filas fuera de su ámbito — útil cuando también quieres proteger la escritura.

Comprobar el resultado

Ahora podemos consultar la tabla fingiendo ser cada usuario, con EXECUTE AS. La comercial "ana" debe ver solo sus dos filas y "bruno" solo la suya.

EXECUTE AS USER = 'ana';
SELECT * FROM dbo.Sales;   -- devolve as 2 linhas da ana
REVERT;

EXECUTE AS USER = 'bruno';
SELECT * FROM dbo.Sales;   -- devolve a 1 linha do bruno
REVERT;

Si cada usuario ve solo sus propias filas, RLS está funcionando. Fíjate en que la consulta es exactamente la misma en ambos casos: el filtrado ocurre de forma transparente, sin que nadie tenga que añadir un WHERE. Esa transparencia es lo que hace a RLS tan útil — la regla se queda en el lugar correcto, la base de datos, en vez de repartida por decenas de informes.

Conclusión

Con una función de predicado y una política de seguridad ya controlas el acceso a los datos fila a fila, directamente en SQL Server. A partir de aquí puedes hacer la regla más dinámica — por ejemplo, usar SESSION_CONTEXT para identificar al usuario de la aplicación en escenarios multi-tenant — o reforzar la escritura con un BLOCK PREDICATE. Para desactivar la política durante una prueba, basta con ALTER SECURITY POLICY Security.VendasFiltro WITH (STATE = OFF). ¿Qué otra tabla de tu modelo se beneficiaría de una regla de acceso a nivel de fila?