Skip to content
Studeia Docs

Multi-tenancy and data isolation

Studeia multi-tenant architecture: each institution has complete isolation at DB level with tenantId filter, Supabase RLS, per-tenant API keys, complete white-label and independent SSO.

2026-05-31 7 min
Resposta curta

Multi-tenancy in Studeia means each institution (Tenant) has completely isolated data at DB level. Mandatory tenantId filter in all Prisma queries, Supabase RLS as safety net, per-tenant API keys, independent AI configuration (can use own Anthropic/OpenAI keys) and complete white-label (domain, branding, theme, email).

Conceptual model

Tenant (Institution)
  ├── Users (students, teachers, coordinators, institutional admin)
  ├── Courses → Modules → Lessons
  ├── ClassGroups
  ├── MediaAssets
  ├── Automations
  ├── EmailTemplates
  ├── VideoProviderConfig (BBB/Zoom/Teams/Meet)
  ├── TenantApiKey (own AI keys)
  ├── TenantSubscription (billing)
  └── ...all other entities

Data isolation — 3 layers

Layer 1: Mandatory query filter

All Prisma queries in application code filter by tenantId:

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

Layer 2: Supabase RLS

As safety net against bugs, RLS policies in Supabase enforce isolation even on direct queries.

Layer 3: Global admin audit

Global admin impersonation uses HMAC cookie with fixed 1h TTL, signed via IMPERSONATION_SECRET, audited in AdminAuditLog.

Per-tenant API keys

TenantApiKey encrypted AES-256-GCM. Resolution cascade: TenantApiKey → ProviderApiKey global → process.env. Costs go directly to tenant's Anthropic/OpenAI account.

Roles

RoleScope
studentOwn progress
parentLinked children
teacherOwn classes
coordinatorAll classes in tenant
pedagogueAll students in tenant
institution_adminEntire tenant
adminGlobal platform

Limits per plan

Enforced via checkTenantResourceLimit() at 7 enforcement points (audited 2026-04-11).

See also

FAQ

Is tenant data really isolated?

Yes. Three layers: (1) every Prisma query filters by tenantId mandatorily (critical rule 30); (2) Supabase RLS policies as safety net; (3) automated cross-tenant query audit via tests. Global admin impersonation is audited (AdminAuditLog) and uses HMAC cookie with fixed 1h TTL.

Can I have a custom domain (full white-label)?

Yes. Configure Tenant.customDomain in settings + point CNAME to Studeia domain. Automatic TLS via Let's Encrypt on Caddy (on-demand TLS, after domain verification via a TXT record). Logo, favicon, colors, fonts, 9 visual themes, and even email messages customizable. Studeia branding can be fully removed.

Are AI costs per tenant?

Yes. Every LLM call is logged in AiUsageLog with tenantId. Global admin sees cost breakdown per tenant at /admin/finance/ai-cost (with margin vs MRR calculation). Tenants can use their own API keys (TenantApiKey) — costs go to tenant, not to Studeia.

How are cross-tenant users managed?

By design, a User belongs to ONE tenant (User.tenantId). For B2B cases where a coordinator serves multiple schools, we recommend separate users per institution. Global admin can reassign users via /admin/tenants (audited).

Veja tambem

Multi-tenancy and data isolation