Inicio · Blog · software-medida/supabase-auth-crm

software-medida/supabase-auth-crm

Supabase Auth para CRM multi-tenant: implementación

Cómo usar Supabase Auth para CRM a medida multi-tenant en LATAM: RBAC, RLS por tenant, JWT custom claims y aislamiento garantizado a nivel base de datos.

Pablo Estrada · 11 de mayo de 2026 · 6 min de lectura
Supabase Auth para CRM multi-tenant: implementación

Supabase Auth con Row Level Security es la opción correcta para CRM a medida multi-tenant en LATAM. Cada usuario ve solo lo que su tenant permite, la separación está en la capa base de datos (no en código aplicación), y cero riesgo de leak entre tenants. Catalizadora construyó plataforma para 100 franquicias internacionales con este patrón. Sin retainers, sin licencias atadas, código a tu nombre.

¿Qué es multi-tenant en CRM y por qué es difícil?

Multi-tenant significa: un solo deploy del sistema sirve a N organizaciones (tenants) que no pueden ver datos entre sí. Cada tenant tiene sus usuarios, sus clientes, sus deals, sus reportes. Cero leak entre tenants es requisito no negociable.

El error clásico es manejar tenancy en código aplicación: cada query agrega "WHERE tenant_id = X" según el usuario. Funciona hasta que hay un bug, un endpoint que olvida agregar el filtro, o un developer que ejecuta query sin pensar. Resultado: tenant A ve datos de tenant B. Disaster comercial y legal.

La solución correcta es manejar tenancy en la capa base de datos con Row Level Security (RLS). Las políticas filtran automáticamente cada query según el JWT del usuario. Aunque el código aplicación tenga bug, la base no devuelve filas no autorizadas.

¿Cómo funciona RLS con Supabase?

Supabase es PostgreSQL gestionado. RLS es feature nativa de PostgreSQL desde 2017. El flujo:

  • Usuario se autentica vía Supabase Auth (email password, magic link, OAuth, OTP)
  • Supabase emite JWT con campos estándar (id, email, role) más custom claims (tenant_id, oficina_id, rol_custom)
  • App envía requests con el JWT en el header Authorization
  • Supabase API ejecuta las queries pasando el JWT a PostgreSQL
  • PostgreSQL aplica RLS policies que leen el JWT y filtran filas

El developer escribe el código como si fuera single-tenant. La RLS hace el filtrado por debajo. Cero código tenant-specific en la aplicación.

El caso real: 100 franquicias internacionales con 7 roles RBAC

Catalizadora construyó la plataforma multi-tenant para una distribuidora con 100 franquicias internacionales:

  • 7 roles RBAC definidos (tni_admin, tni_regional, franchise_owner, franchise_admin, franchise_manager, franchise_user, auditor)
  • RLS por oficina usando JWT custom claims (auth.user_oficina_id())
  • DENY UPDATE/DELETE en audit log (append-only)
  • Schemas silver y gold protegidos por RLS
  • Session mode connection pooler (no transaction mode)
  • 3.6 millones de filas migradas a Supabase con RLS activo desde día uno

Resultado: cada franquicia ve solo sus datos. La arquitectura escala a 100 a 200 inmobiliarias bajo el mismo deploy si fuera SaaS inmobiliario.

Estructura típica de tabla multi-tenant

Una tabla de CRM con tenant_id como columna y RLS policy:

create table public.deals (
  id uuid primary key default gen_random_uuid(),
  tenant_id uuid not null references public.tenants(id),
  owner_id uuid not null references auth.users(id),
  title text not null,
  amount numeric,
  stage text not null,
  created_at timestamptz default now()
);

create index deals_tenant_idx on public.deals(tenant_id);

alter table public.deals enable row level security;

create policy "deals_read_own_tenant" on public.deals
  for select
  using (tenant_id = (auth.jwt() ->> 'tenant_id')::uuid);

create policy "deals_write_own_tenant" on public.deals
  for insert with check (tenant_id = (auth.jwt() ->> 'tenant_id')::uuid);

Cada query del usuario lee solo deals de su tenant. Sin código aplicación tenant-specific. RLS hace el trabajo.

JWT custom claims: cómo agregarlos

Supabase Auth permite agregar claims custom al JWT vía:

  • Auth Hook (Auth Hook Send Email, Auth Hook Custom Access Token): función serverless que enriquece el JWT en cada login
  • raw_app_meta_data en auth.users: campo JSON que se incluye automáticamente en cada JWT emitido
  • Trigger before login que populates raw_app_meta_data

Patrón típico: cuando se crea un usuario, un trigger asigna tenant_id y rol en raw_app_meta_data. Cada login refresca el JWT con esos claims. Las policies leen el campo tenant_id desde el JWT con el operador JSON de PostgreSQL.

Roles RBAC jerárquicos

Para un CRM multi-tenant serio, los roles típicos en LATAM:

Rol Permisos
super_admin (Catalizadora) Todo en todos los tenants. Solo para soporte y migración
tenant_admin Todo dentro de su tenant. CRUD usuarios, configuración, billing
manager CRUD deals, reportes de su equipo. No usuarios ni billing
sales_rep CRUD deals propios. Lectura de equipo
viewer Solo lectura de su tenant
auditor Solo lectura más audit log completo. Para compliance

Las policies RLS implementan esta jerarquía: super_admin bypassea RLS, tenant_admin lee todo su tenant, manager filtra por equipo, sales_rep filtra por owner_id propio.

Audit log inmutable con SHA-256

