Pular para o conteúdo
Studeia Docs

Multi-tenancy e isolamento de dados

Arquitetura multi-tenant do Studeia: cada instituicao tem isolamento completo em nivel de banco com filtro por tenantId, RLS Supabase, per-tenant API keys, white-label total e SSO independente.

Por Equipe Studeia 2026-07-18 7 min
Resposta curta

Multi-tenancy na Studeia garante que os dados de cada instituição ficam totalmente isolados dos demais — requisito de privacidade (LGPD) e segurança para operar com confiança. Cada tenant tem a sua marca, a sua configuração de IA (pode usar as próprias chaves) e as suas API keys, com isolamento no nível do banco e RLS como rede de segurança. Na prática, a sua instituição opera como se a plataforma fosse só sua.

Modelo conceitual

Tenant (Instituicao)
  ├── Users (alunos, professores, coordenadores, admin institucional)
  ├── Courses → Modules → Lessons
  ├── ClassGroups (turmas)
  ├── MediaAssets (biblioteca de midia)
  ├── Automations
  ├── EmailTemplates
  ├── VideoProviderConfig (BBB/Zoom/Teams/Meet)
  ├── TenantApiKey (chaves proprias de IA)
  ├── TenantSubscription (billing)
  ├── ...todas as outras entidades

Usuarios sem tenantId sao B2C (plataforma direta). Usuarios com tenantId pertencem a uma instituicao.

Isolamento de dados — 3 camadas

Camada 1: Filtro obrigatorio em queries

Toda query Prisma em codigo de aplicacao filtra por tenantId:

const { tenantId } = requireTenant(user);
const courses = await prisma.course.findMany({
  where: { tenantId }, // OBRIGATORIO
});

requireTenant() em apps/web/lib/tenant.ts retorna NextResponse 403 se o usuario nao tem tenant. Sem essa chamada, e impossivel acessar dados B2B.

Camada 2: RLS no Supabase

Como safety net contra bugs, policies RLS no Supabase reforcam isolamento ate em queries diretas. Se um codigo esquecer o filtro tenantId, o banco recusa.

Camada 3: Auditoria de admin global

Quando um admin global precisa acessar dados de um tenant (suporte, debug), ele usa impersonacao via cookie HMAC com:

  • TTL fixo de 1h (nao prorrogavel)
  • Assinatura HMAC-SHA256 com IMPERSONATION_SECRET
  • Auditoria em AdminAuditLog (acao impersonate.start, IP, user-agent)
  • getUserProfile() retorna isImpersonating: true + overlay em memoria
  • Supabase auth NUNCA modificado (apenas overlay)
  • Banner sticky no /institution/ alerta o admin durante a sessao

O painel admin SaaS global inclui impersonacao para suporte.

Per-tenant API keys

Por padrao, todas as chamadas LLM usam chaves globais (ANTHROPIC_API_KEY, OPENAI_API_KEY, etc) do Studeia. Custos vao para o tenant via metering.

Mas instituicoes que ja tem contas Anthropic/OpenAI/Google podem usar proprias chaves (TenantApiKey, criptografada AES-256-GCM no banco):

  1. Custos vao DIRETO para a conta do tenant na Anthropic/OpenAI
  2. Studeia nao cobra margem de IA — apenas a assinatura mensal
  3. Resolucao automatica: TenantApiKeyProviderApiKey global → process.env (cascata em apps/web/lib/api-key-resolver.ts)

NUNCA seta process.env em runtime (conflitaria entre tenants) — passa a key via options do SDK.

White-label completo

Cada tenant pode personalizar:

AspectoComo
Logo, faviconUpload no settings
Cores (primary, accent, background)Editor com preview
Fonte (Google Fonts)Dropdown
Tema visual (de 9 opcoes)Toggle por usuario ou padrao do tenant
Custom CSSSanitizado, max 10KB
Dominio customizadoDNS CNAME + TXT _studeia-verify + TLS automatico Caddy (on-demand)
Logo no emailPor template
Sender email (SMTP/Resend/SendGrid)TenantEmailConfig
Esconder marca StudeiaSim (plano enterprise)

