JavaRush /Курси /SQL SELF /Контроль доступу на рівні рядків: Row-Level Security (RLS...

Контроль доступу на рівні рядків: Row-Level Security (RLS)

SQL SELF
Рівень 47 , Лекція 3
Відкрита

Якщо права на рівні ролей і таблиць — це "охоронець біля вхідних дверей", то Row-Level Security — це персональний охоронець, який перевіряє, чи можна тому чи іншому юзеру заходити в кожну окрему кімнату в будівлі.

RLS допомагає зробити так, щоб користувач міг працювати тільки з тими рядками в таблиці, які йому дозволені. Наприклад:

  • В інтернет-магазині менеджер має бачити тільки свої замовлення.
  • У CRM-платформі співробітник бачить лише клієнтів своєї команди.
  • У банківській системі клієнт повинен мати доступ тільки до своїх рахунків.

Як працює RLS

В основі роботи RLS лежить концепція політик доступу. Політики визначають, які рядки таблиці видимі для ролі чи користувача і які доступні для змін (INSERT, UPDATE, DELETE).

За замовчуванням RLS вимкнений для всіх таблиць, і вмикається вручну.

Увімкнення RLS для таблиці

Давай створимо таблицю orders, де зберігаються замовлення інтернет-магазину:

CREATE TABLE orders (
    order_id SERIAL PRIMARY KEY,
    user_id INT NOT NULL,
    product_name TEXT NOT NULL,
    price NUMERIC NOT NULL
);

Додамо кілька тестових даних:

INSERT INTO orders (user_id, product_name, price)
VALUES
    (1, 'Смартфон', 500),
    (2, 'Ноутбук', 1000),
    (1, 'Навушники', 100),
    (3, 'Клавіатура', 50);

Тепер увімкнемо RLS для цієї таблиці:

ALTER TABLE orders ENABLE ROW LEVEL SECURITY;

Що ми зробили? Ми активували механізм RLS, але самі політики ще не встановлені. Поки політики не створені, RLS фактично не впливає на доступ до таблиці.

Створення політики доступу

Щоб додавати правила для керування доступом, використовується команда:

CREATE POLICY ім'я_політики
ON таблиця
[FOR { SELECT | INSERT | UPDATE | DELETE }]
TO роль
USING (умова_доступу)
WITH CHECK (умова_перевірки);
  • FOR: визначає, для яких операцій застосовується політика (SELECT, INSERT, UPDATE, DELETE). Якщо цей параметр пропустити, політика діє для всіх операцій.
  • TO: вказує, для яких ролей політика активна. Якщо не вказано, політика застосовується до будь-якої ролі.
  • USING: задає умову, при якій рядки будуть видимі користувачу.
  • WITH CHECK: визначає умову перевірки для операцій INSERT і UPDATE.

Приклад: доступ тільки до своїх замовлень

Створимо політику, яка дозволяє користувачам бачити тільки свої замовлення. Нехай ідентифікатор поточного користувача збігається з user_id у таблиці:

CREATE POLICY user_can_view_own_orders
ON orders
FOR SELECT
USING (user_id = current_user::INT);

Що тут відбувається?

  • Політика називається user_can_view_own_orders.
  • Вона застосовується до операції SELECT.
  • Тільки рядки, де user_id збігається з ідентифікатором поточного користувача (current_user), видимі.

Отже, якщо ти зайшов у систему як користувач з user_id = 1, ти побачиш тільки свої замовлення.

Перевірка роботи RLS

Створимо двох користувачів: user1 і user2.

CREATE ROLE user1 LOGIN PASSWORD 'password1';
CREATE ROLE user2 LOGIN PASSWORD 'password2';

Дамо ролям доступ до таблиці:

GRANT SELECT ON orders TO user1, user2;

Тепер перемикаємось на користувача user1 і пробуємо виконати запит:

SELECT * FROM orders;

Результат: ти побачиш тільки рядки, де user_id = 1.

Політики для INSERT

Скажімо, ми хочемо дозволити користувачам додавати тільки свої замовлення (тобто рядок з user_id має збігатися з ідентифікатором поточного користувача).

Створимо політику на INSERT:

CREATE POLICY user_can_insert_own_orders
ON orders
FOR INSERT
WITH CHECK (user_id = current_user::INT);

Тепер, якщо користувач user1 спробує додати замовлення, де user_id не дорівнює 1, то запит завершиться з помилкою.

Політики для UPDATE і DELETE

Аналогічно можна створювати політики для зміни й видалення даних. Наприклад:

Для оновлення своїх даних:

CREATE POLICY user_can_update_own_orders
ON orders
FOR UPDATE
USING (user_id = current_user::INT)
WITH CHECK (user_id = current_user::INT);

Для видалення своїх даних:

CREATE POLICY user_can_delete_own_orders
ON orders
FOR DELETE
USING (user_id = current_user::INT);

Застосування кількох політик

Ти можеш створити кілька політик для однієї таблиці. Всі вони будуть застосовуватись одночасно. Наприклад, якщо для однієї ролі діє кілька правил, PostgreSQL перевірить їх всі (логічне І).

Перевірка та дебаг RLS

Щоб перевірити, які політики встановлені для таблиці, використовуй команду:

\di+ ім'я_таблиці

Якщо хочеш тимчасово вимкнути RLS (наприклад, для адміна), виконай:

ALTER TABLE orders DISABLE ROW LEVEL SECURITY;

Адмінська роль SUPERUSER за замовчуванням не обмежена RLS, тому бачить всі дані.

Типові помилки при налаштуванні RLS

Помилки можуть виникнути, якщо ти забудеш:

  • Активувати RLS командою ALTER TABLE ... ENABLE ROW LEVEL SECURITY.
  • Встановити відповідні політики для всіх операцій (SELECT, INSERT, UPDATE, DELETE).
  • Коректно вказати умову в USING і WITH CHECK. Наприклад, не перевіривши user_id, можна випадково відкрити доступ до всіх рядків.

Row-Level Security — це один із найпотужніших інструментів безпеки в PostgreSQL. Він дозволяє налаштувати доступ з точністю до рядка й автоматизувати керування доступом, що особливо важливо для складних додатків із високими вимогами до захисту даних.

Коментарі
ЩОБ ПОДИВИТИСЯ ВСІ КОМЕНТАРІ АБО ЗАЛИШИТИ КОМЕНТАР,
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