> ## Documentation Index
> Fetch the complete documentation index at: https://docs.lerian.studio/llms.txt
> Use this file to discover all available pages before exploring further.

# Modo multi-tenant

> Ejecuta Matcher en modo multi-tenant para atender a múltiples clientes con bases de datos, brokers de mensajes, cachés y almacenamiento aislados.

El modo multi-tenant permite que Matcher sirva a múltiples clientes con aislamiento completo de datos. Cada inquilino opera en su propia base de datos, broker de mensajes y namespace de caché, asegurando que los datos de un inquilino nunca sean visibles para otro.

Esto es esencial para despliegues SaaS, entornos regulados o cualquier escenario donde se requieran límites estrictos de datos entre clientes.

## Descripción general

***

Por defecto, Matcher se ejecuta en **modo single-tenant**: todas las solicitudes comparten una base de datos y un conjunto de conexiones de infraestructura. Esta es la configuración más simple y funciona bien para despliegues de un solo cliente.

Cuando se habilita el **modo multi-tenant**, cada inquilino recibe:

* **Base de datos aislada** — una base de datos PostgreSQL dedicada provisionada y gestionada por el servicio de la plataforma de multi-tenancy
* **Broker de mensajes aislado** — un virtual host dedicado de RabbitMQ, más encabezados `X-Tenant-ID` en cada mensaje como defensa en profundidad
* **Caché aislado** — todas las claves de Redis se prefijan automáticamente con el identificador del inquilino
* **Almacenamiento aislado** — los objetos S3 se prefijan con el identificador del inquilino

La identidad del inquilino se determina a partir del token JWT en cada solicitud de API. El claim `tenant_id` en el token le indica a Matcher a qué inquilino pertenece la solicitud, y las conexiones de infraestructura correctas se resuelven automáticamente. El claim heredado `tenantId` también se acepta como alternativa para compatibilidad con versiones anteriores.

## Cómo activar

***

### Prerrequisitos

* El **servicio de la plataforma de multi-tenancy** debe estar en ejecución y accesible desde la red de Matcher antes de habilitar el modo multi-tenant.
* Matcher debe estar configurado con autenticación habilitada (`PLUGIN_AUTH_ENABLED=true`), ya que la identidad del inquilino proviene del token JWT.

### Configuración

Las configuraciones multi-tenant se establecen a través de variables de entorno, igual que otras configuraciones de Matcher. Dónde las definas depende de tu método de despliegue:

* **Docker Compose:** agrégalas a un archivo `.env` en la raíz del proyecto o directamente en `docker-compose.yml` en la sección `environment`
* **Kubernetes / Helm:** agrégalas a tu archivo de valores de Helm en la sección de entorno correspondiente
* **Standalone:** defínelas en tu entorno de shell o configuración del gestor de procesos

<Note>
  Consulta la [Guía de instalación](/es/matcher/getting-started/matcher-installation) para detalles sobre dónde se ubican los archivos de entorno en tu despliegue.
</Note>

#### Variables requeridas

Agrega estas a tu configuración de entorno para habilitar el modo multi-tenant:

```env theme={null}
# Habilitar el modo multi-tenant
MULTI_TENANT_ENABLED=true

# URL del endpoint del servicio de multi-tenancy
MULTI_TENANT_URL=https://multi-tenancy.example.com

# Clave de API para autenticarse con el servicio de multi-tenancy
MULTI_TENANT_SERVICE_API_KEY=your-api-key
```

#### Ajuste opcional

Puedes ajustar tamaños de pool, tiempos de espera y comportamiento del circuit breaker:

```env theme={null}
# Número máximo de pools de conexión de tenants concurrentes (predeterminado: 100)
MULTI_TENANT_MAX_TENANT_POOLS=200

# Segundos antes de que un pool de tenant inactivo sea desalojado (predeterminado: 300)
MULTI_TENANT_IDLE_TIMEOUT_SEC=600

# Fallos consecutivos del servicio de multi-tenancy antes de que se abra el circuit breaker (predeterminado: 5)
MULTI_TENANT_CIRCUIT_BREAKER_THRESHOLD=3

# Segundos que el circuit breaker permanece abierto antes de reintentar (predeterminado: 30)
MULTI_TENANT_CIRCUIT_BREAKER_TIMEOUT_SEC=60

# Etiqueta de entorno para la resolución de tenants por entorno (opcional)
MULTI_TENANT_ENVIRONMENT=production
```

