Deriva a propriedade no servidor
Um ID de registo identifica algo; não prova quem o pode ler. O supastack delimita os registos de utilizador por workspaceId. O servidor resolve o workspace do utilizador autenticado e inclui esse limite ao ler ou modificar um registo.
Não trates um ID de workspace enviado pelo browser como prova de propriedade. O browser pode pedir uma ação, mas o contexto de servidor de confiança deve estabelecer de quem ela é. Esta regra deve valer para estado de tarefa, configuração de fornecedor guardada, registos de utilização e cada recurso próprio do produto. Layouts e componentes podem filtrar o que é renderizado, mas renderizar não é autorização — a verificação pertence ao lugar onde o registo é realmente lido ou escrito.
Tudo o resto neste post segue dessa regra: a propriedade é derivada, nunca pedida. No momento em que um workspaceId enviado pelo cliente é confiado em algum lugar, todas as outras verificações passam a decoração. O post de autenticação cobre como a própria sessão é estabelecida a montante desta fronteira.
Ser membro faz parte da fronteira
A delimitação responde a que workspace pertence um registo; a condição de membro responde se este utilizador pertence a esse workspace. Resolve ambas no servidor. O supastack modela workspaces pessoais e de organização com papéis de owner, admin e member — o guia de workspaces documenta o modelo.
Os papéis acrescentam um segundo eixo: um membro pode ler o que só um admin pode mudar. Mantém as duas verificações distintas — «pertence a este workspace» e «pode executar esta ação» — para que uma despromoção ou remoção faça efeito na mesma fronteira que todo o resto. Convites e remoções fazem parte do mesmo ciclo de vida, não são uma reflexão tardia de admin.
As mudanças de membros também têm de fazer efeito de imediato. O pedido seguinte de um membro removido deve falhar na fronteira, não quando um token em cache expirar por acaso — mais uma razão para a verificação viver onde os registos são lidos, em vez de dentro de uma credencial emitida antes.
Torna a recuperação útil sem conceder acesso
Um URL de tarefa permite a um utilizador regressar após um refresh. É útil precisamente porque conserva uma referência ao trabalho. A API autenticada deve continuar a verificar que a tarefa pedida pertence ao workspace atual antes de devolver estado ou resultados.
O mesmo princípio aplica-se à recuperação de submissões. Uma chave de idempotência ajuda a identificar um pedido repetido e a evitar trabalho duplicado. Não é uma sessão nem um token de acesso. Tentar novamente uma submissão guardada continua a exigir autenticação, propriedade do workspace e a permissão apropriada.
Os caminhos de conveniência são onde o isolamento se erosiona em silêncio. Um link que ajuda um utilizador legítimo a retomar trabalho — depois de um refresh, a partir de um email de conclusão — tem de passar pela mesma verificação autenticada que qualquer outro pedido. O pipeline pedido-a-resultado usa chaves de idempotência delimitadas à tarefa exatamente por este princípio.
Testa os pedidos que devem falhar
Um teste que deixa um proprietário obter um registo prova o caminho feliz. Não prova o isolamento. Combina-o com um segundo workspace a pedir o mesmo registo, um pedido anónimo e uma escrita que tente substituir outro proprietário.
Afirma o comportamento externo tanto como o resultado persistido. Um pedido rejeitado não deve mutar os dados de outro workspace, e uma resposta de erro não deve expor segredos nem detalhes crus da base. Estas verificações mantêm a fronteira revista quando a implementação muda.
- Um segundo workspace pede o mesmo ID de registo — rejeitado.
- Um pedido anónimo atinge o mesmo endpoint — rejeitado.
- Um membro removido do workspace tenta de novo — rejeitado.
- Uma escrita nomeia outro dono ou workspace — rejeitada, sem nada mutado.
- As respostas de erro mantêm-se genéricas — sem segredos, sem detalhes de schema.
Leva a regra para o teu produto
Quando adicionares uma nova tabela de produto, decide a sua propriedade antes de construir o ecrã. Inclui workspaceId no seu modelo de persistência, resolve o workspace através da fronteira de servidor existente e usa esse contexto tanto em operações de lista como de detalhe.
Os workers em segundo plano exigem o mesmo cuidado. Uma tarefa em fila deve carregar contexto de confiança suficiente para carregar o registo correto, enquanto as credenciais de fornecedor ficam no servidor. Uma regra de propriedade consistente é mais fácil de manter do que uma coleção de exceções por rota.
A superfície de API pertence à mesma fronteira. As chaves de API de workspace e os webhooks de saída assinados transportam consigo o âmbito do workspace — uma chave nunca pode tornar-se uma forma de ler entre tenants, e um payload de webhook nunca pode carregar os registos de um vizinho. O guia do módulo de API cobre a forma dessa superfície.
Perguntas frequentes sobre isolamento de workspaces
O isolamento multi-tenant levanta o mesmo punhado de perguntas em cada projeto. Estas são as que vale a pena resolver cedo.
- A delimitação ao nível da aplicação chega, ou preciso de row-level security? — A delimitação aplicada pelo servidor em cada leitura e escrita cobre o modelo de ameaças da maioria dos SaaS. O RLS da base de dados acrescenta defesa em profundidade, mas não substitui as verificações de fronteira — workers e chaves de API continuam a precisar da mesma regra.
- Como deve funcionar a partilha entre workspaces? — Modela-a explicitamente — um convite, uma linha de membro — em vez de enfraquecer o âmbito. «Qualquer pessoa com o link» deve ser uma funcionalidade desenhada com as suas próprias verificações, não um acidente.
- O que parte primeiro em apps multi-tenant? — Os caminhos de conveniência: links de recuperação, ferramentas de admin, workers em segundo plano que carregam registos por ID simples. Audita cada caminho de código que toca num registo sem passar pelo âmbito normal.
- Como adiciono delimitação a uma tabela existente? — Adiciona
workspaceId, preenche-o retroativamente, aplica-o em leituras e escritas, depois toca na UI. Lança primeiro os testes negativos para que a fronteira fique provada em vez de assumida. - As ações de servidor precisam de verificações se a página estiver protegida? — Sim. As guardas de página escondem ecrãs; não autorizam operações. Cada ação resolve a sessão e o workspace independentemente.