RLS
Isolamento por workspace com Row Level Security
Row Level Security (RLS) garante que cada workspace só acesse seus próprios dados. É a única camada de isolamento multi-tenant — o frontend não filtra por workspace_id por confiança, ele filtra porque o banco também filtra.
Como funciona
Todas as tabelas com dados de negócio possuem:
- Uma coluna
workspace_id - Policies RLS que verificam se o usuário pertence ao workspace
get_user_workspace_ids()
Função SQL central que retorna os IDs de workspaces aos quais o usuário autenticado pertence:
CREATE FUNCTION get_user_workspace_ids()
RETURNS SETOF uuid AS $$
SELECT workspace_id
FROM members
WHERE user_id = auth.uid()
AND is_active = true
$$ LANGUAGE sql SECURITY DEFINER STABLE;Padrão de policy
Todas as tabelas seguem o mesmo padrão:
CREATE POLICY "workspace_isolation" ON deals
FOR ALL
USING (workspace_id IN (SELECT get_user_workspace_ids()));Isso garante que:
SELECT— Usuários só veem dados do seu workspaceINSERT— Só podem inserir com workspace_id válidoUPDATE— Só podem alterar dados do seu workspaceDELETE— Só podem excluir dados do seu workspace
Multi-tenancy
O modelo multi-tenant usa workspaces como unidade de isolamento:
- Um usuário pode pertencer a múltiplos workspaces via
members - Cada workspace tem seus próprios dados isolados
- A troca de workspace no frontend muda o
workspace_idusado nos hooks
Super Admin bypass
Usuários cadastrados na tabela super_admins têm uma policy separada que permite acesso a qualquer workspace. A verificação acontece via função is_super_admin() chamada dentro das policies:
CREATE POLICY "super_admin_access" ON deals
FOR ALL
USING (is_super_admin());No client, o super admin entra em modo de impersonação soft (workspaceStore.enterAsAdmin) e enxerga o workspace alvo como se fosse membro — mas o members real não ganha um registro fantasma. O acesso é puramente via policy.
Nunca bypass RLS no código da aplicação. O bypass é sempre via policy no banco. Se você precisa de acesso elevado em um fluxo específico, ou o usuário é super admin (e a policy resolve), ou o fluxo deve rodar em uma edge function com service_role.
O RLS é a camada de segurança no banco. Mesmo que o frontend envie dados incorretos, o banco rejeita operações fora do workspace.
Toda nova tabela deve ter RLS habilitado (ALTER TABLE ... ENABLE ROW LEVEL SECURITY) e ao menos uma policy de workspace isolation antes de ir para produção. Tabela sem RLS em prod é vazamento garantido.