La seguridad a nivel de fila (RLS) es una característica que le permite restringir las filas devueltas por una consulta en función del usuario que ejecuta la consulta.
Introducción
El RLS le permite controlar el acceso a filas individuales en tablas según el usuario actual y condiciones específicas definidas por las políticas.
Los pasos básicos para implementar la seguridad a nivel de fila son los siguientes:
Primero, habilita la seguridad a nivel de fila en una tabla usando la delclaración ALTER TABLE
:
ALTER TABLE table_name
ENABLE ROW LEVEL SECURITY;
En segundo lugar, crea una nueva política de seguridad a nivel de fila para una tabla utilizando la declaración CREATE POLICY
:
CREATE POLICY name ON table_name
USING (condition);
En la política, se define una condición que determina qué filas son visibles.
Ten en cuenta que los superusuarios y roles con el atributeo BYPASSRLS
pueden omitir el sistema de seguridad de filas al acceder a una tabla.
Además, los propietarios de tablas también pasan por alto la seguridad a nivel de fila.
Para aplicar la seguridad a nivel de fila a los propietarios de tablas, puede smodificar la tabla utilizando la opción FORCE ROW LEVEL SECURITY
:
ALTER TABLE table_name
FORCE ROW LEVEL SECURITY;
Ejemplo: deparment
Inicia una sesión psql en una base de datos.
Por ejemplo:
> connect-wsl postgres
> docker exec -it postgres psql -U postgres
A continuación crearás una tabla y unos roles donde los roles pueden recuperar datos de la tabla cuya columna manager
coincida con el rol actual.
Crea una base de datos hr
:
create database hr;
Cambia la base de datos actual a la base de datos hr
:
\c hr
You are now connected to database "hr" as user "postgres".
Crea una nueva tabla department
para almacenar datos del departamento:
create table department (
id serial primary key,
name text not null unique,
manager name not null
);
Inserta algunas filas en la tabla department
:
insert into department(name, manager)
values('Sales', 'alice'), ('Marketing', 'bob'), ('IT', 'carol');
Crea un rol de grupo llamado manager
:
create role manager;
Otorga el privilegio select
de todas las tablas del esquema public
al rol de grupo manager
:
grant select on all tables in schema public to manager;
Crea tres nuevos roles alice
, bob
y carol
, y asígnalos como miembros del rol de grupo `manager:
create role alice with login password 'password' in role manager;
create role bob with login password 'password' in role manager;
create role carol with login password 'password' in role manager;
Los roles alice
, boby
y carol
heredarán implícitamente los privilegios de los administradores de roles de grupo.
En otras palabras, pueden recuperar datos de todas las tablas del esquena public
.
Canvia al rol alice
:
set role alice;
Si el usuario alice
sólo quiere acceder a sus registros puede utlizar un where
:
select * from department where manager = 'alice';
id | name | manager
----+-------+---------
1 | Sales | alice
(1 row)
Pero la base de datos no impide al usuario alice
acceder a todos los registros de la tabla deparment
:
select * from department;
id | name | manager
----+-----------+---------
1 | Sales | alice
2 | Marketing | bob
3 | IT | carol
(3 rows)
Vuelve al rol postgres
:
set role postgres;
Habilita la seguridad a nivel de fila en la tabla deparment
:
alter table department enable row level security;
Crea una política que permita que el usuario actual pueda acceder a las filas cuyo valor en la columna manager
de la tabla department
coincida con el nombre del rol actual:
create policy department_manager on department to manager
using (manager = current_user);
Cierra la conexión y vuelve a iniciar sesion com el usuario alice
:
quit
docker exec -it postgres psql -U alice -d hr
Recuperar datos de la tabla department
:
select * from department;
id | name | manager
----+-------+---------
1 | Sales | alice
(1 row)
La consulta devuelve las filas cuya columna de administrador es alice
.
Ejempo: user
TODO: https://www.postgresql.org/docs/current/ddl-rowsecurity.html
Activitat: sales
A continuación tienes el diseño de la base de datos sales
:
classDiagram direction LR class Customer { user text pk name text } class Product { id int pk name text } class Order { id int pk date timestamp } Order --> Customer : user class Item { quantity int user text } Item --> Order : order pk Item --> Product : product pk
La base de datos tiene tres roles: manager
, product
y customer
.
A continuación tienes parcialmente implementada la seguridad de la base de datos:
rol | product | customer |
---|---|---|
manager |
select , update , insert |
select |
anonymous |
select |
|
customer (in anonymous ) |
select (rls), update (rls) |
Tienes que:
- Finalizar de diseñar y escribir el código SQL correspondiente.
- Insertar algunos datos de prueba.
- Probar que la base de datos funciona correctament y es segura.