SET ROLE dbo; DROP SCHEMA IF EXISTS vmreports CASCADE; CREATE SCHEMA IF NOT EXISTS vmreports AUTHORIZATION dbo; GRANT USAGE ON SCHEMA vmreports TO appserver; ALTER DEFAULT PRIVILEGES FOR ROLE dbo IN SCHEMA vmreports GRANT SELECT ON TABLES TO appserver; ALTER DEFAULT PRIVILEGES FOR ROLE dbo IN SCHEMA vmreports GRANT USAGE ON SEQUENCES TO appserver; GRANT USAGE ON SCHEMA vmreports TO nifi,analytics,analyst; ALTER DEFAULT PRIVILEGES FOR ROLE dbo IN SCHEMA vmreports GRANT SELECT ON TABLES TO nifi,analytics,analyst; ALTER DEFAULT PRIVILEGES FOR ROLE dbo IN SCHEMA vmreports GRANT USAGE ON SEQUENCES TO nifi,analytics,analyst; /* конструкция осложняется тем, что нужен один пользователь-владелец и второй читатель Это вызывает множество телодвижений при создании. Необходимость указывать пароль при локальном коннекте не очень радует (ведь пользователь локальный, прописан на этом же сервере) */ --DROP FOREIGN TABLE IF EXISTS host; --CREATE FOREIGN TABLE vmreports.host () SERVER billing OPTIONS (schema_name 'vmreports', table_name 'host'); -- вместо этого лучше импортировать схему DROP SERVER IF EXISTS billing CASCADE; CREATE SERVER billing FOREIGN DATA WRAPPER postgres_fdw OPTIONS (host 'localhost', port '5432', dbname 'billing', updatable 'false'); -- для импорта схемы мы создаем маппинг владельцу DROP USER MAPPING IF EXISTS FOR PUBLIC SERVER billing; CREATE USER MAPPING FOR PUBLIC SERVER billing OPTIONS (user 'appserver', password '***'); IMPORT FOREIGN SCHEMA vmreports FROM SERVER billing INTO vmreports; --GRANT SELECT ON vmreports.host to appserver; --DROP USER MAPPING IF EXISTS FOR dbo SERVER billing; -- мы импортировали схему, маппинг больше не нужен. -- Но нам все равно пришлось указать пароль дважды --DROP USER MAPPING IF EXISTS FOR appserver SERVER billing; --CREATE USER MAPPING FOR appserver SERVER billing OPTIONS (user 'nifi', password '***'); --проверка --set role appserver; select * from vmreports.host; -- это если интересно, не разрешен ли локальный коннект --SELECT * FROM pg_hba_file_rules; /* Довольно тонкий нюанс, легко ускользающий ALTER DEFAULT PRIVILEGES FOR ROLE target_creator_role IN SCHEMA schema_name GRANT privilege_type ON TABLES TO recipient_role; Recommended Strategy for "Any User"Because there is no "FOR ALL ROLES" option, the best practice is to have all users create objects as a shared group role.Create a group role (e.g., schema_owner_role).Grant that role to all relevant users.Instruct users to run SET ROLE schema_owner_role; before creating objects.Run ALTER DEFAULT PRIVILEGES FOR ROLE schema_owner_role ... once to cover all objects created under that role. */ /* Best Practices for Role Owners:Dedicated Schema Owner: Create a dedicated, non-login role for managing database schema objects (DDL) and make it the owner of the database/schemas.Separation of Duties: Separate the application user (DML - SELECT, INSERT, UPDATE) from the owner role (DDL - CREATE, ALTER, DROP).Use ALTER DEFAULT PRIVILEGES: Set up default privileges for new objects to ensure that user roles automatically gain access to new tables or functions created by the owner role.Leverage Role Hierarchy: Create group roles (e.g., app_reader, app_writer) and grant these to individual user roles for easier permission management.Avoid Public Schema: Create specific schemas and revoke CREATE privileges on the public schema to prevent accidental object creation.Secure SUPERUSER Usage: Only use the default postgres superuser role for initial setup and critical administrative tasks. Never use it for applications.Example Implementation:sql-- Create a schema owner CREATE ROLE ddl_user NOLOGIN; -- Create an app user CREATE ROLE dml_user LOGIN PASSWORD 'secure_password'; -- Assign ownership ALTER DATABASE mydb OWNER TO ddl_user; ALTER SCHEMA public OWNER TO ddl_user; -- Grant future access ALTER DEFAULT PRIVILEGES FOR ROLE ddl_user IN SCHEMA public GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO dml_user; */