Skip to content

Row Level Security

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;

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:

Terminal window
\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:

Terminal window
set role alice;

Si el usuario alice sólo quiere acceder a sus registros puede utlizar un where:

Terminal window
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:

Terminal window
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:

Terminal window
quit
docker exec -it postgres psql -U alice -d hr

Recuperar datos de la tabla department:

Terminal window
select * from department;
id | name | manager
----+-------+---------
1 | Sales | alice
(1 row)

La consulta devuelve las filas cuya columna de administrador es alice.

TODO: https://www.postgresql.org/docs/current/ddl-rowsecurity.html

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:

rolproductcustomer
managerselect, update, insertselect
anonymousselect
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.

El contingut d'aquest lloc web té llicència CC BY-NC-ND 4.0.

©2022-2025 xtec.dev