AiHummer
Русский
ВойтиЛичный кабинет
v1.2.x
{ }Swagger

Row-Level Security

v1.2.x · обновлено 2026-07-21

AiHummer многоарендный, и PostgreSQL Row-Level Security (RLS) — это дополнительная граница изоляции на уровне базы данных. При включённом RLS база данных — а не только код приложения — гарантирует, что запрос видит только строки, принадлежащие текущему арендатору.

Важно: RLS не заменяет аутентификацию, RBAC и правильную установку tenant_id в транзакции — это дополнительный слой под ними, а не замена.

Зачем RLS

Фильтрация на уровне приложения (WHERE tenant_id = ...) необходима, но хрупка: одно забытое условие может «утечь» данные между арендаторами. RLS переносит гарантию в PostgreSQL, так что даже нефильтрованный запрос вернёт только строки текущего арендатора. Это слой эшелонированной защиты под собственным ограничением области доступа приложения. Полную модель multitenancy — и как она сочетается с идемпотентными побочными эффектами — см. в Multitenancy и идемпотентность.

Ограниченная роль (опционально)

RLS включается опционально — передачей gateway второго подключения к базе, которое использует ограниченную роль вместо владельца:

# ~/.aihummer/etc/gateway.env
# Пул владельца — выполняет миграции, используется для system/bypass операций
AIHUMMER_DATABASE_URL=postgres://owner:...@localhost/aihummer

# Ограниченный пул приложения — действуют политики RLS (роль aihummer_app)
AIHUMMER_DB_APP_URL=postgres://aihummer_app:...@localhost/aihummer

Роль aihummer_app не является владельцем таблиц, поэтому PostgreSQL применяет к ней политики RLS. Запросы приложения идут через этот ограниченный пул. Включение RLS сводится к заданию AIHUMMER_DB_APP_URL — и локальные/стандартные (host-native) установки настраивают эту переменную автоматически, поэтому RLS активен «из коробки». «Опционально» он лишь в том смысле, что при нестандартном или ручном развёртывании AIHUMMER_DB_APP_URL нужно задать самому.

[!NOTE] Без AIHUMMER_DB_APP_URL шлюз использует пул владельца для всего, и RLS фактически не применяется. Задайте ограниченный пул (что за вас делает стандартный установщик), чтобы включить изоляцию на уровне базы данных.

[!IMPORTANT] RLS не зависит от тарифа. Он работает одинаково на всех тарифах, включая Community. Если на экране лицензии строка «Защита на уровне строк» показана как недоступная, это неточность самого экрана, а не состояние базы данных.

Где RLS активен сразу, а где его надо включить

Как вы ставили продукт Состояние RLS после установки
Обычная установка, PostgreSQL разворачивает установщик Активен. Ограниченная роль и AIHUMMER_DB_APP_URL создаются автоматически
Свой или управляемый PostgreSQL (адрес базы задан заранее) Не активен. Роль и AIHUMMER_DB_APP_URL заводит оператор
Установка без прав администратора (rootless) Не активен. То же самое

[!WARNING] Две ошибки, после которых RLS «включён», но не защищает. Первая: в AIHUMMER_DB_APP_URL указана роль-владелец таблиц или суперпользователь — PostgreSQL освобождает такие роли от политик, а шлюз при этом всё равно сообщит, что RLS активен. Используйте отдельную ограниченную роль. Вторая: на своём PostgreSQL ограниченная роль может быть создана автоматически с предсказуемым паролем — задайте ей собственный пароль до того, как база станет доступна по сети.

Ограничение по арендатору

Внутри запроса приложение устанавливает текущего арендатора (tenant_id) на подключении до выполнения запросов, ограниченных арендатором — концептуально db.WithTenant. После этого политики RLS на ограниченной роли ограничивают каждое чтение и запись строками этого арендатора. Область действия привязана к единице работы, поэтому она не утекает между параллельными запросами. Если приложение не установит tenant_id корректно, RLS не спасёт — поэтому этот шаг обязателен.

запрос ─▶ определить арендатора ─▶ db.WithTenant(арендатор) ─▶ запросы видят только его

Режим system / bypass для воркеров

Часть работы законно кросс-арендна или не привязана к арендатору — фоновые воркеры, планировщики, восстановление доставки и похожее обслуживание. Для них шлюз использует режим system (bypass), который работает на пуле владельца, вне политик RLS на арендатора, чтобы инфраструктурные задачи могли работать со всем набором данных.

[!WARNING] Режим bypass — только для доверенных внутренних воркеров. Кодовые пути обработки запросов, действующие от имени пользователя, всегда должны идти через ограниченный, привязанный к арендатору пул — никогда через путь bypass.

Миграции выполняются на пуле владельца

Изменения схемы требуют привилегий, которых у ограниченной роли нет, поэтому миграции всегда выполняются на пуле владельца (AIHUMMER_DATABASE_URL), под advisory-lock, при старте. Ограниченная роль aihummer_app используется только для обычного трафика приложения. Это держит разделение привилегий чистым: операции изменения схемы — у владельца; доступ к данным арендаторов — у ограниченной роли с применением RLS.

Куда дальше