Estou usando o AGI para gerar Postgres SQL (AWS RDS Postgres), mas quero evitar que os usuários façam perguntas sobre tabelas subjacentes, como "Mostrar todos os bancos de dados", "Mostrar todos os usuários", que resultam em consultas como SELECT * FROM pg_database
e SELECT * FROM pg_roles
.
O script de trabalho que tenho para isso é:
Conectar postgres
como postgres
(superusuário):
CREATE ROLE client_creator WITH LOGIN PASSWORD '<generate>' CREATEDB CREATEROLE;
Conecte-se postgres
como client_creator
:
CREATE DATABASE "client_db";
CREATE ROLE "client_reader" WITH LOGIN PASSWORD '<generate>';
Conecte-se client_db
comoclient_creator
GRANT CONNECT, TEMPORARY ON DATABASE "client_db" TO "client_reader";
GRANT SELECT ON ALL TABLES IN SCHEMA public TO "client_reader";
GRANT USAGE ON SCHEMA public TO "client_reader";
ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO "client_reader";
REVOKE ALL PRIVILEGES ON SCHEMA pg_catalog FROM client_reader;
REVOKE ALL PRIVILEGES ON SCHEMA pg_catalog FROM public;
O problema é que os dois últimos REVOKE
comandos parecem não ter efeito, pois ainda consigo executar SELECT * FROM pg_roles
e receber todas as linhas.
Também tentei revogar SELECT
tabelas pg_catalog
.
A questão é:
- Posso fazer isso?
- Devo fazer isso? Pensamentos...
- Vi comentários em outras postagens que sugerem que isso é uma má ideia, mas como entendi que cada banco de dados tem uma cópia do pg_catalog, pensei que não seria um problema.
- Acredito que as consultas geradas não devem depender de objetos pg_catalog, mas posso estar errado
Você deve ser um superusuário para mexer com os privilégios no esquema do sistema
pg_catalog
; um usuário normal não conseguirá fazer isso. Remover oUSAGE
privilégio no esquemapg_catalog
restringiráPUBLIC
o acesso para usuários normais, mas não para superusuários, que estão isentos de restrições de privilégios.Fazer isso é uma má ideia, porque quebrará todos os clientes interativos e pode causar outros problemas piores. Metadados são públicos no PostgreSQL, e você não deve tentar mudar isso (veja as muitas outras perguntas sobre esse tópico). A única maneira razoável de impedir que um usuário veja metadados de outros é colocá-los em bancos de dados diferentes, já que cada banco de dados tem suas próprias tabelas de catálogo.