security(rls): ENABLE_RLS обязателен в production (fatal без флага)

Шаг 0.1 (завершение) плана production-готовности:
- прод: ENABLE_RLS=true включён, 31 таблица ENABLE+FORCE проверена
- код: fatal при NODE_ENV=production без ENABLE_RLS
- .env.example + DOCKER.md: пометки об обязательности
This commit is contained in:
2026-09-08 10:55:58 +03:00
parent 12e797eb1a
commit 639036c87e
4 changed files with 31 additions and 1 deletions

View File

@@ -31,6 +31,11 @@ VAPID_PRIVATE_KEY=your-vapid-private-key
# SendGrid API key for transactional email (optional — app works without it) # SendGrid API key for transactional email (optional — app works without it)
# SENDGRID_API_KEY=SG.xxxxxxxxxxxx # SENDGRID_API_KEY=SG.xxxxxxxxxxxx
# Row Level Security (изоляция tenant'ов на уровне БД).
# ОБЯЗАТЕЛЬНО для production: без него процесс не стартует (fatal при NODE_ENV=production).
# В dev можно не задавать (safe default — политики существуют, но не активны).
# ENABLE_RLS=true
# ============================================= # =============================================
# Database — choose ONE of the two modes below # Database — choose ONE of the two modes below
# ============================================= # =============================================

View File

@@ -212,6 +212,11 @@ xxx...
3. Создаёт MinIO bucket если настроен S3 (автоматически) 3. Создаёт MinIO bucket если настроен S3 (автоматически)
4. Запускает сервер приложения (`npm run start`) 4. Запускает сервер приложения (`npm run start`)
**Row Level Security (RLS):** при `ENABLE_RLS=true` на старте включается ENABLE+FORCE RLS
на 31 таблице с проверкой политик (schema drift, count политик) — при расхождении процесс падает.
**В production (`NODE_ENV=production`) `ENABLE_RLS=true` обязателен** — без него процесс не стартует.
В development флаг можно не задавать (политики существуют, но не активны).
--- ---
## Изменение схемы базы данных ## Изменение схемы базы данных

View File

@@ -429,3 +429,16 @@
- Что осталось (прод, с подтверждения): 1) добавить ENABLE_RLS=true в .env сервера и перезапустить app, проверить; 2) затем задеплоить fatal-проверку (NODE_ENV=production без ENABLE_RLS → процесс не стартует) + пометки в .env.example/DOCKER.md. - Что осталось (прод, с подтверждения): 1) добавить ENABLE_RLS=true в .env сервера и перезапустить app, проверить; 2) затем задеплоить fatal-проверку (NODE_ENV=production без ENABLE_RLS → процесс не стартует) + пометки в .env.example/DOCKER.md.
- Влияние на поиск/UX: нет. - Влияние на поиск/UX: нет.
- Подводные камни: порядок важен — fatal-проверку деплоить ТОЛЬКО после включения флага на проде, иначе app не поднимется. - Подводные камни: порядок важен — fatal-проверку деплоить ТОЛЬКО после включения флага на проде, иначе app не поднимется.
---
## [0.1] RLS обязательным в production — завершение
- Статус: ✅ done
- Что сделано после локальной проверки (см. запись выше):
1. Прод: бэкап БД (crm-20260908-075039.dump.gz), `ENABLE_RLS=true` в /opt/crm/.env, recreate app — старт-лог «Startup RLS: active — ENABLE+FORCE verified on 31 tables, 31 policies», health 200, поиск/списки через API работают.
2. Код: `server/index.ts` — при NODE_ENV=production без ENABLE_RLS=true — fatal (процесс не поднимается); dev — предупреждение.
3. Документация: `.env.example` (обязательность для production), `DOCKER.md` (sequence при старте + блок про RLS).
- Как проверялось: на проде подтверждено включение (pg_class relrowsecurity+relforcerowsecurity=31), smoke через API; локально — полный цикл на копии прод-БД.
- Влияние на поиск/UX: нет.
- Подводные камни: при переносе на новый сервер — сначала ENABLE_RLS=true в .env, иначе app не поднимется (это и есть цель шага).

View File

@@ -985,8 +985,15 @@ async function runStartupDataPatches() {
} }
log(`Startup RLS: active — ENABLE+FORCE verified on ${rlsVerified} tables, ${policyVerified} policies`); log(`Startup RLS: active — ENABLE+FORCE verified on ${rlsVerified} tables, ${policyVerified} policies`);
} else if (process.env.NODE_ENV === "production") {
// Шаг 0.1: в production RLS обязателен — без изоляции tenant'ов на уровне БД
// процесс не поднимается.
throw new Error(
"Startup RLS: ENABLE_RLS=true is REQUIRED in production. " +
"Set ENABLE_RLS=true in the environment and restart."
);
} else { } else {
log("Startup RLS: ENABLE_RLS not set — policies exist but inactive (safe default)"); log("Startup RLS: ENABLE_RLS not set — policies exist but inactive (safe default, dev only)");
} }
const seedDir = path.resolve( const seedDir = path.resolve(