Para CRM multi-tenant con compliance (financiero, legal, salud), el audit log debe ser append-only verificable. Catalizadora implementa:

  • Schema audit aparte con RLS DENY UPDATE/DELETE forzado
  • Trigger en cada INSERT que calcula SHA-256 hash del registro anterior más el nuevo (hash chain)
  • Función audit.verify_chain_integrity() que recalcula la cadena y detecta manipulaciones
  • Cada evento tiene user_id, ip, action, table, row_id en JSON metadata

Si alguien intenta modificar audit log directamente en base, falla por RLS. Si modifica via super_admin, la hash chain se rompe en la próxima verificación.

¿Qué pasa con storage de archivos multi-tenant?

Supabase Storage tiene RLS análoga para buckets y objects. Patrón típico:

  • Bucket por tipo (avatars, documents, attachments)
  • Estructura de carpetas: /[tenant_id]/[user_id]/[filename]
  • Policy: solo permitir acceso a objects donde el primer segmento del path coincide con tenant_id del JWT

Cada tenant ve solo sus archivos. Cero leak. Sin lógica tenant-specific en código aplicación.

Conexión pooler: session mode vs transaction mode

Para CRM serio con RLS activo, usar session mode pooler (puerto 5432 directo o pooler en port 6543 con session mode), no transaction mode (port 6543 transaction). Razón:

  • Transaction mode reinicia la sesión entre queries. El JWT context se pierde.
  • Session mode mantiene la sesión durante la duración de la conexión. RLS funciona correctamente.

Catalizadora usa session mode para todas las plataformas multi-tenant sobre Supabase.

Escalabilidad: ¿hasta cuántos tenants y usuarios?

Supabase Pro plan base maneja sin problemas:

  • 50,000 a 100,000 usuarios activos por instance
  • 100 a 1,000 tenants por instance
  • 5 a 50 millones de filas con RLS activo (con índices correctos)

Para escalas mayores, Supabase ofrece compute upgrade lineal y eventualmente self-hosted con replicación. La distribuidora con 100 franquicias internacionales que Catalizadora construyó corre cómoda sobre Supabase Pro compute Micro.

Stack recomendado para CRM multi-tenant 2026

Capa Tecnología Razón
Frontend Next.js 15 + Tailwind + shadcn/ui RSC, app router maduro
Backend API Direct Supabase + Edge Functions Reduce hop, RLS automático
Auth Supabase Auth con custom claims Multi-tenant nativo
Database Supabase Pro PostgreSQL RLS, JSONB, pgvector
Storage Supabase Storage con RLS Archivos por tenant
Realtime Supabase Realtime Subscriptions con RLS
Observabilidad Sentry + Better Stack Errors, logs por tenant

Próximos pasos

Si vas a construir CRM multi-tenant serio en LATAM, Supabase Auth con RLS es la opción correcta para 90 por ciento de casos. La excepción son escalas extremas (más de 200,000 usuarios concurrentes) o requisitos regulatorios on-prem específicos.

MAGIA Forge construye el CRM multi-tenant completo en 12 semanas con CI/CD, hardening, observabilidad y auditoría compliance por 20,000 USD pago único. Para CRM single-tenant más simple, MAGIA Core cubre por 15,000 USD. Código a tu nombre, sin retainers, sin licencias atadas.

Cómo te ayuda Catalizadora

Construimos sistemas con IA a la medida, con el código 100% tuyo. Elige por dónde empezar:

  • MAGIA Solo — marca, sitio, CRM y asistente con IA en 15 días.
  • MAGIA Core — automatización empresarial y dashboards por rol.
  • MAGIA Forge — software a medida con IA.
  • Ver precios · Academia de IA

Preguntas frecuentes

¿Supabase Auth sirve para CRM multi-tenant serio?

Sí. Con Row Level Security (RLS), JWT custom claims y políticas por tenant, Supabase Auth maneja multi-tenant a escala. Catalizadora construyó plataforma para 100 franquicias internacionales sobre este patrón.

¿Qué es JWT custom claims y por qué importa?

Es información custom incrustada en el token JWT (tenant_id, oficina_id, rol). Las políticas RLS leen ese JWT y filtran datos automáticamente a nivel base. Cada usuario ve solo lo que su tenant le permite ver.

¿Cómo se evita leak de datos entre tenants?

RLS forzado en cada tabla de aplicación. La separación está en la capa base de datos, no en código aplicación. Aunque haya bug en el código, la base no devuelve filas de otro tenant. Cero riesgo de leak.

¿Cuántos roles RBAC se manejan típicamente?

Entre 4 y 10 roles por proyecto serio. Catalizadora implementó 7 roles RBAC para una distribuidora multi-país (tni_admin, tni_regional, franchise_owner, franchise_admin, franchise_manager, franchise_user, auditor) con permisos jerárquicos.

¿Qué pasa si un tenant tiene millones de filas?

RLS escala bien si las políticas están indexadas correctamente. Los índices sobre tenant_id, oficina_id o equivalente son críticos. Catalizadora migró 3.6 millones de filas a Supabase y RLS performó sin degradación.

¿Esto aplica a tu operación?

Déjanos tu correo y te escribimos en menos de 24 horas con un diagnóstico inicial sin costo. Sin pitch, sin agenda comercial.

¿Prefieres conversar antes? Agenda 30 minutos con Pablo Estrada — sin pitch deck.

Agendar llamada →

¿Prefieres aprender a hacerlo tú? El curso completo de la Academia son 8 clases, gratis y sin tarjeta.

Entrar a la Academia →

Sigue leyendo

SaaS en 2026: ruta honesta para fundadores LATAMAutomatización en sector salud mental México casos 2026Catalizadora vs Encora vs Globant para pymes LATAM 2026