Melhores Práticas para Multi-Tenant
Teste vazamentos entre tenants em CI com casos negativos. A correção multi-tenant é uma propriedade de segurança - trate-a como autenticação, não como uma convenção de nomenclatura.
Como Usar Esta Lista
- Aplique a cada nova tabela e endpoint de API pertencente a um tenant.
- Execute testes negativos de tenant em CI em cada PR que toque no código de acesso a dados.
- Reavalie ao adicionar ferramentas de BI, consoles de suporte ou jobs em segundo plano.
- Escolha o nível de isolamento (compartilhado, schema, banco de dados) por contrato - documente no registro de tenants.
A - Modelo de Dados
- Coloque
tenant_idem cada linha pertencente a um tenant (schema compartilhado). Chaves primárias e estrangeiras compostas incluemtenant_id. - Use
UNIQUE (tenant_id, ...)em vez de UNIQUE global. Slugs e e-mails colidem entre tenants por design. - Indexe com
tenant_idcomo coluna principal. CorrespondaWHERE tenant_id = $1em todos os caminhos de acesso frequente. - Separe dados de referência globais de dados de tenant. Documente tabelas sem
tenant_idcomo intencionalmente globais. - Registre o slug do tenant, schema, banco de dados e nível no plano de controle. Fonte única para roteamento de conexão.
B - Aplicação
- Habilite
FORCE ROW LEVEL SECURITYem tabelas de tenant. Políticas em SELECT, INSERT, UPDATE, DELETE conforme necessário. - Defina
app.tenant_id(ou equivalente) a cada requisição. Nunca confie no tenant fornecido pelo cliente sem vinculação de autenticação. - Redefina o estado da sessão ao retirar do pool. PgBouncer
server_reset_query = DISCARD ALLou equivalente. - Proíba conexões de aplicativo com BYPASSRLS. Migrações usam role separada em pipeline controlado.
- Chaves estrangeiras compostas em links pai-filho. Evite joins de
document_idque cruzem tenants.
C - Testes e Operações
- Teste negativo em CI: tenant A não pode ler linhas do tenant B. Obrigatório por classe de tabela, não um teste de integração opcional.
- Alerta sobre anomalias de crescimento de linhas por tenant. Detecção de vizinho barulhento na plataforma de métricas.
- Runbook para exportação e exclusão por tenant. Solicitações GDPR/CCPA não devem exigir restauração completa do cluster.
- Automatize o provisionamento de schema/banco de dados de forma idempotente. Caminhos de inscrição e upgrade de nível testados em staging.
- Audite consultas de bypass de suporte e admin. Registre o contexto do tenant para roles de plataforma com acesso elevado.
D - Estratégia de Nível
- Nível SMB padrão: schema compartilhado + RLS. Menor custo operacional com filtros disciplinados.
- Nível Business: avalie schema por tenant quando os contratos exigirem. Limite a contagem de tenants com investimento em automação.
- Nível Enterprise: banco de dados ou instância por tenant quando for obrigatório. O preço reflete o multiplicador de operações.
- Não misture níveis sem roteamento explícito. String de conexão incorreta equivale a vazamento de dados.
- Revise os limites de nível anualmente. Conformidade e escala mudam os padrões aceitáveis.
FAQs
Qual é o teste mínimo de CI para multi-tenant?
Popule os tenants A e B, autentique como A, consulte cada endpoint/tabela, afirme que zero linhas de B foram retornadas. Falhe a build em qualquer vazamento.
RLS é suficiente sem filtros de aplicativo?
RLS é defesa em profundidade. Os aplicativos ainda devem filtrar - as políticas capturam erros, não substituem o design intencional da consulta.
Como testar vazamentos de pooling do PgBouncer?
Duas requisições sequenciais como tenants diferentes através do mesmo pool sem redefinição não devem ver dados cruzados - automatize em staging.
E sobre os workers em segundo plano?
Os workers devem definir o GUC do tenant por payload do job. Workers globais iteram sobre tenants explicitamente - nunca escaneiem a tabela completa sem filtro.
O tenant_id deve aparecer nos logs?
Sim para trilhas de auditoria; evite PII na mesma linha de log. Correlacione tenant_id com o ID da requisição para resposta a incidentes.
Como escolher o nível de isolamento?
Comece com schema compartilhado + RLS. Mova para schema/banco de dados quando os contratos, métricas de vizinho barulhento ou SLAs de restauração exigirem.
Qual é a principal causa de incidentes multi-tenant?
Falta de WHERE tenant_id em um método do repositório ou GUC obsoleto em uma conexão pooled.
Réplicas de leitura precisam de RLS?
Sim, se os aplicativos se conectarem com roles não superusuários. As políticas de réplica correspondem à primária - teste vazamentos na réplica em CI também.
Como as migrações evitam impacto entre tenants?
Schema compartilhado: um DDL afeta todos - teste no maior fixture de tenant. Schemas/DBs por tenant: paralelize com alertas de falha.
Posso pular o tenant_id em tabelas de auditoria?
Não - logs de auditoria são dados pertencentes ao tenant e precisam do mesmo isolamento e índices.
Relacionados
- Noções Básicas de Multi-Tenant - visão geral do padrão
- Tenancy com Row-Level Security - modelos de política
- Schema Compartilhado + tenant_id - detalhes de indexação
- Banco de Dados por Tenant - nível enterprise
Versões de Stack: Esta página foi escrita para PostgreSQL 18.4 (estável 18, manutenção 17), pgvector 0.8+, PgBouncer 1.x, Patroni 3.x e PostGIS 3.5+.