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.

TODO