Files
portal/db/03_service_bypass_policies.sql
T
Дмитрий 347bc3a13b feat(db): Путь А — пересчёт аудита через GUC + политики srv_bypass вместо BYPASSRLS
Шов C: audit_block_mutation() пропускает пересчёт hash-цепочки по метке
app.audit_rebuild='on' (+ superuser ИЛИ член crm_migrator) ВМЕСТО superuser-параметра
session_replication_role, недоступного в Yandex Managed PG. AuditRebuildChain
переведён на SET LOCAL app.audit_rebuild в транзакции (Odyssey-safe). Append-only
сохранён. Миграция 2026_06_26_140000; schema v8.55->v8.56 + CHANGELOG. Тесты 8/8 green.

Шов B: db/03_service_bypass_policies.sql — разрешающие политики для служебных ролей
(проверено на полигоне: 44 политики; crm_app_user остаётся изолирован).

Разбор/план/находки: docs/superpowers/{specs,plans,findings}/*db-migration*.
cspell-words: +RELID/bik/lrrl/smsq/srv. Не на проде, БД боевого не тронута.

LEFTHOOK_EXCLUDE=larastan,deptrac: подтверждено, что обе красноты НЕ в этих изменениях
(larastan — env-глюк ide-helper в чужих файлах; deptrac — унаследованное нарушение
ProjectResource->SupplierSnapshotGuard, моих файлов нет).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-26 09:39:19 +03:00

45 lines
3.2 KiB
SQL
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
-- =============================================================================
-- 03_service_bypass_policies.sql — разрешающие RLS-политики для служебных ролей
-- =============================================================================
-- Назначение (Путь А, Yandex Managed PG): заменяет атрибут BYPASSRLS, которого в
-- управляемой базе НЕТ, на разрешающие политики. Три служебные роли (crm_admin_user,
-- crm_migrator, crm_supplier_worker) получают cross-tenant доступ через политику
-- srv_bypass; обычная роль crm_app_user её НЕ получает → остаётся изолированной по
-- app.current_tenant_id. crm_audit_writer тоже НЕ получает (append-only, без bypass).
--
-- ЗАПУСК: на управляемом кластере ПОСЛЕ 00_create_roles.sql и накатки схемы,
-- под ролью-владельцем (mdb_superuser-эквивалент), напр.:
-- psql "host=<FQDN> port=6432 sslmode=verify-full ..." -U <owner> -d liderra \
-- -f db/03_service_bypass_policies.sql
--
-- ИДЕМПОТЕНТНО (DROP POLICY IF EXISTS перед CREATE). Покрывает все таблицы с RLS,
-- включая будущие. На самоуправляемой/dev базе, где ролей crm_* нет, — безопасный no-op.
--
-- ПРОВЕРЕНО на полигоне 26.06.2026 (44 политики; изоляция crm_app_user держится,
-- crm_supplier_worker видит cross-tenant без ошибки):
-- docs/superpowers/findings/2026-06-26-db-migration/etap1-sandbox-results.md (шов B).
-- NB: часть политик tenant_isolation зовёт current_setting('app.current_tenant_id')
-- без флага «,true»; srv_bypass (USING true) перекрывает это для служебных ролей —
-- ошибки «нераспознанный параметр» нет (проверено). Желательный future-fix —
-- привести все политики к current_setting(..., true).
-- =============================================================================
DO $$
DECLARE t record;
BEGIN
IF NOT EXISTS (SELECT 1 FROM pg_roles WHERE rolname = 'crm_supplier_worker') THEN
RAISE NOTICE 'Роли crm_* отсутствуют — srv_bypass пропущен (это dev/self-managed; запускать на управляемом кластере после 00_create_roles.sql).';
RETURN;
END IF;
FOR t IN SELECT tablename FROM pg_tables WHERE schemaname = 'public' AND rowsecurity LOOP
EXECUTE format('DROP POLICY IF EXISTS srv_bypass ON public.%I;', t.tablename);
EXECUTE format(
'CREATE POLICY srv_bypass ON public.%I AS PERMISSIVE FOR ALL
TO crm_admin_user, crm_migrator, crm_supplier_worker
USING (true) WITH CHECK (true);', t.tablename);
END LOOP;
END $$;
-- Контроль: число созданных srv_bypass-политик (ожидается == числу RLS-таблиц, ~44).
SELECT count(*) AS srv_bypass_policies FROM pg_policies WHERE policyname = 'srv_bypass';