-- ============================================================================= -- 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= port=6432 sslmode=verify-full ..." -U -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';