> ## 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

> Execute o Matcher em modo multi-tenant para atender múltiplos clientes com bancos de dados, message brokers, caches e armazenamento isolados.

O modo multi-tenant permite que o Matcher atenda múltiplos clientes com isolamento completo de dados. Cada tenant opera em seu próprio banco de dados, message broker e namespace de cache — garantindo que os dados de um tenant nunca sejam visíveis para outro.

Isso é essencial para deployments SaaS, ambientes regulados ou qualquer cenário onde limites rígidos de dados entre clientes sejam necessários.

## Visão geral

***

Por padrão, o Matcher roda em **modo single-tenant**: todas as requisições compartilham um banco de dados e um conjunto de conexões de infraestrutura. Essa é a configuração mais simples e funciona bem para deployments de um único cliente.

Quando o **modo multi-tenant** é habilitado, cada tenant recebe:

* **Banco de dados isolado** — um banco de dados PostgreSQL dedicado provisionado e gerenciado pelo serviço da plataforma de multi-tenancy
* **Message broker isolado** — um virtual host RabbitMQ dedicado, além de headers `X-Tenant-ID` em cada mensagem como defesa em profundidade
* **Cache isolado** — todas as chaves Redis são automaticamente prefixadas com o identificador do tenant
* **Storage isolado** — objetos S3 são prefixados com o identificador do tenant

A identidade do tenant é determinada a partir do token JWT em cada requisição de API. A claim `tenant_id` no token indica ao Matcher a qual tenant a requisição pertence, e as conexões de infraestrutura corretas são resolvidas automaticamente. A claim legada `tenantId` também é aceita como fallback para compatibilidade com versões anteriores.

## Como ativar

***

### Pré-requisitos

* O **serviço da plataforma de multi-tenancy** deve estar em execução e acessível a partir da rede do Matcher antes de habilitar o modo multi-tenant.
* O Matcher deve estar configurado com autenticação habilitada (`PLUGIN_AUTH_ENABLED=true`), já que a identidade do tenant vem do token JWT.

### Configuração

As configurações multi-tenant são definidas através de variáveis de ambiente, assim como outras configurações do Matcher. Onde você as define depende do seu método de deployment:

* **Docker Compose:** adicione-as a um arquivo `.env` na raiz do projeto ou diretamente no `docker-compose.yml` na seção `environment`
* **Kubernetes / Helm:** adicione-as ao seu arquivo de valores Helm na seção de ambiente apropriada
* **Standalone:** defina-as no ambiente do seu shell ou na configuração do gerenciador de processos

<Note>
  Consulte o [Guia de instalação](/pt/matcher/getting-started/matcher-installation) para detalhes sobre onde os arquivos de ambiente estão localizados no seu deployment.
</Note>

#### Variáveis obrigatórias

Adicione estas à sua configuração de ambiente para habilitar o modo multi-tenant:

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

# URL do endpoint do serviço de multi-tenancy
MULTI_TENANT_URL=https://multi-tenancy.example.com

# Chave de API para autenticar com o serviço de multi-tenancy
MULTI_TENANT_SERVICE_API_KEY=your-api-key
```

#### Ajustes opcionais

Você pode ajustar tamanhos de pool, timeouts e comportamento do circuit breaker:

```env theme={null}
# Número máximo de pools de conexão de tenants simultâneos (padrão: 100)
MULTI_TENANT_MAX_TENANT_POOLS=200

# Segundos antes de um pool de tenant ocioso ser removido (padrão: 300)
MULTI_TENANT_IDLE_TIMEOUT_SEC=600

# Falhas consecutivas do serviço de multi-tenancy antes de o circuit breaker abrir (padrão: 5)
MULTI_TENANT_CIRCUIT_BREAKER_THRESHOLD=3

# Segundos que o circuit breaker permanece aberto antes de tentar novamente (padrão: 30)
MULTI_TENANT_CIRCUIT_BREAKER_TIMEOUT_SEC=60

