Saltar al contingut

Row Level Security

La seguretat en l'àmbit de fila (RLS) és una característica que et permet restringir les files retornades per una consulta en funció de l'usuari que executa la consulta.

El RLS et permet controlar l’accés a files individuals en taules segons l’usuari actual i condicions específiques definides per les polítiques.

Els passos bàsics per implementar la seguretat en l’àmbit de fila són els següents:

Primer, habilita la seguretat en l’àmbit de fila en una taula utilitzant la declaració ALTER TABLE:

ALTER TABLE table_name
ENABLE ROW LEVEL SECURITY;

En segon lloc, crea una nova política de seguretat en l’àmbit de fila per a una taula utilitzant la declaració CREATE POLICY:

CREATE POLICY name ON table_name
USING (condition);

A la política, es defineix una condició que determina quines files són visibles.

Tingues en compte que els superusuaris i rols amb l’atribut BYPASSRLS poden ometre el sistema de seguretat de files quan accedeixen a una taula.

A més, els propietaris de taules també passen per alt la seguretat en l’àmbit de fila.

Per aplicar la seguretat en l’àmbit de fila als propietaris de taules, pots modificar la taula utilitzant l’opció FORCE ROW LEVEL SECURITY:

ALTER TABLE table_name
FORCE ROW LEVEL SECURITY;

Inicia una sessió psql en una base de dades.

Per exemple:

Terminal window
connect-wsl postgres
docker exec -it postgres psql -U postgres

A continuació crea una taula i uns rols on els rols poden recuperar dades de la taula on la columna manager coincideixi amb el rol actual.

Crea una base de dades hr:

create database hr;

Canvia la base de dades actual a la base de dades hr:

Terminal window
\c hr
You are now connected to database "hr" as user "postgres".

Crea una nova taula department per emmagatzemar dades del departament:

create table department (
id serial primary key,
name text not null unique,
manager name not null
);

Insereix algunes files a la taula department:

insert into department(name, manager)
values('Sales', 'alice'), ('Marketing', 'bob'), ('IT', 'carol');

Crea un rol de grup anomenat manager:

create role manager;

Atorga el privilegi select de totes les taules de l’esquema public al rol de grup manager:

grant select on all tables in schema public to manager;

Crea tres nous rols alice, bob i carol, i assigna’ls com a membres del rol de grup 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;

Els rols alice, bob i carol heretaran implícitament els privilegis dels administradors de rols de grup.

En altres paraules, poden recuperar dades de totes les taules de l’esquema public.

Canvia al rol alice:

Terminal window
set role alice;

Si l’usuari alice només vol accedir als seus registres pot utilitzar un where:

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

Però la base de dades no impedeix a l’usuari alice accedir a tots els registres de la taula department:

select * from department;
id | name | manager
----+-----------+---------
1 | Sales | alice
2 | Marketing | bob
3 | IT | carol
(3 rows)

Torna al rol postgres:

Terminal window
set role postgres;

Habilita la seguretat en l’àmbit de fila a la taula department:

alter table department enable row level security;

Crea una política que permeti que l’usuari actual pugui accedir a les files on el valor de la columna manager de la taula department coincideixi amb el nom del rol actual:

create policy department_manager on department to manager
using (manager = current_user);

Tanca la connexió i torna a iniciar sessió com l’usuari alice:

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

Recuperar dades de la taula department:

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

La consulta retorna les files on la columna d’administrador és alice.

TODO: Postgres - RLS

A continuació tens el disseny de la base de dades sales:

user

order pk

product pk

Customer

user text pk

name text

Product

id int pk

name text

Order

id int pk

date timestamp

Item

quantity int

user text

La base de dades té tres rols: manager, product i customer.

A continuació tens parcialment implementada la seguretat de la base de dades:

rolproductcustomer
managerselect, update, insertselect
anonymousselect
customer (in anonymous)select (rls), update (rls)

Has de:

  • Finalitzar de dissenyar i escriure el codi SQL corresponent.
  • Inserir algunes dades de prova.
  • Provar que la base de dades funciona correctament i és segura.

Quan treballem amb bases de dades, és habitual crear un fitxer seed.sql que conté un subconjunt de dades de producció per a fer proves.

Durant el desenvolupament inicial, és acceptable abocar tota la base de dades i restaurar-la a la màquina de desenvolupament. No obstant això, quan ja tens usuaris en producció això esdevé un problema de seguretat - realment vols abocar les dades dels teus usuaris a les teves màquines locals?

Hi ha moltes maneres de resoldre això, però una manera elegant de fer-ho utilitzant la Seguretat en l’àmbit de Fila (Row Level Security, RLS) de PostgreSQL.

El concepte és simple:

  1. Crear un usuari de base de dades amb accés restringit.
  2. Definir algunes regles RLS per a aquest usuari, limitant a quines dades pot accedir.
  3. Executar pg_dump com aquest usuari.

Per a aquest escenari, imagina’t que tens una taula anomenada profiles a la teva base de dades::

Partial data dumps using Postgres Row Level Security


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

©2022-2025 xtec.dev