Cómo implementar Column-Level Security en SQL Server
Proteger columnas sensibles — como salarios, números de identificación fiscal o datos de contacto — es una necesidad común en cualquier base de datos. Column-Level Security en SQL Server permite decidir, columna a columna, quién puede ver qué, sin duplicar tablas ni mantener vistas complicadas. Con los permisos GRANT y DENY aplicados directamente a las columnas, controlas el acceso con pocas líneas de T-SQL y mantienes una única fuente de datos.
Requisitos previos
- Una instancia de SQL Server (2016 o superior) o Azure SQL Database.
- SQL Server Management Studio (SSMS) o Azure Data Studio.
- Permisos de administrador en la base de datos para crear usuarios y conceder permisos.
- Conocimientos básicos de T-SQL (SELECT y CREATE TABLE).
Paso 1: Crear una tabla de ejemplo
Para este ejemplo, creamos una tabla de empleados con una columna sensible — Salario — que queremos ocultar al equipo de soporte, manteniendo visibles el nombre y el departamento.
CREATE TABLE dbo.Funcionarios
(
FuncionarioID INT PRIMARY KEY,
Nome NVARCHAR(100),
Departamento NVARCHAR(50),
Salario DECIMAL(10,2)
);
INSERT INTO dbo.Funcionarios VALUES
(1, N'Ana Silva', N'Financeiro', 3200.00),
(2, N'Bruno Costa', N'Suporte', 1800.00);
Paso 2: Crear un usuario y un rol
A continuación, creamos un usuario de base de datos y un rol. Asignar permisos a un rol, y no a cada persona, es una buena práctica de gobernanza: cuando alguien entra o sale del equipo, basta con añadir o quitar el miembro del rol.
-- Database user without login (simple for testing)
CREATE USER SuporteUser WITHOUT LOGIN;
-- Role for the support team
CREATE ROLE SuporteRole;
ALTER ROLE SuporteRole ADD MEMBER SuporteUser;
Paso 3: Conceder acceso solo a las columnas permitidas
Aquí está el núcleo de Column-Level Security. En lugar de conceder SELECT sobre toda la tabla, concedemos SELECT solo en las columnas que el equipo puede consultar. La columna Salario simplemente se queda fuera de la lista.
GRANT SELECT ON dbo.Funcionarios(FuncionarioID, Nome, Departamento) TO SuporteRole;
Este enfoque es más seguro y más fácil de mantener que crear una vista solo con las columnas permitidas, porque las reglas quedan guardadas en el propio motor de permisos de SQL Server. Los permisos a nivel de columna funcionan con SELECT, UPDATE y REFERENCES.
Paso 4: Bloquear una columna con DENY (patrón alternativo)
A veces es más práctico conceder acceso a casi todo y bloquear solo una o dos columnas. En ese caso, concede SELECT sobre la tabla y usa DENY en la columna sensible. Es importante saber que DENY siempre tiene prioridad sobre GRANT: incluso con permiso sobre la tabla, la columna denegada permanece inaccesible.
GRANT SELECT ON dbo.Funcionarios TO SuporteRole;
DENY SELECT ON dbo.Funcionarios(Salario) TO SuporteRole;
Elige solo uno de los patrones — el del Paso 3 (lista de permitidos) o el del Paso 4 (lista de denegados) — según sea más corto enumerar lo que está permitido o lo que está prohibido.
Verificar el resultado
No necesitas iniciar sesión como otro usuario para probar. Usa EXECUTE AS para asumir la identidad de SuporteUser en la misma ventana y REVERT para volver a tu propio usuario. Fíjate en que un SELECT con asterisco falla, porque incluye la columna protegida.
EXECUTE AS USER = 'SuporteUser';
-- This WORKS (only permitted columns)
SELECT FuncionarioID, Nome, Departamento FROM dbo.Funcionarios;
-- This FAILS: "The SELECT permission was denied on the column 'Salario'"
SELECT * FROM dbo.Funcionarios;
REVERT;
Si la primera consulta devuelve las filas y la segunda termina con un error de permiso en la columna Salario, entonces Column-Level Security está configurada correctamente.
Conclusión
En pocos minutos has restringido el acceso a una columna sensible sin duplicar datos ni crear objetos adicionales. El siguiente paso natural es combinar esta técnica con Row-Level Security, para controlar filas y columnas a la vez, o organizar los permisos en roles por departamento para simplificar la gestión. ¿Cuál es la primera columna de tu base de datos que debería quedar protegida hoy mismo?