Pular para conteúdo

0013 — GRANT SELECT ao powersync_role

Status: Aprovado · Responsável: Gustavo Madruga · Atualizado em: 2026-07-06 · Decidido em: 2026-05-26

Contexto

O powersync_role (user que o PowerSync usa para replicar) lê as tabelas com SELECT. Mas tabelas criadas pelo user das migrations (user_onpetro) nascem sem GRANT para ele — Postgres não propaga GRANT automático entre roles. Sintoma se esquecer: a replicação para com permission denied for table (42501), o cliente Flutter trava no sync e o nuke morre em SNAPSHOT_PRE (o PowerSync não consegue subir um sync_rules ACTIVE no Mongo).

Decisão

A migration V13 aplicou ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT SELECT ON TABLES TO powersync_role rodando como user_onpetro — assim toda tabela futura em public herda o GRANT. Como cinto de segurança, cada migration que cria uma tabela bi_* nova adiciona, logo após o CREATE TABLE, um GRANT SELECT … TO powersync_role explícito guardado por um bloco DO que checa pg_roles (no-op se o role não existir ou se o default já cobriu).

Consequências

  • Tabelas bi_* novas herdam o SELECT sem intervenção manual — mas "confia desconfiando": conferir \dp <tabela> (deve mostrar powersync_role=r) antes de redeployar o PowerSync com a tabela nova no sync_rules.yaml.
  • Fix manual em prod se aparecer 42501 mesmo assim: GRANT SELECT ON <tabela> TO powersync_role + ajustar a migration retroativa.
  • Tabelas xls_* não precisam (não sincronizam), mas ganham o GRANT sem custo — a publicação powersync no PG filtra o que entra no WAL, não o GRANT.

Alternativas consideradas

  • GRANT manual a cada tabela: fácil esquecer → 42501 em produção e nuke travado. O default privileges + cinto reduz o risco (o cinto vira a defesa). Parcialmente descartado.
  • Rodar migrations como superuser: quebraria o isolamento de privilégios do banco. Descartado.