Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Глава 30. PostgreSQL как часть модели безопасности

30.1. База данных как граница применения

База данных обычно рассматривается как место хранения.

В модели с RLS она становится ещё и местом принудительного применения ограничений.

Это не означает, что база данных становится владельцем всей модели авторизации.

Она получает дополнительную ответственность:

не вернуть физические строки, которые не должны быть доступны текущему запросу.


30.2. Авторизация и RLS — разные уровни

Полезно разделять:

Authorization

и:

Data enforcement

Авторизация отвечает:

Can(Subject, Action, Object)?

RLS отвечает:

Which rows can this SQL operation see or modify?

Поэтому архитектурно:

Relationship-based authorization
             ↓
Effective permission
             ↓
Object authorization
             ↓
PostgreSQL RLS
             ↓
Physical data

30.3. PostgreSQL не должен строить весь контекст

Если доступ зависит от длинной цепочки:

User
 → Group
 → Parent Group
 → Project
 → Role
 → Publication
 → Object

нет необходимости заставлять RLS каждый раз вычислять весь этот граф.

Это уже было сделано на этапе построения security projections.

База получает более компактное условие.

Так разделяются:

model construction

и:

data enforcement

30.4. Что именно проверяется в Guardian

Для объектной авторизации текущая схема использует:

object_scope

и:

effective_user_permission

Обычная ветка сопоставляет:

scope_type
scope_id

и проверяет:

permissionMask
    &
publicationMask
    &
requiredMask

Владелец проверяется отдельно через OWNER-scope.

Таким образом, PostgreSQL участвует в принятии решения, но получает уже материализованную модель.


30.5. Почему это не «Zanzibar внутри PostgreSQL»

Relationship-based подход и PostgreSQL RLS решают разные задачи.

Relationship-based authorization определяет, какие отношения и правила приводят к разрешению.

RLS ограничивает физические строки.

Поэтому архитектура может выглядеть так:

Relationship facts
       ↓
Security projections
       ↓
Authorization
       ↓
PostgreSQL RLS

Это не означает, что PostgreSQL является authorization engine целиком.


30.6. Контекст пользователя в базе

Чтобы RLS мог применять пользовательские ограничения, база должна знать контекст текущего запроса.

В Guardian используется:

current_company_id
current_user_id

Эти значения устанавливаются в рамках управляемого соединения.

Важно, что они не должны сохраняться как неконтролируемое состояние connection pool.


30.7. RlsDataSourceProxy

В текущей архитектуре приложение получает:

@Primary DataSource
        ↓
RlsDataSourceProxy
        ↓
physicalDataSource

Прокси не выполняет побочные SQL-операции просто при получении соединения.

RLS-контекст устанавливается лениво перед первым бизнес-SQL.

Это позволяет связать security context с тем же физическим соединением, на котором выполняется запрос.


30.8. Почему Flyway использует отдельный источник

Миграции базы данных — инфраструктурная операция.

Они не должны зависеть от пользовательского:

company_id
user_id

Поэтому:

Flyway
   ↓
physicalDataSource

а бизнес-приложение:

Hibernate / repositories
   ↓
RlsDataSourceProxy

Это два разных контекста доверия.


30.9. RLS как защита от ошибки приложения

Допустим, разработчик написал новый запрос:

SELECT *
FROM documents

и забыл добавить фильтр доступа.

Если единственной защитой была логика приложения, запрос может вернуть лишние данные.

При наличии корректного RLS запрос всё равно проходит через физическую границу:

SQL
 ↓
RLS policy
 ↓
allowed rows

Это не отменяет необходимость правильной авторизации.

Но создаёт дополнительный уровень защиты от ошибок конкретного пути доступа.


30.10. Почему RLS не должен быть универсальным

Не вся информация обязана защищаться одинаковым способом.

Для одних данных естественной границей являются строки.

Для других:

  • бизнес-операция;

  • состояние процесса;

  • отдельное поле;

  • внешний сервис;

  • документ;

  • результат вычисления.

Поэтому решение:

Всё защитим RLS

так же неправильно, как:

Ничего не будем защищать на уровне базы.

RLS должен соответствовать физической структуре данных и модели угроз.


30.11. Главный вывод

PostgreSQL может быть частью security architecture, не становясь всей моделью безопасности.

В рассматриваемой архитектуре его роль можно выразить так:

Source security facts
        ↓
Security projections
        ↓
Effective authorization
        ↓
Object authorization
        ↓
PostgreSQL RLS
        ↓
Physical data

Проекции строят производное состояние.

Авторизация принимает логическое решение.

RLS физически ограничивает данные.

Так три разных задачи остаются различимыми.