Después de actualizar la configuración, reinicia el servicio Matcher. Al iniciar, deberías ver mensajes de log confirmando que la infraestructura multi-tenant fue inicializada.

## Aislamiento de inquilinos

***

### Aislamiento de base de datos

Cada inquilino obtiene su propia base de datos PostgreSQL. Cuando llega una solicitud, Matcher resuelve el inquilino desde el JWT y se conecta a la base de datos dedicada de ese inquilino. Si aún no existe un pool de conexiones para ese inquilino, se crea bajo demanda usando la configuración del servicio de la plataforma de multi-tenancy.

Los pools de conexiones están limitados por `MULTI_TENANT_MAX_TENANT_POOLS` y se desalojan cuando están inactivos más allá de `MULTI_TENANT_IDLE_TIMEOUT_SEC`.

### Aislamiento del broker de mensajes

El aislamiento de RabbitMQ utiliza dos capas:

* **Virtual host por inquilino** — los mensajes de cada inquilino se enrutan a través de un vhost dedicado, previniendo cualquier filtración de mensajes entre inquilinos
* **Encabezados de Tenant ID** — cada mensaje publicado incluye un encabezado `X-Tenant-ID` como capa de seguridad adicional para consumidores posteriores

No se necesita crear vhosts manualmente. El servicio de la plataforma de multi-tenancy provisiona los vhosts automáticamente.

### Aislamiento de caché

Todas las claves de Redis se prefijan automáticamente con el identificador del inquilino en el formato `tenant:{tenantID}:{key}`. Esto aplica a verificaciones de idempotencia, deduplicación, limitación de tasa y almacenamiento en caché de credenciales.

### Aislamiento de almacenamiento

Los objetos almacenados en almacenamiento compatible con S3 se prefijan con `{tenantID}/`, asegurando que las exportaciones y archivos de cada inquilino estén separados a nivel de almacenamiento.

## Gestión de pools de conexiones

***

Matcher mantiene un pool de conexiones de base de datos para cada inquilino activo. Estas configuraciones controlan el uso de recursos:

| Variable                        | Por defecto | Descripción                                                                                                                                  |
| ------------------------------- | ----------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| `MULTI_TENANT_MAX_TENANT_POOLS` | `100`       | Número máximo de pools de inquilinos mantenidos simultáneamente. Cuando se alcanza el límite, el pool menos recientemente usado se desaloja. |
| `MULTI_TENANT_IDLE_TIMEOUT_SEC` | `300`       | Cuánto tiempo (en segundos) un pool de inquilino inactivo permanece abierto antes de ser limpiado.                                           |

### Planificación de capacidad

Cada pool de inquilino usa hasta `POSTGRES_MAX_OPEN_CONNS` conexiones (por defecto: 25). Con 100 pools de inquilinos, el peor caso total es 2,500 conexiones PostgreSQL. Dimensiona el `max_connections` de tu base de datos en consecuencia.

### Verificaciones de salud automáticas

Matcher verifica periódicamente la configuración de inquilinos (cada `MULTI_TENANT_CONNECTIONS_CHECK_INTERVAL_SEC`, por defecto 30s) para detectar rotación de credenciales o cambios en la configuración del pool. Las configuraciones actualizadas se aplican sin requerir un reinicio.

## Circuit breaker

***

Si el servicio de la plataforma de multi-tenancy se vuelve inaccesible, un circuit breaker protege a Matcher de fallos en cascada.

