Isolamento de tenants é uma disciplina de muros dentro de sistemas compartilhados — controles que mantêm cada tenant selado em relação a todos os outros. O ponto que a maioria das explicações enterra merece o primeiro parágrafo: isolamento não é autenticação nem autorização. Um usuário perfeitamente logado, com o papel correto, ainda pode ler os dados de um concorrente se nada der escopo à consulta — isolamento é a terceira camada, a que decide em qual universo cada operação acontece.
Principais pontos
| Pergunta | Resposta |
|---|---|
| O que é | As garantias de que nenhum tenant alcança os dados ou recursos de outro |
| Não confundir com | Autenticação (quem) e autorização (o quê) — isolamento é de quem |
| Onde os muros ficam | Linhas do banco, caches, filas, storage, tokens — toda camada compartilhada |
| O modo de falha | Uma consulta, job ou chave de cache sem escopo = vazamento entre tenants |
| O padrão de mercado | Aplique na camada de dados; teste adversarialmente; nunca confie em IDs de tenant vindos do cliente |
O bug, e o muro que sobrevive a ele
-- O bug que o isolamento existe para sobreviver: uma consulta que esqueceu o tenant
SELECT * FROM invoices WHERE id = $1; -- retorna a fatura de qualquer um
-- Com o muro na camada de dados, o mesmo bug retorna nada:
ALTER TABLE invoices ENABLE ROW LEVEL SECURITY;
CREATE POLICY tenant_wall ON invoices
USING (tenant_id = current_setting('app.tenant')::uuid);
Em bancos de documentos o muro é construído com papéis e controle de acesso por objeto — o tenant é um papel, e toda linha é selada a ele no momento da escrita:
// JavaScript / Node.js — Back4app JS SDK
// Provisioning a tenant boundary: a role is the tenant, membership is access
const tenantRole = new Parse.Role('tenant-acme', new Parse.ACL());
tenantRole.getUsers().add(adminUser);
await tenantRole.save();
// Every acme row from now on: readable and writable by the role only
const doc = new Parse.Object('Project', { name: 'Q3 Launch' });
const acl = new Parse.ACL();
acl.setRoleReadAccess('tenant-acme', true);
acl.setRoleWriteAccess('tenant-acme', true);
doc.setACL(acl);
await doc.save(); // Flutter / Dart — Back4app Flutter SDK
// Every tenant row: readable and writable by the tenant role only
final acl = ParseACL();
acl.setRoleReadAccess('tenant-acme', true);
acl.setRoleWriteAccess('tenant-acme', true);
final doc = ParseObject('Project')
..set('name', 'Q3 Launch')
..setACL(acl);
await doc.save(); // invisible to every other tenant, enforced server-side // iOS / Swift — Back4app Swift SDK
// Every tenant row: readable and writable by the tenant role only
var acl = ParseACL()
acl.setReadAccess(roleName: "tenant-acme", value: true)
acl.setWriteAccess(roleName: "tenant-acme", value: true)
var doc = Project()
doc.name = "Q3 Launch"
doc.ACL = acl
doc.save { _ in } // invisible to every other tenant, enforced server-side // Android / Kotlin — Back4app Android SDK
// Every tenant row: readable and writable by the tenant role only
val acl = ParseACL().apply {
setRoleReadAccess("tenant-acme", true)
setRoleWriteAccess("tenant-acme", true)
}
val doc = ParseObject("Project").apply {
put("name", "Q3 Launch")
setACL(acl)
}
doc.saveInBackground() // invisible to every other tenant, enforced server-side A pilha de enforcement
Cada camada captura o que a de cima deixa cair: o token estabelece a identidade do tenant no servidor, o código da aplicação dá escopo por hábito, a camada de dados aplica por política e a infraestrutura coloca namespace em todo o resto que é compartilhado. O cheat sheet da OWASP é o checklist canônico da pilha completa.
Isolamento vs. autenticação vs. autorização
| Pergunta respondida | Mecanismo | A falha parece com |
|---|---|---|
| Quem é você? (autenticação) | Login, sessões, tokens | Um impostor entra |
| O que você pode fazer? (autorização) | Papéis, permissões | Um usuário excede seu papel |
| De quem são estes dados? (isolamento) | Escopo de tenant + muros na camada de dados | Um usuário válido lê outro tenant |
A terceira linha é a que produz manchetes, porque ela passa em todos os testes que as duas primeiras definem: o atacante loga legitimamente, usa operações permitidas — e atravessa um muro que não existe. As vulnerabilidades entre tenants canônicas da era da nuvem (a classe ChaosDB de descobertas de pesquisa, em que um tenant conseguia derivar acesso aos bancos de outros) foram todas falhas de terceira linha em sistemas com primeira e segunda linhas impecáveis.
De onde os vazamentos realmente vêm
- O filtro esquecido — uma consulta sem o escopo de tenant; a razão de os muros pertencerem à camada de dados, não à memória do desenvolvedor.
- IDOR — IDs sequenciais ou adivinháveis buscados sem verificação de tenant; troque um ID, leia o registro de um estranho.
- Execução fora de contexto — jobs em segundo plano, webhooks, tarefas agendadas e exports de dados rodando com credenciais amplas e sem contexto de tenant.
- Serviços compartilhados sem escopo — chaves de cache, índices de busca e caminhos de arquivo sem o prefixo do tenant; o muro do banco fica de pé enquanto o cache vaza.
- Pipelines paralelos — analytics e relatórios lendo o banco diretamente, por baixo de toda verificação da aplicação.
- Tenant confiado ao cliente — um ID de tenant aceito do corpo da requisição em vez de derivado da sessão; o jeito mais educado possível de entregar os dados dos outros tenants.
Isolamento de segurança vs. vizinhos barulhentos
Mesma palavra, dois problemas. Isolamento de segurança mantém o tenant A fora dos dados do tenant B. Isolamento de performance — o problema do vizinho barulhento (noisy neighbor) — mantém o import em massa do tenant A fora da latência de checkout do tenant B, e se resolve com cotas, rate limits e particionamento, coberto no lado de arquitetura deste tema. Um sistema pode ser estanque e ainda deixar um tenant sufocar o resto; orce para os dois, e não deixe uma discussão de cotas se passar por revisão de segurança.
Como testar o isolamento de tenants
A varredura adversarial de dois tenants, automatizada no CI: crie os tenants A e B e tente todo cruzamento — os IDs de objetos de B pela sessão de A em todo endpoint (a varredura de IDOR), o token de A contra os recursos de B, as superfícies fora do caminho principal (exports, painéis de admin, jobs) com o contexto de cada tenant, e uma inspeção de chaves de cache, URLs de arquivos e resultados de busca à procura de escopo de tenant faltando. Adicione o caso do contexto não definido: nenhum tenant na sessão deveria significar nenhuma linha, nunca todas. Isolamento que não foi atacado no CI é uma hipótese com certificado de compliance.
Casos de uso comuns
- SaaS B2B. Todo workspace é um tenant; isolamento é a promessa de produto por baixo de cada feature.
- Plataformas que hospedam apps de clientes. Duas altitudes ao mesmo tempo — a plataforma isola apps uns dos outros, cada app isola os próprios tenants.
- Tiers enterprise e regulados. Exigências contratuais de isolamento mapeadas para muros mais fortes — chaves por tenant, recursos dedicados — para as contas que precisam delas.
- Agências e produtos white-label. Um deploy, muitas organizações clientes, cada uma selada.
- Plataformas internas multi-time. Departamentos como tenants; modelo de ameaça mais amigável, mecânica idêntica.
Quanto isolamento? Matriz de decisão
| Pool + muros na camada de dados quando… | Separação mais forte quando… |
|---|---|
| Muitos tenants pequenos, sensibilidade padrão | Contratos nomeiam requisitos de isolamento |
| O custo por tenant precisa ficar perto de zero | Os dados de um tenant exigem chaves ou região próprias |
| Os muros são aplicados (RLS/ACLs) e testados | Argumentos de raio de explosão vencem a economia de densidade |
| Um ciclo de update deve cobrir todo mundo | Restore por tenant é feature prometida |
| O time consegue manter testes adversariais | Auditores querem fronteiras que possam apontar |
O enquadramento honesto: pool com muros aplicados e testados é isolamento legítimo — a maior parte da indústria roda assim. Suba tenants individuais na escada de separação quando os requisitos deles, e não a moda, exigirem.
Limitações e trade-offs
- Isolamento é transversal para sempre. Toda feature nova — cache, fila, export, busca — refaz a pergunta do tenant; a disciplina nunca termina.
- Muros na camada de dados têm letras miúdas operacionais. Contexto de sessão vs. connection pooling, roles que fazem bypass de política e modos de dump — o verbete de segurança em nível de linha cataloga tudo.
- O raio de explosão compartilhado sobrevive à correção. Isolamento lógico perfeito ainda compartilha domínios de falha — um deploy ruim toca todos os tenants; só separação física muda isso.
- Testar é o custo fora do orçamento. A suíte de dois tenants é engenharia de verdade; pular essa etapa converte “aplicado” de volta em “presumido”.
- Muros mais fortes custam densidade. Chaves por tenant, silos e recursos dedicados trocam exatamente a economia que tornou o compartilhamento atraente — gaste-os nos tenants que precisam.
Isolamento de tenants no Back4app
O Back4app é uma plataforma open-source de Backend as a Service (BaaS) que combina banco de dados gerenciado, APIs REST e GraphQL geradas automaticamente, autenticação, armazenamento de arquivos e funções serverless com Cloud Code. O isolamento nasce na camada de dados por construção: papéis definem o tenant, a ACL de cada objeto o sela a esse papel e permissões em nível de classe controlam o schema — aplicado server-side em todo caminho, SDKs, REST, GraphQL e dashboard igualmente, então o bug do filtro esquecido não tem o que esquecer. A própria plataforma aplica a mesma disciplina um nível acima, isolando o backend de cada app de todos os outros — e o mergulho de engenharia em segurança em nível de linha mostra o padrão completo na prática.
Perguntas frequentes
O que é isolamento de tenants?
O conjunto de controles arquiteturais que impede que um tenant de um sistema compartilhado alcance os dados ou recursos de outro — os muros entre apartamentos de um mesmo prédio. Ele atravessa toda camada compartilhada: linhas do banco, caches, filas, armazenamento de arquivos e computação, cada uma precisando da própria fronteira com escopo no tenant atual.
Qual a diferença entre isolamento de tenants, autenticação e autorização?
Um usuário pode estar plenamente autenticado e corretamente autorizado para o seu papel — e ainda assim alcançar os dados de outro tenant se nada der escopo à consulta. Autenticação prova quem você é; autorização decide que ações você pode executar; isolamento garante em qual universo de tenant essas ações acontecem. É uma camada separada, e tratar login mais papéis como suficiente é a raiz da maioria dos bugs entre tenants.
O que causa vazamento de dados entre tenants?
Uma lista curta e estável: consultas sem o filtro de tenant; IDOR — IDs adivinháveis buscados sem escopo de tenant; jobs em segundo plano, webhooks e exports rodando fora do contexto do tenant; caches com chaves sem o tenant; pipelines de analytics e relatórios que contornam as verificações da aplicação; e confiar em um identificador de tenant enviado pelo cliente em vez de derivá-lo da sessão no servidor.
O problema do vizinho barulhento é o mesmo que isolamento de tenants?
São irmãos, não o mesmo problema. Isolamento de segurança impede que um tenant acesse os dados de outro; isolamento de performance — o problema do vizinho barulhento (noisy neighbor) — impede que a carga de um tenant degrade a experiência de todos os outros, e se resolve com cotas, throttling e particionamento. As discussões os confundem com frequência; um sistema pode ser perfeitamente seguro e ainda deixar um tenant sufocar o resto.
Qual modelo de isolamento os frameworks de compliance exigem?
Nenhum dos grandes frameworks manda uma arquitetura — eles são baseados em resultado, exigindo medidas apropriadas e demonstráveis. Separação física costuma ser exigência de clientes enterprise e de contratos, não de reguladores. O que as auditorias recompensam: regras aplicadas na camada de dados, fronteiras documentadas e evidência de que o isolamento é testado em vez de presumido.
Como a segurança em nível de linha aplica o isolamento de tenants?
Tornando a fronteira do tenant uma propriedade da tabela: políticas filtram toda consulta pelo contexto de tenant da sessão, então uma consulta que esquece o filtro retorna nada em vez de tudo. O equivalente em bancos de documentos é o controle de acesso por objeto — ACLs nomeando o papel do tenant — aplicado pela plataforma em toda requisição. Nos dois casos, o muro fica de pé mesmo quando o código da aplicação tropeça.
Como testar o isolamento de tenants?
Adversarialmente, com dois tenants: troque IDs de objetos entre eles em todo endpoint (a sonda de IDOR), use o token de um tenant contra os recursos do outro, exercite os caminhos que pulam o app principal — exports, painéis de admin, jobs em segundo plano — e inspecione chaves de cache e URLs de arquivos em busca de escopo de tenant faltando. Automatize os testes negativos no CI; isolamento não testado é uma hipótese.
Que camadas precisam de isolamento além do banco?
Tudo que é compartilhado: chaves de cache prefixadas pelo tenant, tópicos de fila e consumer groups com escopo por tenant, object storage sob prefixos por tenant com políticas de acesso correspondentes, chaves de criptografia por tenant onde os contratos exigem, e claims de tenant carregadas nos tokens e validadas em toda requisição. O muro do banco é necessário, nunca suficiente.