Si los permisos a nivel de roles y tablas son como "el guardia en la puerta principal", entonces Row-Level Security es como un guardia personal que revisa si cada usuario puede entrar a cada habitación del edificio.
RLS ayuda a que un usuario solo pueda trabajar con las filas de la tabla que tiene permitidas. Por ejemplo:
- En una tienda online, el manager solo debe ver sus propios pedidos.
- En una plataforma CRM, el empleado ve solo los clientes de su equipo.
- En un sistema bancario, el cliente solo debe tener acceso a sus propias cuentas.
Cómo funciona RLS
La base de RLS es el concepto de políticas de acceso. Las políticas definen qué filas de la tabla son visibles para un rol o usuario y cuáles se pueden modificar (INSERT, UPDATE, DELETE).
Por defecto, RLS está desactivado para todas las tablas, y tienes que activarlo manualmente.
Activar RLS para una tabla
Vamos a crear una tabla orders, donde se guardan los pedidos de la tienda online:
CREATE TABLE orders (
order_id SERIAL PRIMARY KEY,
user_id INT NOT NULL,
product_name TEXT NOT NULL,
price NUMERIC NOT NULL
);
Agregamos algunos datos de prueba:
INSERT INTO orders (user_id, product_name, price)
VALUES
(1, 'Smartphone', 500),
(2, 'Portátil', 1000),
(1, 'Auriculares', 100),
(3, 'Teclado', 50);
Ahora activamos RLS para esta tabla:
ALTER TABLE orders ENABLE ROW LEVEL SECURITY;
¿Qué hicimos? Activamos el mecanismo de RLS, pero todavía no hay políticas creadas. Mientras no existan políticas, RLS realmente no afecta el acceso a la tabla.
Crear una política de acceso
Para agregar reglas de control de acceso, se usa el comando:
CREATE POLICY nombre_politica
ON tabla
[FOR { SELECT | INSERT | UPDATE | DELETE }]
TO rol
USING (condicion_acceso)
WITH CHECK (condicion_verificacion);
FOR: define para qué operaciones se aplica la política (SELECT,INSERT,UPDATE,DELETE). Si lo omites, la política se aplica a todas las operaciones.TO: indica para qué roles está activa la política. Si no lo pones, se aplica a cualquier rol.USING: pone la condición bajo la cual las filas serán visibles para el usuario.WITH CHECK: define la condición de verificación para operacionesINSERTyUPDATE.
Ejemplo: acceso solo a tus propios pedidos
Vamos a crear una política que permite a los usuarios ver solo sus propios pedidos. Supón que el identificador del usuario actual coincide con user_id en la tabla:
CREATE POLICY user_can_view_own_orders
ON orders
FOR SELECT
USING (user_id = current_user::INT);
¿Qué pasa aquí?
- La política se llama
user_can_view_own_orders. - Se aplica a la operación
SELECT. - Solo las filas donde
user_idcoincide con el identificador del usuario actual (current_user) son visibles.
Así que, si entras como usuario con user_id = 1, solo verás tus propios pedidos.
Comprobar cómo funciona RLS
Vamos a crear dos usuarios: user1 y user2.
CREATE ROLE user1 LOGIN PASSWORD 'password1';
CREATE ROLE user2 LOGIN PASSWORD 'password2';
Les damos acceso a la tabla:
GRANT SELECT ON orders TO user1, user2;
Ahora cambiamos al usuario user1 y probamos la consulta:
SELECT * FROM orders;
Resultado: solo verás las filas donde user_id = 1.
Políticas para INSERT
Supón que queremos permitir a los usuarios agregar solo sus propios pedidos (o sea, la fila con user_id debe coincidir con el identificador del usuario actual).
Creamos la política para INSERT:
CREATE POLICY user_can_insert_own_orders
ON orders
FOR INSERT
WITH CHECK (user_id = current_user::INT);
Ahora, si el usuario user1 intenta agregar un pedido donde user_id no es 1, la consulta fallará con error.
Políticas para UPDATE y DELETE
De forma parecida puedes crear políticas para modificar y borrar datos. Por ejemplo:
Para actualizar tus propios datos:
CREATE POLICY user_can_update_own_orders
ON orders
FOR UPDATE
USING (user_id = current_user::INT)
WITH CHECK (user_id = current_user::INT);
Para borrar tus propios datos:
CREATE POLICY user_can_delete_own_orders
ON orders
FOR DELETE
USING (user_id = current_user::INT);
Aplicar varias políticas
Puedes crear varias políticas para una misma tabla. Todas se aplican al mismo tiempo. Por ejemplo, si para un rol hay varias reglas, PostgreSQL las revisa todas (lógico AND).
Comprobar y depurar RLS
Para ver qué políticas hay en una tabla, usa el comando:
\di+ nombre_tabla
Si quieres desactivar RLS temporalmente (por ejemplo, para admin), ejecuta:
ALTER TABLE orders DISABLE ROW LEVEL SECURITY;
El rol de administrador SUPERUSER por defecto no está limitado por RLS, así que puede ver todos los datos.
Errores típicos al configurar RLS
Puedes tener errores si olvidas:
- Activar RLS con
ALTER TABLE ... ENABLE ROW LEVEL SECURITY. - Poner políticas para todas las operaciones (
SELECT,INSERT,UPDATE,DELETE). - Poner bien la condición en
USINGyWITH CHECK. Por ejemplo, si no revisasuser_id, puedes abrir acceso a todas las filas sin querer.
Row-Level Security es una de las herramientas de seguridad más potentes en PostgreSQL. Te permite configurar el acceso con precisión de fila y automatizar el control de acceso, lo que es súper importante para apps complejas con altos requisitos de protección de datos.
GO TO FULL VERSION