| Variable                                   | Por defecto | Descripción                                                               |
| ------------------------------------------ | ----------- | ------------------------------------------------------------------------- |
| `MULTI_TENANT_CIRCUIT_BREAKER_THRESHOLD`   | `5`         | Cuántos fallos consecutivos antes de que el circuit breaker se active.    |
| `MULTI_TENANT_CIRCUIT_BREAKER_TIMEOUT_SEC` | `30`        | Cuánto tiempo el breaker permanece activo antes de permitir un reintento. |

Mientras el circuit breaker está activo, las solicitudes para nuevos inquilinos fallarán rápidamente. Sin embargo, **las conexiones existentes de inquilinos continúan funcionando normalmente** — solo la incorporación de nuevos inquilinos se ve afectada.

## Caché de configuración de inquilinos

***

Para reducir llamadas al servicio de la plataforma de multi-tenancy, Matcher almacena en caché las configuraciones de inquilinos en memoria.

| Variable                     | Por defecto | Descripción                                                                                                                               |
| ---------------------------- | ----------- | ----------------------------------------------------------------------------------------------------------------------------------------- |
| `MULTI_TENANT_CACHE_TTL_SEC` | `120`       | Cuánto tiempo (en segundos) la configuración del inquilino se almacena en caché antes de actualizarse desde el servicio de multi-tenancy. |

En la primera solicitud para un inquilino, Matcher obtiene la configuración de la API del servicio de la plataforma de multi-tenancy y la almacena en caché. Las solicitudes posteriores para el mismo inquilino se sirven desde caché hasta que el TTL expire.

## Todas las variables de entorno

***

### Infraestructura multi-tenant

<ParamField path="MULTI_TENANT_ENABLED" type="bool" default="false">
  Interruptor principal para el modo multi-tenant.
</ParamField>

<ParamField path="MULTI_TENANT_URL" type="string">
  Requerida cuando el modo multi-tenant está habilitado. URL base del servicio de la plataforma de multi-tenancy.
</ParamField>

<ParamField path="MULTI_TENANT_SERVICE_API_KEY" type="string">
  Requerida cuando el modo multi-tenant está habilitado. Clave API para autenticarse con el servicio de multi-tenancy.
</ParamField>

<ParamField path="MULTI_TENANT_ENVIRONMENT" type="string">
  Etiqueta de entorno para resolución de inquilinos.
</ParamField>

<ParamField path="MULTI_TENANT_MAX_TENANT_POOLS" type="int" default="100">
  Pools de conexiones de inquilinos concurrentes máximos.
</ParamField>

<ParamField path="MULTI_TENANT_IDLE_TIMEOUT_SEC" type="int" default="300">
  Segundos antes de que un pool de inquilino inactivo sea desalojado.
</ParamField>

<ParamField path="MULTI_TENANT_TIMEOUT" type="int" default="30">
  Tiempo de espera HTTP (segundos) para llamadas al servicio de multi-tenancy.
</ParamField>

<ParamField path="MULTI_TENANT_CIRCUIT_BREAKER_THRESHOLD" type="int" default="5">
  Fallos consecutivos antes de que el circuit breaker se active.
</ParamField>

<ParamField path="MULTI_TENANT_CIRCUIT_BREAKER_TIMEOUT_SEC" type="int" default="30">
  Segundos que el circuit breaker permanece activo.
</ParamField>

<ParamField path="MULTI_TENANT_CACHE_TTL_SEC" type="int" default="120">
  TTL de caché (segundos) para configuraciones de inquilinos.
</ParamField>

<ParamField path="MULTI_TENANT_CONNECTIONS_CHECK_INTERVAL_SEC" type="int" default="30">
  Intervalo (segundos) para verificaciones de salud del pool de conexiones.
</ParamField>

<ParamField path="MULTI_TENANT_REDIS_HOST" type="string">
  Host de Redis para descubrimiento de inquilinos basado en eventos.
</ParamField>

<ParamField path="MULTI_TENANT_REDIS_PORT" type="string" default="6379">
  Puerto de Redis para descubrimiento de inquilinos.
</ParamField>

<ParamField path="MULTI_TENANT_REDIS_PASSWORD" type="string">
  Contraseña de Redis para descubrimiento de inquilinos.
</ParamField>

