Saltar al contenido
Studeia Docs
AI-assisted translation — last updated 2026-07-18. For original (pt-BR or en-US), use the language switcher.

Multi-tenancy y aislamiento de datos

Arquitectura multi-tenant de Studeia: cada institución tiene aislamiento completo a nivel de base de datos con filtro por tenantId, RLS Supabase, API keys por tenant, white-label total y SSO independiente.

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

El multi-tenancy en Studeia garantiza que los datos de cada institución queden totalmente aislados de los demás — requisito de privacidad y seguridad para operar con confianza. Cada tenant tiene su propia marca, su configuración de IA (puede usar sus propias claves) y sus API keys, con aislamiento a nivel de base de datos y RLS como red de seguridad. En la práctica, su institución opera como si la plataforma fuera exclusivamente suya.

Modelo conceptual

Tenant (Institución)
  ├── Users (alumnos, profesores, coordinadores, admin institucional)
  ├── Courses → Modules → Lessons
  ├── ClassGroups (grupos/clases)
  ├── MediaAssets (biblioteca de medios)
  ├── Automations
  ├── EmailTemplates
  ├── VideoProviderConfig (BBB/Zoom/Teams/Meet)
  ├── TenantApiKey (claves propias de IA)
  ├── TenantSubscription (billing)
  ├── ...todas las demás entidades

Los usuarios sin tenantId son B2C (plataforma directa). Los usuarios con tenantId pertenecen a una institución.

Aislamiento de datos — 3 capas

Capa 1: Filtro obligatorio en queries

Toda query Prisma en el código de aplicación filtra por tenantId:

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

requireTenant() en apps/web/lib/tenant.ts retorna NextResponse 403 si el usuario no tiene tenant. Sin esta llamada, es imposible acceder a datos B2B.

Capa 2: RLS en Supabase

Como red de seguridad contra bugs, las políticas RLS en Supabase refuerzan el aislamiento incluso en queries directas. Si un código olvida el filtro tenantId, la base de datos lo rechaza.

Capa 3: Auditoría de admin global

Cuando un admin global necesita acceder a los datos de un tenant (soporte, debug), utiliza suplantación vía cookie HMAC con:

  • TTL fijo de 1h (no prorrogable)
  • Firma HMAC-SHA256 con IMPERSONATION_SECRET
  • Auditoría en AdminAuditLog (acción impersonate.start, IP, user-agent)
  • getUserProfile() retorna isImpersonating: true + overlay en memoria
  • La auth de Supabase NUNCA se modifica (solo overlay)
  • Banner sticky en /institution/ alerta al admin durante la sesión

El panel admin SaaS global incluye suplantación para soporte.

API keys por tenant

Por defecto, todas las llamadas LLM utilizan las claves globales (ANTHROPIC_API_KEY, OPENAI_API_KEY, etc.) de Studeia. Los costos se imputan al tenant vía metering.

Pero las instituciones que ya tienen cuentas en Anthropic/OpenAI/Google pueden usar sus propias claves (TenantApiKey, cifrada AES-256-GCM en la base de datos):

  1. Los costos van DIRECTAMENTE a la cuenta del tenant en Anthropic/OpenAI
  2. Studeia no cobra margen de IA — solo la suscripción mensual
  3. Resolución automática: TenantApiKeyProviderApiKey global → process.env (cascada en apps/web/lib/api-key-resolver.ts)

NUNCA se establece process.env en runtime (entraría en conflicto entre tenants) — la clave se pasa vía opciones del SDK.

White-label completo

Cada tenant puede personalizar:

AspectoCómo
Logo, faviconSubida en settings
Colores (primary, accent, background)Editor con preview
Fuente (Google Fonts)Dropdown
Tema visual (de 9 opciones)Toggle por usuario o predeterminado del tenant
CSS personalizadoSaneado, máx. 10KB
Dominio personalizadoDNS CNAME + TXT _studeia-verify + TLS automático Caddy (on-demand)
Logo en el emailPor plantilla
Email de envío (SMTP/Resend/SendGrid)TenantEmailConfig
Ocultar marca StudeiaSí (plan enterprise)

