template-saas/docs/architecture/adr/ADR-001-multi-tenancy-rls.md
rckrdmrd 50a821a415
Some checks failed
CI / Backend CI (push) Has been cancelled
CI / Frontend CI (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / CI Summary (push) Has been cancelled
[SIMCO-V38] feat: Actualizar a SIMCO v3.8.0
- HERENCIA-SIMCO.md actualizado con directivas v3.7 y v3.8
- Actualizaciones de configuracion

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 08:53:08 -06:00

4.2 KiB

id title type status priority supersedes superseded_by version created_date updated_date
ADR-001 Multi-tenancy con PostgreSQL Row-Level Security ADR Accepted P0 N/A N/A 1.0.0 2026-01-07 2026-01-10

ADR-001: Multi-tenancy con PostgreSQL Row-Level Security

Metadata

Campo Valor
ID ADR-001
Estado Accepted
Fecha 2026-01-10
Supersede N/A

Contexto

Template SaaS requiere soporte para múltiples organizaciones (tenants) en una misma instancia de la aplicación. Cada tenant debe tener sus datos completamente aislados de otros tenants por razones de seguridad y privacidad.

Requisitos

  • Aislamiento completo de datos entre tenants
  • Escalabilidad para miles de tenants
  • Simplicidad operacional (un solo deployment)
  • Performance consistente
  • Facilidad de backup/restore por tenant

Opciones Consideradas

Opción 1: Database per Tenant

Descripción: Cada tenant tiene su propia base de datos PostgreSQL.

Pros:

  • Aislamiento total de datos
  • Fácil backup/restore individual
  • Sin riesgo de data leaks entre tenants

Contras:

  • Complejidad operacional alta (miles de DBs)
  • Connection pooling complejo
  • Migraciones costosas (aplicar a cada DB)
  • Mayor costo de infraestructura

Opción 2: Schema per Tenant

Descripción: Cada tenant tiene su propio schema dentro de una base de datos.

Pros:

  • Mejor aislamiento que shared tables
  • Backup/restore por schema posible
  • Un solo connection pool

Contras:

  • Migraciones aún costosas
  • Límite práctico de schemas (~10,000)
  • Complejidad en queries cross-tenant

Opción 3: Row-Level Security (RLS) ✓

Descripción: Todos los tenants comparten las mismas tablas, con políticas RLS que filtran por tenant_id.

Pros:

  • Operacionalmente simple
  • Un solo set de tablas y migraciones
  • Escalable a millones de tenants
  • Performance optimizado con índices
  • Queries simples y consistentes

Contras:

  • Riesgo de data leaks si RLS mal configurado
  • Requiere disciplina en desarrollo
  • Backup individual más complejo

Decisión

Elegimos Row-Level Security (RLS) por las siguientes razones:

  1. Simplicidad Operacional: Un solo deployment, una base de datos, un set de migraciones
  2. Escalabilidad: Soporta desde 1 hasta millones de tenants sin cambios arquitectónicos
  3. Performance: PostgreSQL RLS es eficiente y se beneficia de índices
  4. Costo: Menor infraestructura requerida

Implementación

Estructura de Tablas

Todas las tablas multi-tenant incluyen:

tenant_id UUID NOT NULL REFERENCES tenants.tenants(id)

Políticas RLS

-- Ejemplo para tabla users
ALTER TABLE users.users ENABLE ROW LEVEL SECURITY;

CREATE POLICY users_tenant_isolation ON users.users
    USING (tenant_id = current_setting('app.current_tenant_id')::uuid);

Context Setting

El tenant_id se establece en cada request:

SET app.current_tenant_id = 'uuid-del-tenant';

Middleware NestJS

@Injectable()
export class TenantContextInterceptor implements NestInterceptor {
  async intercept(context: ExecutionContext, next: CallHandler) {
    const request = context.switchToHttp().getRequest();
    const tenantId = request.user?.tenant_id;

    await this.dataSource.query(
      `SET app.current_tenant_id = '${tenantId}'`
    );

    return next.handle();
  }
}

Consecuencias

Positivas

  • Código más simple y mantenible
  • Un solo esquema de datos
  • Migraciones atómicas
  • Queries sin WHERE tenant_id manual
  • Escalabilidad lineal

Negativas

  • Requiere testing exhaustivo de RLS
  • Datos de todos los tenants en mismas tablas
  • Backup por tenant requiere queries filtradas
  • Posible contención en tablas muy grandes

Mitigaciones

  • Tests automatizados de aislamiento
  • Auditoría de queries en desarrollo
  • Particionamiento por tenant_id si necesario
  • Monitoreo de performance por tenant

Referencias


Fecha decision: 2026-01-10 Autores: Claude Code (Arquitectura)