Duas fechaduras — e o buraco que o PostgreSQL reserva ao dono

O PostgreSQL deixa o DONO de uma tabela contornar as próprias políticas de RLS — salvo com FORCE ROW LEVEL SECURITY. E nada trava um SUPERUSER. Por isso o isolamento são 2 fechaduras, não 1.

Two locks, and the hole PostgreSQL reserves for the owner

The €100 Lakehouse — 7/12

O PostgreSQL deixa o DONO de uma tabela contornar as próprias políticas de RLS — salvo com FORCE ROW LEVEL SECURITY. E nada trava um SUPERUSER. Por isso o isolamento são 2 fechaduras, não 1.

Regra dura desde o dia zero: o tenant_id nasce na origem, nunca vem do cliente. Claim SSO → Superset RLS (fechadura 1) → RLS nativa do Postgres (fechadura 2). Se a aplicação for comprometida, o Postgres recusa na mesma linhas de outro tenant.

Cada fechadura assertada por um teste, não por diagrama:

→ o role de serving não possui nada nem é membro de nada — pg_has_role assertado falso
→ nenhum dos 4 roles do mart tem rolsuper ou rolbypassrls — assertado nos 4
→ o publisher nem pode fazer DELETE ou TRUNCATE no mart

Bónus medido: o PUBLIC tinha CONNECT em todas as bases do RDS partilhado. Revogado na nossa via migração, assertado por pgTAP. Revogar na base da plataforma? Ficou como platform-ask — nunca executado do nosso lado.

Exceção honesta, escrita: o master do RDS pode ler tudo. Break-glass da instância, nunca caminho de serving, não nosso para mudar.

Defesa em profundidade só é real quando cada fechadura é assertada por um teste — incluindo a lista do que ela NÃO consegue fechar.

Daí o tenant #2 ser clone de template, não build: isolamento estrutural, não processual.

No teu setup multi-tenant: se a camada aplicacional cair, qual é a segunda fechadura — e algum teste já a provou?

Databricks · dbt · Airflow · Terraform · AWS

P.S. Novo post tech todas as quartas-feiras.

#100EuroLakehouse #PostgreSQL #MultiTenant

Comentários