# Label de ambiente para resolução de tenant com escopo de ambiente (opcional)
MULTI_TENANT_ENVIRONMENT=production
```

Após atualizar a configuração, reinicie o serviço Matcher. Na inicialização, você deve ver mensagens de log confirmando que a infraestrutura multi-tenant foi inicializada.

## Isolamento de tenants

***

### Isolamento de banco de dados

Cada tenant recebe seu próprio banco de dados PostgreSQL. Quando uma requisição chega, o Matcher resolve o tenant a partir do JWT e conecta ao banco de dados dedicado daquele tenant. Se ainda não existir um pool de conexões para aquele tenant, um é criado sob demanda usando configuração do serviço da plataforma de multi-tenancy.

Os pools de conexão são limitados por `MULTI_TENANT_MAX_TENANT_POOLS` e removidos quando ociosos além de `MULTI_TENANT_IDLE_TIMEOUT_SEC`.

### Isolamento do message broker

O isolamento do RabbitMQ usa duas camadas:

* **Virtual host por tenant** — as mensagens de cada tenant são roteadas através de um vhost dedicado, prevenindo qualquer vazamento de mensagens entre tenants
* **Headers de tenant ID** — cada mensagem publicada inclui um header `X-Tenant-ID` como uma camada adicional de segurança para consumidores downstream

Não é necessário criar vhosts manualmente. O serviço da plataforma de multi-tenancy provisiona vhosts automaticamente.

### Isolamento de cache

Todas as chaves Redis são automaticamente prefixadas com o identificador do tenant no formato `tenant:{tenantID}:{key}`. Isso se aplica a verificações de idempotência, deduplicação, rate limiting e cache de credenciais.

### Isolamento de storage

Objetos armazenados em storage compatível com S3 são prefixados com `{tenantID}/`, garantindo que exportações e arquivos de cada tenant sejam separados no nível de armazenamento.

## Gerenciamento de pools de conexão

***

O Matcher mantém um pool de conexões de banco de dados para cada tenant ativo. Estas configurações controlam o uso de recursos:

| Variável                        | Padrão | Descrição                                                                                                                               |
| ------------------------------- | ------ | --------------------------------------------------------------------------------------------------------------------------------------- |
| `MULTI_TENANT_MAX_TENANT_POOLS` | `100`  | Número máximo de pools de tenants mantidos simultaneamente. Quando o limite é atingido, o pool menos recentemente utilizado é removido. |
| `MULTI_TENANT_IDLE_TIMEOUT_SEC` | `300`  | Quanto tempo (em segundos) um pool de tenant não utilizado permanece aberto antes de ser limpo.                                         |

### Planejamento de capacidade

Cada pool de tenant usa até `POSTGRES_MAX_OPEN_CONNS` conexões (padrão: 25). Com 100 pools de tenants, o total no pior caso é 2.500 conexões PostgreSQL. Dimensione o `max_connections` do seu banco de dados adequadamente.

### Verificações de saúde automáticas

O Matcher periodicamente re-verifica a configuração dos tenants (a cada `MULTI_TENANT_CONNECTIONS_CHECK_INTERVAL_SEC`, padrão 30s) para detectar rotação de credenciais ou mudanças nas configurações do pool. Configurações atualizadas são aplicadas sem necessidade de reinicialização.

## Circuit breaker

***

Se o serviço da plataforma de multi-tenancy se tornar inacessível, um circuit breaker protege o Matcher de falhas em cascata.

| Variável                                   | Padrão | Descrição                                                                    |
| ------------------------------------------ | ------ | ---------------------------------------------------------------------------- |
| `MULTI_TENANT_CIRCUIT_BREAKER_THRESHOLD`   | `5`    | Quantas falhas consecutivas antes do circuit breaker ativar.                 |
| `MULTI_TENANT_CIRCUIT_BREAKER_TIMEOUT_SEC` | `30`   | Quanto tempo o breaker permanece ativo antes de permitir uma nova tentativa. |

Enquanto o circuit breaker está ativo, requisições para novos tenants falharão rapidamente. No entanto, **conexões existentes de tenants continuam funcionando normalmente** — apenas o onboarding de novos tenants é afetado.

## Cache de configuração de tenants

***

Para reduzir chamadas ao serviço da plataforma de multi-tenancy, o Matcher armazena em cache as configurações dos tenants em memória.

| Variável                     | Padrão | Descrição                                                                                                                    |
| ---------------------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------- |
| `MULTI_TENANT_CACHE_TTL_SEC` | `120`  | Quanto tempo (em segundos) a configuração do tenant é cacheada antes de ser atualizada a partir do serviço de multi-tenancy. |

Na primeira requisição para um tenant, o Matcher busca a configuração na API do serviço da plataforma de multi-tenancy e a armazena em cache. Requisições subsequentes para o mesmo tenant são servidas a partir do cache até o TTL expirar.

## Todas as variáveis de ambiente

***

### Infraestrutura multi-tenant

<ParamField path="MULTI_TENANT_ENABLED" type="bool" default="false">
  Chave mestra para o modo multi-tenant.
</ParamField>

<ParamField path="MULTI_TENANT_URL" type="string">
  Obrigatório quando o modo multi-tenant está habilitado. URL base do serviço da plataforma de multi-tenancy.
</ParamField>

<ParamField path="MULTI_TENANT_SERVICE_API_KEY" type="string">
  Obrigatório quando o modo multi-tenant está habilitado. Chave de API para autenticação com o serviço de multi-tenancy.
</ParamField>

<ParamField path="MULTI_TENANT_ENVIRONMENT" type="string">
  Label de ambiente para resolução de tenant.
</ParamField>

<ParamField path="MULTI_TENANT_MAX_TENANT_POOLS" type="int" default="100">
  Máximo de pools de conexão de tenants simultâneos.
</ParamField>

<ParamField path="MULTI_TENANT_IDLE_TIMEOUT_SEC" type="int" default="300">
  Segundos antes de um pool de tenant ocioso ser removido.
</ParamField>

<ParamField path="MULTI_TENANT_TIMEOUT" type="int" default="30">
  Timeout HTTP (segundos) para chamadas ao serviço de multi-tenancy.
</ParamField>

<ParamField path="MULTI_TENANT_CIRCUIT_BREAKER_THRESHOLD" type="int" default="5">
  Falhas consecutivas antes do circuit breaker ativar.
</ParamField>

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

<ParamField path="MULTI_TENANT_CACHE_TTL_SEC" type="int" default="120">
  TTL do cache (segundos) para configurações de tenants.
</ParamField>

<ParamField path="MULTI_TENANT_CONNECTIONS_CHECK_INTERVAL_SEC" type="int" default="30">
  Intervalo (segundos) para verificações de saúde dos pools de conexão.
</ParamField>

<ParamField path="MULTI_TENANT_REDIS_HOST" type="string">
  Host Redis para descoberta de tenant orientada a eventos.
</ParamField>

<ParamField path="MULTI_TENANT_REDIS_PORT" type="string" default="6379">
  Porta Redis para descoberta de tenant.
</ParamField>

<ParamField path="MULTI_TENANT_REDIS_PASSWORD" type="string">
  Senha Redis para descoberta de tenant.
</ParamField>

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

### Tenant padrão

<ParamField path="DEFAULT_TENANT_ID" type="string" default="11111111-1111-1111-1111-111111111111">
  UUID do tenant padrão (fallback). Usado no modo single-tenant.
</ParamField>

<ParamField path="DEFAULT_TENANT_SLUG" type="string" default="default">
  Slug do tenant padrão.
</ParamField>

## Verificando o modo multi-tenant

***

Após ativar o modo multi-tenant, verifique se tudo está funcionando:

1. **Verifique os logs de inicialização.** Procure por mensagens confirmando que a infraestrutura multi-tenant foi inicializada com sucesso.

2. **Teste com um JWT de tenant.** Envie uma requisição de API (por exemplo, [listar contextos](/pt/reference/matcher/list-contexts)) usando um JWT que contenha uma claim `tenant_id`. A requisição deve ter sucesso e retornar dados para aquele tenant específico.

3. **Verifique o isolamento.** Faça a mesma chamada de API com JWTs para dois tenants diferentes. Confirme que dados criados sob um tenant não são visíveis para o outro.

4. **Verifique métricas** (se telemetria estiver habilitada). A métrica `tenant_connections_total` deve incrementar conforme novos pools de tenants são criados.

## Desativando o modo multi-tenant

***

Para retornar ao modo single-tenant:

1. Defina `MULTI_TENANT_ENABLED=false` na sua configuração de ambiente (ou remova a variável completamente).
2. Reinicie o serviço Matcher.

O serviço operará com um único banco de dados compartilhado e a identidade do tenant padrão será aplicada a todas as requisições.

## Considerações de deployment

***

<AccordionGroup>
  <Accordion title="Migração de chaves Redis">
    Ao mudar do modo single-tenant para multi-tenant, as chaves Redis mudam de formato. Chaves no formato antigo são tratadas como cache misses até que seu TTL expire. Isso é auto-corrigível e tipicamente se resolve em 1-5 minutos.
  </Accordion>

  <Accordion title="Migração de objetos S3">
    Objetos existentes criados antes da ativação multi-tenant permanecem em seus caminhos originais. Novos objetos recebem o prefixo do tenant automaticamente. Se dados históricos devem ser acessíveis por tenant, um script de migração único pode ser necessário.
  </Accordion>

  <Accordion title="Dimensionamento de pools de conexão">
    Planeje o `max_connections` do seu PostgreSQL baseado no número máximo de pools de tenants multiplicado por conexões por pool. Use `MULTI_TENANT_IDLE_TIMEOUT_SEC` para recuperar pools de tenants inativos.
  </Accordion>

  <Accordion title="Circuit breaker durante indisponibilidade do serviço de multi-tenancy">
    Enquanto o circuit breaker está ativo, requisições de novos tenants falham rapidamente, mas pools de tenants existentes continuam funcionando. Planeje alta disponibilidade do serviço da plataforma de multi-tenancy em produção.
  </Accordion>
</AccordionGroup>

## Próximos passos

***

<Card title="Configuração em tempo de execução" icon="sliders" href="/pt/matcher/configuration/matcher-systemplane" horizontal>
  Altere configurações do Matcher em runtime sem reinicializações.
</Card>

<Card title="Guia de instalação" icon="download" href="/pt/matcher/getting-started/matcher-installation" horizontal>
  Configure o Matcher do zero.
</Card>

<Card title="Segurança" icon="shield" href="/pt/matcher/reference/matcher-security" horizontal>
  Autenticação, autorização e proteção de dados.
</Card>

<Card title="Discovery (Fetcher)" icon="magnifying-glass" href="/pt/matcher/integrations/matcher-discovery" horizontal>
  Descoberta automática de sources através do Fetcher.
</Card>
