Multi-tenant
Toda query no banco e tenant-scoped por municipioId. Violar isso e considerado bug critico de seguranca (LGPD + responsabilidade contratual).
Como funciona
- TenantMiddleware valida JWT, extrai
municipioIde abreTenantContext.run(...). - AsyncLocalStorage propaga o contexto em toda chain async.
- GovonPrismaService.db lanca
ForbiddenErrorse nao houver tenant ativo. - scopedWhere/scopedData injetam
municipioIde rejeitam divergencia entre header/body e contexto.
Uso em Service
import { scopedWhere } from '@govon/data';
async listar() {
return this.prisma.db.usuario.findMany({
where: scopedWhere({ ativo: true }),
});
}
// Tentativa de cross-tenant joga:
this.prisma.db.usuario.findMany({
where: scopedWhere({ municipioId: 'outro-municipio' })
});
// Error: cross-tenantVetores de ataque cobertos
- Header
?municipioId=Xignorado em prod (so JWT vale) - Body com
municipioIddivergente:scopedDatarejeita - switch-tenant para municipio sem vinculo: 403
AUTH_NO_TENANT_ACCESS - AuditLog le
municipioIddoTenantContext, nunca do header
Ver politica completa em docs/MULTI_TENANT_POLICY.md.