En entornos donde múltiples usuarios acceden a la misma base de datos, es habitual que queramos controlar qué registros específicos puede ver o modificar cada usuario. Por ejemplo, en una aplicación bancaria, un cliente no debería poder ver la cuenta de otro cliente, aunque ambos datos estén en la misma tabla.
Para este tipo de escenarios, PostgreSQL ofrece una característica muy potente: Row Level Security (RLS), o seguridad a nivel de fila. Es una alternativa rápida, fiable y muy útil a la encriptación u otros mecanismos mucho más intrusivos en el sistema.
¿Qué es RLS?
RLS es una funcionalidad de PostgreSQL que permite definir reglas de acceso a nivel de fila dentro de una tabla. En lugar de solo asignar permisos globales de SELECT
, INSERT
, UPDATE
o DELETE
sobre toda la tabla, con RLS podemos establecer políticas que filtren automáticamente las filas a las que un usuario puede acceder o modificar.
Esto significa que la restricción se aplica dentro del motor de la base de datos, no en la lógica de la aplicación. Así, aunque un usuario intente ejecutar un SELECT * FROM ...
, solo obtendrá las filas que cumplan las políticas que le correspondan.
Ventajas de RLS
- Transparencia para el aplicativo: Las restricciones se aplican directamente en la base de datos.
- Control de seguridad avanzado: Con unos pocos comandos de administración, se pueden establecer reglas claras.
- Escenarios ideales: Aunque no debe usarse de forma universal, es especialmente útil en soluciones multitenant.
Activando RLS
Por defecto, RLS está desactivado. Para activarlo en una tabla, debemos usar el siguiente comando:
ALTER TABLE nombre_tabla ENABLE ROW LEVEL SECURITY;
A partir de ese momento, PostgreSQL evaluará las políticas (POLICY
) que definamos para decidir qué filas puede ver, insertar, actualizar o borrar cada usuario.
Ejemplo práctico de RLS
A continuación, veremos un caso práctico para entender cómo funciona RLS. Trabajaremos con una tabla llamada clientes
, un administrador y dos usuarios (juan
y jose
). Cada usuario solo podrá ver y modificar sus propios datos, mientras que el administrador tendrá acceso completo.
1. Preparación del entorno
Primero, creamos la tabla y los usuarios:
CREATE TABLE clientes (
id SERIAL PRIMARY KEY,
nombre TEXT,
CCC TEXT -- cuenta bancaria
);
CREATE USER administrador PASSWORD 'aaa';
CREATE USER juan PASSWORD 'bbb';
CREATE USER jose PASSWORD 'ccc';
INSERT INTO clientes (nombre, CCC) VALUES ('juan', '998877');
INSERT INTO clientes (nombre, CCC) VALUES ('jose', '887766');
2. Activar RLS
Activamos RLS en la tabla clientes
:
ALTER TABLE clientes ENABLE ROW LEVEL SECURITY;
3. Crear las políticas
Administrador con acceso total
CREATE POLICY admin_all
ON clientes
TO administrador
USING (true)
WITH CHECK (true);
Usuarios normales: solo ven sus propias filas
CREATE POLICY all_view
ON clientes
FOR SELECT
USING (current_user = nombre);
La condición current_user = nombre
asegura que solo puedan consultar la fila cuyo campo nombre
coincida con su usuario de base de datos.
Usuarios normales: solo modifican sus propias filas
CREATE POLICY user_mod
ON clientes
FOR UPDATE
USING (current_user = nombre)
WITH CHECK (current_user = nombre);
Esto limita las actualizaciones para que un usuario no pueda editar datos de otros.
4. Asignar permisos complementarios
Asignamos los permisos necesarios para cada tipo de usuario:
-- Administrador: permisos totales
GRANT SELECT, INSERT, UPDATE, DELETE ON clientes TO administrador;
-- Usuarios normales: permisos limitados
GRANT SELECT (nombre, CCC) ON clientes TO public;
GRANT UPDATE (nombre) ON clientes TO public;
5. Probando el RLS
Veamos qué sucede al acceder con distintos usuarios:
Como administrador:
\c postgres administrador
SELECT * FROM clientes;
Resultado: Muestra todas las filas.
Como juan:
\c postgres juan
SELECT nombre, CCC FROM clientes;
Resultado: Solo muestra:
juan | 998877
Como jose:
\c postgres jose
SELECT nombre, CCC FROM clientes;
Resultado: Solo muestra:
jose | 887766
Beneficios de RLS
- Seguridad dentro del motor: Las restricciones no dependen del código de la aplicación.
- Escalabilidad: Se pueden manejar muchos usuarios con políticas claras y centralizadas.
- Flexibility: Es posible crear políticas diferentes para
SELECT
,UPDATE
,DELETE
oINSERT
. - Menos riesgo de fugas de datos: Incluso si alguien ejecuta consultas directas, seguirá limitado.
Conclusión
The Seguridad a nivel de fila (RLS) en PostgreSQL es una herramienta fundamental para sistemas multiusuario que manejan información sensible. Al establecer políticas claras y aplicarlas directamente en la base de datos, reducimos riesgos y aseguramos que cada usuario solo pueda acceder a los datos que le corresponden.
Con el ejemplo anterior, hemos visto cómo un administrador puede tener acceso completo mientras que cada usuario ve únicamente sus propios registros. Esta lógica se puede adaptar a sistemas mucho más complejos, como aplicaciones financieras, sistemas médicos o plataformas multiempresa.
No dejes de seguir lo último en seguridad informática y buenas prácticas para tu empresa, mantente actualizado en:
Hopla! Insights