https://github.com/quarkiverse/quarkus-multitenancy
A fully decoupled Quarkus extension providing a generic tenant resolution API and request-scoped TenantContext, with pluggable resolvers for HTTP, JWT, cookies
https://github.com/quarkiverse/quarkus-multitenancy
java microservices multitenancy quarkiverse quarkus-extension tenant-resolution
Last synced: about 1 month ago
JSON representation
A fully decoupled Quarkus extension providing a generic tenant resolution API and request-scoped TenantContext, with pluggable resolvers for HTTP, JWT, cookies
- Host: GitHub
- URL: https://github.com/quarkiverse/quarkus-multitenancy
- Owner: quarkiverse
- License: apache-2.0
- Created: 2026-06-01T10:46:26.000Z (about 1 month ago)
- Default Branch: main
- Last Pushed: 2026-06-05T04:49:01.000Z (about 1 month ago)
- Last Synced: 2026-06-06T15:24:43.656Z (about 1 month ago)
- Topics: java, microservices, multitenancy, quarkiverse, quarkus-extension, tenant-resolution
- Language: Java
- Homepage: https://docs.quarkiverse.io/quarkus-multitenancy/dev
- Size: 316 KB
- Stars: 5
- Watchers: 0
- Forks: 1
- Open Issues: 7
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- Contributing: .github/CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
README
# ๐งฉ Quarkus Multitenancy Extension
[](https://github.com/quarkiverse/quarkus-multitenancy/actions/workflows/build.yml)
[](https://docs.quarkiverse.io/quarkus-multitenancy/dev/)
[](LICENSE)



> A modular, decoupled multitenancy extension for Quarkus
> supporting HTTP tenant resolution, ORM integration, and future integrations.
Quarkus Multitenancy is a Quarkiverse extension that provides a generic tenant resolution API and reusable building blocks for Quarkus applications.
It abstracts tenant identification logic away from any specific technology and exposes a consistent `TenantContext` that can be injected by application code or reused by integrations such as HTTP and ORM.
## Why this exists
- Quarkus already provides powerful building blocks such as OIDC multitenancy and Hibernate ORM multitenancy.
- Applications still often need a consistent way to resolve and propagate the current tenant.
- This extension provides a reusable tenant resolution layer across HTTP, ORM, and custom integrations.
- It is now maintained as a Quarkiverse extension.
---
๐ก Designed for REST microservices and backend modules, it can provide tenant resolution for HTTP requests, persistence, cache, messaging, or custom application layers.
## ๐ About This Project
**Quarkus Multitenancy** is an extension designed to standardize and simplify tenant resolution for Quarkus services. It provides a decoupled multi-layer architecture.
- A core runtime module that defines `TenantResolver`, `TenantContext`, and tenant resolution contracts.
- Independent HTTP, ORM, and deployment layers built on top of the core.
- Built-in support for tenant resolution from headers, cookies, JWT claims, and request paths.
This makes the extension modular, lightweight, and framework-friendly, so you can plug tenant resolution into HTTP requests, ORM integrations, or custom application code.
- Consistent tenant identification per request
- Pluggable resolvers: header, cookie, JWT claim, path, and custom resolvers
- Minimal boilerplate code
- Integration point for datasources, caches, identity providers, and other tenant-aware components
- Quarkiverse migration completed
- First preview release preparation in progress
---
## ๐ Modules
| Module | Description | Docs |
|--------|-------------|------|
| ๐ง **Core Runtime** | Defines `TenantContext`, `TenantResolver`, and tenant resolution contracts | [Read more โ](quarkus-multitenancy-core-runtime/README.md) |
| โ๏ธ **Core Deployment** | Build-time Quarkus integration for core | [Read more โ](quarkus-multitenancy-core-deployment/README.md) |
| ๐ **HTTP Runtime** | Resolves tenants from header, cookie, JWT claim, or path | [Read more โ](quarkus-multitenancy-http-runtime/README.md) |
| ๐งฉ **HTTP Deployment** | Registers HTTP tenant resolution support | [Read more โ](quarkus-multitenancy-http-deployment/README.md) |
| ๐งฑ **ORM Runtime** | Integrates tenant context with Hibernate ORM multitenancy use cases | [Read more โ](quarkus-multitenancy-orm-runtime/README.md) |
| โ๏ธ **ORM Deployment** | Quarkus feature registration for ORM integration | [Read more โ](quarkus-multitenancy-orm-deployment/README.md) |
| ๐งช **Demo App** | PostgreSQL multi-tenant REST demo | [Read more โ](quarkus-multitenancy-demo/README.md) |
---
# ๐ง Quarkus Multitenancy Core Runtime
The **core foundation** of the Quarkus Multitenancy extension.
It defines the base APIs used to resolve and propagate tenants across layers, from HTTP requests to ORM and custom application code.
---
## ๐ What It Does
This module provides:
- The **`TenantContext`** โ a request-scoped CDI bean exposing the active tenant.
- The **`TenantResolver`** โ an interface for resolving tenant identifiers dynamically.
- The **`TenantResolution`** contract โ a three-state result model: `Resolved`, `NotApplicable`, and `Rejected`.
- The **`CompositeTenantResolver`** โ allows multiple resolvers such as header, JWT, cookie, or path to cooperate.
---
## ๐งฉ Tenant-Aware Isolation
Using this module together with the HTTP and ORM runtimes, each incoming request can be associated with a resolved tenant identifier.
โ
Each request can carry a tenant identifier, for example `X-Tenant: tenant1`.
โ
The active tenant is exposed through `TenantContext`.
โ
The ORM runtime can use the resolved tenant to route persistence operations.
โ
Actual database isolation depends on how the application configures Hibernate ORM, datasources, schemas, or databases.
For example:
| Request | Header | Tenant Resolved |
|----------|---------|----------------|
| `GET /api/users` | `X-Tenant: tenant1` | `tenant1` |
| `GET /api/users` | `X-Tenant: tenant2` | `tenant2` |
This means the extension provides the tenant resolution layer. The application remains responsible for configuring the actual persistence isolation model.
---
## โ๏ธ Required Dependencies
To enable HTTP tenant resolution:
```xml
io.quarkiverse.multitenancy
quarkus-multitenancy-http
${quarkus-multitenancy.version}
```
To enable ORM integration:
```xml
io.quarkiverse.multitenancy
quarkus-multitenancy-orm
${quarkus-multitenancy.version}
```
Replace `${quarkus-multitenancy.version}` with the latest released version once the first preview release is published.
---
## ๐ก Example Usage
```java
import io.quarkiverse.multitenancy.core.runtime.context.TenantContext;
import jakarta.inject.Inject;
import jakarta.ws.rs.GET;
import jakarta.ws.rs.Path;
@Path("/tenant")
public class TenantResource {
@Inject
TenantContext tenantContext;
@GET
public String getTenant() {
return tenantContext.getTenantId().orElse("NO TENANT FOUND");
}
}
```
When you send:
```bash
curl -H "X-Tenant: tenant1" http://localhost:8080/tenant
```
Output:
```text
tenant1
```
| Layer | Module | Responsibility |
|------|--------|----------------|
| **HTTP Runtime** | `quarkus-multitenancy-http` | Resolves tenant per HTTP request |
| **ORM Runtime** | `quarkus-multitenancy-orm` | Connects ORM layer to tenant context |
Together, they provide tenant-aware request handling and persistence integration in Quarkus.
---
## ๐ JWT Tenant Resolution
The JWT strategy resolves the tenant from a claim in a **verified bearer token**.
Applications must configure SmallRye JWT or Quarkus OIDC before enabling the `jwt` strategy.
Example:
```properties
quarkus.multi-tenant.http.strategy=jwt
quarkus.multi-tenant.http.jwt-claim-name=tenant
mp.jwt.verify.publickey.location=publicKey.pem
mp.jwt.verify.publickey.algorithm=RS256
mp.jwt.verify.issuer=https://my-issuer.example.com
```
OIDC can also be used as the verification source:
```properties
quarkus.oidc.auth-server-url=https://issuer.example.com
```
Named OIDC tenants are also supported:
```properties
quarkus.oidc.customer.auth-server-url=https://customer-issuer.example.com
```
If a bearer token is present but cannot be verified, or if the configured tenant claim is missing, non-string, or blank, the request is rejected with HTTP 401 and does not fall back to the default tenant.
---
## ๐ฆ Resolution Outcomes
Tenant resolution uses a three-state result contract:
| Outcome | Meaning |
|---------|---------|
| `Resolved` | A resolver successfully resolved a tenant identifier |
| `NotApplicable` | The resolver had no input to process, so the next strategy may be tried |
| `Rejected` | The resolver found invalid input and the request must be rejected |
This distinction is important for security.
For example, a missing bearer token can be `NotApplicable`, but a malformed or unverifiable bearer token is `Rejected` and must not silently fall back to `defaultTenant`.
---
## ๐ Quick Start
```bash
mvn clean install
cd quarkus-multitenancy-demo
mvn quarkus:dev
```
To test the demo, import the `demo.postman_collection.json` file into Postman.
---
## ๐งญ Architecture Overview
```text
[HTTP Request]
โ
[HTTP TenantResolver] (header/JWT/cookie/path)
โ
[TenantContext] (request-scoped)
โ
[ORM / Application / Custom Integration]
```
๐ See the `quarkus-multitenancy-demo` README for full setup with Docker, PostgreSQL, Postman, and sample tenants.
---
## ๐ Documentation
Full documentation is available at:
```text
https://docs.quarkiverse.io/quarkus-multitenancy/dev/
```
---
## ๐ License
This project is licensed under the Apache License 2.0.