Roles y permisos

RolAlcancePuede hacer
studentPropio progresoChat tutor, cursos, simulacros, gamificación
parentHijos vinculadosVer progreso, alertas, informes
teacherPropios grupos/cursosCrear cursos, subir material, ver alumnos de los grupos
coordinatorTodos los grupos del tenantGestionar grupos, ver todos los alumnos
pedagogueTodos los alumnos del tenantOrientación educativa, informes
institution_adminTodo el tenantConfig IA, API keys, white-label, usuarios
adminGlobal (plataforma)Todo + gestionar tenants

Límites por plan

Límites aplicados vía checkTenantResourceLimit(tenantId, resource) en apps/web/lib/plan-limits.ts:

PlanAlumnos máx.ProfesoresCursosIA
Demo111Solo Haiku, 10 msgs/día
Mini10IlimitadoIlimitadoTodos los providers
Crescimento50IlimitadoIlimitadoTodos los providers
Escala100IlimitadoIlimitadoTodos los providers
EnterpriseCustom (maxStudentsOverride)IlimitadoIlimitadoTodos los providers

7 puntos de aplicación (todos auditados el 2026-04-11):

  1. POST /api/courses/[courseId]/enroll — auto-inscripción del alumno
  2. POST /api/institution/courses/[id]/clone — clonar curso
  3. POST /api/institution/courses/import — importar IMS CC
  4. executeEnrollUser() en automatización
  5. POST /api/scim/v2/Users — aprovisionamiento SCIM
  6. POST /api/institution/users — vincular usuario existente
  7. PATCH /api/institution/users/[id] — promover rol

Cómo solicitar override enterprise

Los tenants enterprise pueden tener Tenant.maxStudentsOverride: Int? ajustado por el admin global. Sin override (null), enterprise = ilimitado. Contacto comercial vía contact@studeia.com.

Limitaciones

  • Un User pertenece a UN tenant. Para profesores que atienden múltiples escuelas, crear usuarios separados.
  • El intercambio de cursos entre tenants no es nativo (cada tenant tiene su CMS aislado). Roadmap: marketplace de cursos con licenciamiento.
  • La migración de un tenant a otro plan es instantánea, pero el downgrade que viola los límites actuales queda bloqueado hasta que el tenant ajuste sus recursos.

Ver también

FAQ

¿Los datos de los tenants están realmente aislados?

Sí. Tres capas: (1) toda query Prisma filtra por tenantId obligatoriamente (regla crítica 30 del proyecto); (2) políticas RLS en Supabase como red de seguridad; (3) auditoría automatizada de queries cross-tenant mediante tests. La suplantación de admin global es auditada (AdminAuditLog) y utiliza cookie HMAC con TTL fijo de 1h.

¿Puedo tener dominio propio (white-label completo)?

Sí. Configure Tenant.customDomain en settings + apunte CNAME al dominio de Studeia. TLS automático vía Let's Encrypt en Caddy (on-demand TLS, tras verificación del dominio por registro TXT). Logo, favicon, colores, fuentes, 9 temas visuales e incluso mensajes de email personalizables. Puede eliminar la marca Studeia totalmente.

¿Los costos de IA son por tenant?

Sí. Cada llamada LLM se registra en AiUsageLog con tenantId. El admin global puede ver el desglose de costos por tenant en /admin/finance/ai-cost (con cálculo de margen vs MRR). Los tenants pueden usar sus propias claves de API (TenantApiKey) — en ese caso los costos van al tenant, no a Studeia.

¿Cómo se gestionan los usuarios cross-tenant?

Por diseño, un User pertenece a UN tenant (User.tenantId). Para casos B2B donde un pedagogo atiende múltiples escuelas, recomendamos crear usuarios separados por institución. El admin global puede reasignar usuarios vía /admin/tenants (auditado).

Veja tambem

Multi-tenancy y aislamiento de datos