<ParamField path="MULTI_TENANT_REDIS_TLS" type="bool" default="false">
  Habilitar TLS para Redis de descubrimiento de inquilinos.
</ParamField>

### Inquilino por defecto

<ParamField path="DEFAULT_TENANT_ID" type="string" default="11111111-1111-1111-1111-111111111111">
  UUID del inquilino por defecto (fallback). Usado en modo single-tenant.
</ParamField>

<ParamField path="DEFAULT_TENANT_SLUG" type="string" default="default">
  Slug del inquilino por defecto.
</ParamField>

## Verificar el modo multi-tenant

***

Después de activar el modo multi-tenant, verifica que todo esté funcionando:

1. **Revisa los logs de inicio.** Busca mensajes que confirmen que la infraestructura multi-tenant se inicializó correctamente.

2. **Prueba con un JWT de inquilino.** Envía una solicitud de API (por ejemplo, [listar contextos](/es/reference/matcher/list-contexts)) usando un JWT que contenga un claim `tenant_id`. La solicitud debería ser exitosa y devolver datos para ese inquilino específico.

3. **Verifica el aislamiento.** Realiza la misma llamada de API con JWTs para dos inquilinos diferentes. Confirma que los datos creados bajo un inquilino no son visibles para el otro.

4. **Revisa las métricas** (si la telemetría está habilitada). La métrica `tenant_connections_total` debería incrementarse a medida que se crean nuevos pools de inquilinos.

## Desactivar el modo multi-tenant

***

Para volver al modo single-tenant:

1. Establece `MULTI_TENANT_ENABLED=false` en tu configuración de entorno (o elimina la variable completamente).
2. Reinicia el servicio Matcher.

El servicio operará con una sola base de datos compartida y la identidad del inquilino por defecto se aplicará a todas las solicitudes.

## Consideraciones de despliegue

***

<AccordionGroup>
  <Accordion title="Migración de claves de Redis">
    Al cambiar de modo single-tenant a multi-tenant, las claves de Redis cambian de formato. Las claves con formato antiguo se tratan como cache misses hasta que expire su TTL. Esto se auto-repara y típicamente se resuelve en 1–5 minutos.
  </Accordion>

  <Accordion title="Migración de objetos S3">
    Los objetos existentes creados antes de la activación multi-tenant permanecen en sus rutas originales. Los nuevos objetos obtienen el prefijo de inquilino automáticamente. Si los datos históricos deben ser accesibles por inquilino, puede ser necesario un script de migración único.
  </Accordion>

  <Accordion title="Dimensionamiento de pools de conexiones">
    Planifica el `max_connections` de PostgreSQL basándote en el número máximo de pools de inquilinos multiplicado por las conexiones por pool. Usa `MULTI_TENANT_IDLE_TIMEOUT_SEC` para reclamar pools de inquilinos inactivos.
  </Accordion>

  <Accordion title="Circuit breaker durante interrupciones del servicio de multi-tenancy">
    Mientras el circuit breaker está activo, las solicitudes de nuevos inquilinos fallan rápidamente pero los pools de inquilinos existentes continúan funcionando. Planifica alta disponibilidad del servicio de la plataforma de multi-tenancy en producción.
  </Accordion>
</AccordionGroup>

## Próximos pasos

***

<Card title="Configuración en tiempo de ejecución" icon="sliders" href="/es/matcher/configuration/matcher-systemplane" horizontal>
  Cambia la configuración de Matcher en tiempo de ejecución sin reinicios.
</Card>

<Card title="Guía de instalación" icon="download" href="/es/matcher/getting-started/matcher-installation" horizontal>
  Configura Matcher desde cero.
</Card>

<Card title="Seguridad" icon="shield" href="/es/matcher/reference/matcher-security" horizontal>
  Autenticación, autorización y protección de datos.
</Card>

<Card title="Discovery (Fetcher)" icon="magnifying-glass" href="/es/matcher/integrations/matcher-discovery" horizontal>
  Descubrimiento automático de fuentes a través de Fetcher.
</Card>
