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

# Multi-tenant configuration

> Configure Matcher for tenant-aware authentication and tenant-specific PostgreSQL pools.

For supported multi-tenant requests, Matcher first derives tenant context from the authorized JWT and then uses it to resolve tenant-specific PostgreSQL infrastructure through Tenant Manager. It is a deployment mode, not a runtime toggle: validate it in a non-production environment before enabling it for a shared installation.

## Requirements

***

Before enabling multi-tenant mode:

* Set `MULTI_TENANT_ENABLED=true` and `PLUGIN_AUTH_ENABLED=true`. Matcher rejects multi-tenant startup without authorization enforcement.
* Use `AUTH_PROVIDER=plugin-auth`. The current `workos` provider resolves verified requests to the default tenant and is not supported for tenant selection.
* Set `MULTI_TENANT_URL` to an origin-only HTTPS URL in staging and production, plus a non-empty `MULTI_TENANT_SERVICE_API_KEY`. `MULTI_TENANT_ENVIRONMENT` is optional and falls back to `ENV_NAME` when unset. Plaintext `http` is allowed for local development; in other environments it also requires an explicit `MULTI_TENANT_ALLOW_INSECURE_HTTP=true`.
* Set `ENVIRONMENT_NAME` (or `ENV_NAME`) to `staging` or `production`.
* Provide a valid `tenant_id` or `tenantId` claim in requests authenticated through `plugin-auth`.
* Keep the default tenant database available on the root pool for default-tenant workloads and operational tools.

Matcher resolves dedicated PostgreSQL pools for non-default tenants; the default tenant uses the root pool. It does not switch tenant schemas through PostgreSQL `SET search_path`; tenant-specific credentials, network boundaries, and Tenant Manager configuration remain part of the isolation boundary.

## Tenant identity

***

With `AUTH_PROVIDER=plugin-auth` in multi-tenant mode, Matcher derives tenant identity from a valid `tenant_id` or `tenantId` JWT claim. It does not accept a caller-controlled tenant selector from request bodies, query parameters, or arbitrary headers. `workos`, single-tenant, and authentication-disabled deployments use the configured default tenant.

## Connection-pool controls

***

| Control                                  | Scope                             | Effect                                                                                                                                                                                                                                                                                                                                        |
| ---------------------------------------- | --------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `MULTI_TENANT_MAX_OPEN_CONNS_PER_TENANT` | Bootstrap environment             | Per-tenant PostgreSQL open-connection default and hard ceiling. It defaults to `0`; when both connection-limit variables are `0`, lib-commons uses 25 open / 5 idle defaults and 200 open / 50 idle ceilings. It is independent of the root pool's `POSTGRES_MAX_*` settings. Change it through deployment configuration and restart Matcher. |
| `MULTI_TENANT_MAX_IDLE_CONNS_PER_TENANT` | Bootstrap environment             | Companion idle-connection default and hard ceiling; it shares the `0` fallback behavior above. Change it through deployment configuration and restart Matcher.                                                                                                                                                                                |
| `MULTI_TENANT_MAX_TENANT_POOLS`          | Systemplane runtime configuration | Maximum number of tenant pools Matcher may keep open; the default is `100` and the value must be positive.                                                                                                                                                                                                                                    |
| `MULTI_TENANT_IDLE_TIMEOUT_SEC`          | Systemplane runtime configuration | Idle-pool timeout used by the tenant-pool manager; the default is `300` seconds and the value must be positive. The new value applies through Systemplane without a restart.                                                                                                                                                                  |

At the configured limits, Matcher's tenant-pool manager evicts an idle least-recently-used pool when resolving a new tenant would exceed `MULTI_TENANT_MAX_TENANT_POOLS`; the evicted tenant is re-resolved on demand. Validate migration and failure behavior against the deployed Tenant Manager integration.

## Shared infrastructure

***

Matcher delegates tenant-aware infrastructure resolution to the multi-tenancy platform service. Do not assume a fixed RabbitMQ virtual-host name, message-header convention, Redis key format, cache TTL, or S3 prefix from Matcher alone. Those conventions are component- and deployment-specific; review the corresponding infrastructure and platform documentation before building an integration around them.

## Enabling the mode

***

1. Provision and verify the default tenant and the tenants that Matcher must serve.
2. Configure the authentication provider, Tenant Manager, PostgreSQL connectivity, and bootstrap environment variables.
3. Start Matcher and confirm the health checks and a tenant-scoped authenticated request.
4. Observe the tenant-pool count and database connection use under expected load.
5. Roll out the deployment only after isolation and failure behavior have been exercised in the target environment.

<Warning>Changing tenant topology, database credentials, or per-pool PostgreSQL connection limits is an infrastructure change. Apply it through the deployment process; Systemplane cannot change those bootstrap values without a restart.</Warning>

## Next steps

***

<Card title="Runtime configuration" icon="sliders" href="/en/matcher/configuration/matcher-systemplane" horizontal>
  Review the values that Matcher can change through Systemplane.
</Card>

<Card title="Security" icon="shield-halved" href="/en/matcher/reference/matcher-security" horizontal>
  Review authentication, tenant isolation, and dependency TLS controls.
</Card>
