Umbral
Back to plugin directory
UT

Umbral Tenants

Official by Umbral contributors

schema/shared-table tenancy, request resolution, membership

official beta

About

Turn one app into a multi-tenant SaaS without forking it per customer. Umbral Tenants routes each tenant to its own Postgres schema (or scopes them by a tenant column), resolves the active tenant from the request, and binds it to the caller through a membership check so nobody reads across the wall. Pick the isolation strategy that fits — a schema per tenant for hard separation, a shared table for density — and the framework handles the routing.

Install

cargo add umbral-tenants

Wire it up

Choose which apps are tenant-scoped, the isolation strategy, and how the tenant is identified.

use umbral::prelude::*;
use umbral_tenants::{TenantsPlugin, TenantStrategy};

let app = App::builder()
    .database("default", pool)
    .plugin(
        TenantsPlugin::new()
            .strategy(TenantStrategy::Schema)   // one DB, a schema per tenant
            .tenant_apps(["billing", "projects"])
            .tenant_header("X-Tenant"),
    )
    .build()?;

Target: hard isolation with a safety net

Run TenantStrategy::Schema for separation and layer umbral-rls underneath, so the database enforces the tenant boundary even if request routing has a bug.

What you get

  • Schema-per-tenant or row-per-tenant (shared column) strategies
  • Tenant resolved from the request (header or your own resolver)
  • Membership binding so a caller can't read another tenant's data
  • Choose which apps are tenant-scoped and which stay shared
  • Pairs with umbral-rls for database-enforced defence in depth

Usage

On `TenantsPlugin::new()` pick a `.strategy(...)` (schema-per-tenant or shared-column), list the `.tenant_apps([...])` that are scoped, and set how the tenant is resolved (`.tenant_header(...)` or a membership guard). Layer umbral-rls for database-enforced isolation.

plugin setup
cargo add umbral-tenants

Feature tracker

Per-feature shipping status, recorded in the directory.

6 of 6 shipped
Schema-per-tenant strategy usable Beta

Route tenant-scoped apps into isolated Postgres schemas.

Shared-column strategy usable Beta

Scope rows by tenant key when density matters more than schemas.

Tenant resolution usable Beta

Resolve tenants from headers, subdomains, or custom policy.

Membership guard usable Beta

Bind resolved tenants to callers through a membership check.

Scoped app lists usable Beta

Choose tenant-scoped apps and shared apps explicitly.

Current tenant context usable Beta

Handlers can read the active tenant from request-local context.

Compatibility

Declared support per Umbral version and database backend.

No compatibility rows declared yet.

Community notes

0 notes in the discussion thread.

No notes yet. Be the first to share how this plugin works for you.

Reported issues

Bugs and abuse reports filed against this plugin.

Report an issue

No open issues

No issues have been reported against this plugin. Track upstream bugs on the maintainer's tracker, or report a directory problem to the Umbral team.