-- PANELS · Postgres · Fase 0 (esquemas y privilegios dentro de panels_product) -- -- Correr conectado A LA BASE panels_product, como superuser/admin: -- psql "$SUPERUSER_URL/panels_product" -f 04-product-database.sql -- -- Crea los esquemas iam/core, cada uno con su propio dueño (_owner, usado -- por Liquibase) y su propio rol de runtime (_app, solo DML). Se revoca -- explícitamente cualquier acceso cruzado entre iam y core: son dos -- módulos del monolito modular que NO deben poder leerse entre sí por SQL. REVOKE ALL ON SCHEMA public FROM PUBLIC; CREATE SCHEMA IF NOT EXISTS iam AUTHORIZATION panels_iam_owner; CREATE SCHEMA IF NOT EXISTS core AUTHORIZATION panels_core_owner; -- citext (comparación case-insensitive real para curp/rfc, reemplaza el -- COLLATE NOCASE de SQLite) se instala DENTRO del esquema core (no en -- public, que queda sin USAGE para nadie salvo el propio superuser) -- -- así el tipo es resoluble por panels_core_owner/panels_core_app con su -- search_path=core, sin tener que abrirles el esquema public. CREATE EXTENSION IF NOT EXISTS citext SCHEMA core; -- ===== iam ===== GRANT USAGE ON SCHEMA iam TO panels_iam_app; ALTER DEFAULT PRIVILEGES FOR ROLE panels_iam_owner IN SCHEMA iam GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO panels_iam_app; ALTER DEFAULT PRIVILEGES FOR ROLE panels_iam_owner IN SCHEMA iam GRANT USAGE, SELECT ON SEQUENCES TO panels_iam_app; GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA iam TO panels_iam_app; GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA iam TO panels_iam_app; ALTER ROLE panels_iam_owner IN DATABASE panels_product SET search_path = iam; ALTER ROLE panels_iam_app IN DATABASE panels_product SET search_path = iam; -- ===== core ===== GRANT USAGE ON SCHEMA core TO panels_core_app; ALTER DEFAULT PRIVILEGES FOR ROLE panels_core_owner IN SCHEMA core GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO panels_core_app; ALTER DEFAULT PRIVILEGES FOR ROLE panels_core_owner IN SCHEMA core GRANT USAGE, SELECT ON SEQUENCES TO panels_core_app; GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA core TO panels_core_app; GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA core TO panels_core_app; ALTER ROLE panels_core_owner IN DATABASE panels_product SET search_path = core; ALTER ROLE panels_core_app IN DATABASE panels_product SET search_path = core; -- ===== Aislamiento cruzado explícito (defensa en profundidad) ===== -- Nadie del lado "core" puede tocar "iam" y viceversa, ni por accidente. REVOKE ALL ON SCHEMA iam FROM panels_core_app, panels_core_owner, PUBLIC; REVOKE ALL ON SCHEMA core FROM panels_iam_app, panels_iam_owner, PUBLIC;