Montar uma hierarquia de roles com privilégio mínimo (GRANT + ALTER DEFAULT PRIVILEGES)
PostgreSQLSegurançaComando
-- Group roles (NOLOGIN): object owner, read-only, read-write
CREATE ROLE app_owner NOLOGIN;
CREATE ROLE app_readonly NOLOGIN;
CREATE ROLE app_readwrite NOLOGIN;
GRANT app_readonly TO app_readwrite;
CREATE SCHEMA app AUTHORIZATION app_owner;
-- Restrict PUBLIC's default privileges
REVOKE ALL ON DATABASE mydb FROM PUBLIC;
REVOKE CREATE ON SCHEMA public FROM PUBLIC;
-- Existing objects
GRANT CONNECT ON DATABASE mydb TO app_readonly;
GRANT USAGE ON SCHEMA app TO app_readonly;
GRANT SELECT ON ALL TABLES IN SCHEMA app TO app_readonly;
GRANT INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA app TO app_readwrite;
GRANT USAGE, SELECT ON ALL SEQUENCES IN SCHEMA app TO app_readwrite;
-- Objects app_owner will create IN THE FUTURE
ALTER DEFAULT PRIVILEGES FOR ROLE app_owner IN SCHEMA app GRANT SELECT ON TABLES TO app_readonly;
ALTER DEFAULT PRIVILEGES FOR ROLE app_owner IN SCHEMA app GRANT INSERT, UPDATE, DELETE ON TABLES TO app_readwrite;
ALTER DEFAULT PRIVILEGES FOR ROLE app_owner IN SCHEMA app GRANT USAGE, SELECT ON SEQUENCES TO app_readwrite;
-- Login users get privileges only through group membership
CREATE ROLE web_app LOGIN PASSWORD 'Change#2026' IN ROLE app_readwrite;
CREATE ROLE report_app LOGIN PASSWORD 'Change#2026' IN ROLE app_readonly;
-- Configured default privileges (psql: \ddp)
SELECT pg_get_userbyid(d.defaclrole) AS owner_role,
n.nspname AS schema_name,
d.defaclobjtype AS object_type,
d.defaclacl
FROM pg_default_acl d
LEFT JOIN pg_namespace n ON n.oid = d.defaclnamespace
ORDER BY 1, 2, 3;O que faz
Monta uma hierarquia de roles de grupo owner, somente leitura e leitura/escrita; concede os privilégios certos em tabelas/sequences existentes e futuras e autoriza os usuários da aplicação apenas por meio de associação a grupos.
Quando usar
Ao configurar um novo schema de aplicação, corrigir aplicações que conectam como superusuário ou dono das tabelas e simplificar privilégios antes de uma auditoria.
Atenção
ALTER DEFAULT PRIVILEGES só se aplica a objetos criados DEPOIS pela role indicada em FOR ROLE; se a ferramenta de migração criar tabelas como outro usuário, os privilégios não são aplicados, então execute o DDL com SET ROLE app_owner. GRANT ... ON ALL TABLES cobre apenas os objetos que existem naquele momento. Bancos criados no PG15+ já não concedem CREATE no schema public a PUBLIC; bancos atualizados de versões antigas precisam do REVOKE. REVOKE ALL ON DATABASE ... FROM PUBLIC também remove CONNECT e TEMP; conceda-os separadamente às outras roles que precisam deles. Use psql \password em vez de colocar senhas na linha de comando (elas ficam fora de logs e do histórico).