Roles e permissoes

RoleEscopoPode fazer
studentProprio progressoChat tutor, cursos, simulados, gamificacao
parentFilhos vinculadosVer progresso, alertas, relatorios
teacherProprias turmas/cursosCriar cursos, upload material, ver alunos das turmas
coordinatorTodas turmas do tenantGerenciar turmas, ver todos os alunos
pedagogueTodos alunos do tenantOrientacao educacional, relatorios
institution_adminTodo o tenantConfig IA, API keys, white-label, usuarios
adminGlobal (plataforma)Tudo + gerenciar tenants

Limites por plano

Limites enforceados via checkTenantResourceLimit(tenantId, resource) em apps/web/lib/plan-limits.ts:

PlanoAlunos maxProfessoresCursosIA
Demo111Haiku only, 10 msgs/dia
Mini10IlimitadoIlimitadoTodos providers
Crescimento50IlimitadoIlimitadoTodos providers
Escala100IlimitadoIlimitadoTodos providers
EnterpriseCustom (maxStudentsOverride)IlimitadoIlimitadoTodos providers

7 pontos de enforcement (todos auditados em 2026-04-11):

  1. POST /api/courses/[courseId]/enroll — self-enroll do aluno
  2. POST /api/institution/courses/[id]/clone — clone de curso
  3. POST /api/institution/courses/import — import IMS CC
  4. executeEnrollUser() em automacao
  5. POST /api/scim/v2/Users — provisionamento SCIM
  6. POST /api/institution/users — vincular usuario existente
  7. PATCH /api/institution/users/[id] — promover role

Como solicitar override enterprise

Tenants enterprise podem ter Tenant.maxStudentsOverride: Int? ajustado pelo admin global. Sem override (null), enterprise = ilimitado. Contato comercial via contact@studeia.com.

Limitacoes

  • Um User pertence a UM tenant. Para professores que atendem multiplas escolas, criar usuarios separados.
  • Compartilhamento de cursos entre tenants nao e nativo (cada tenant tem seu CMS isolado). Roadmap: marketplace de cursos com licenciamento.
  • Migracao de tenant para outro plano e instantanea, mas downgrade que viola limites atuais e bloqueado ate o tenant ajustar os recursos.

Veja tambem

FAQ

Dados de tenants estao realmente isolados?

Sim. Tres camadas: (1) toda query Prisma filtra por tenantId obrigatoriamente (regra critica 30 do projeto); (2) RLS policies no Supabase como safety net; (3) auditoria automatizada de queries cross-tenant via testes. Impersonacao de admin global e auditada (AdminAuditLog) e usa cookie HMAC com TTL fixo de 1h.

Posso ter dominio proprio (white-label completo)?

Sim. Configure Tenant.customDomain no settings + aponte CNAME para o dominio Studeia. TLS automatico via Let's Encrypt no Caddy (on-demand TLS, apos verificacao do dominio por registro TXT). Logo, favicon, cores, fontes, 9 temas visuais e ate mensagens de email customizaveis. Pode remover a marca Studeia totalmente.

Custos de IA sao por tenant?

Sim. Cada chamada LLM e logada em AiUsageLog com tenantId. Admin global ve breakdown de custo por tenant em /admin/finance/ai-cost (com calculo de margem vs MRR). Tenants podem usar proprias chaves de API (TenantApiKey) — nesse caso custos vao para o tenant, nao para Studeia.

Como sao gerenciados usuarios cross-tenant?

Por design, um User pertence a UM tenant (User.tenantId). Para casos B2B onde um pedagogo atende multiplas escolas, recomendamos criar usuarios separados por instituicao. Admin global pode reassign usuarios via /admin/tenants (auditado).

Veja tambem

Multi-tenancy e isolamento de dados