rent
Concepts

Multi-tenancy

Drag to pan · scroll or pinch to zoom · use the controls to reset or open fullscreen

A request-scoped client carries the authenticated viewer. Generated tenant metadata adds the tenant predicate to reads and writes before SQL is rendered.

let client = base_client
    .clone()
    .with_viewer(Viewer::tenant(tenant_id).user(user_id));

let projects = client.project().status_eq("active").all().await?;

The application query says only "active projects." Rent supplies tenant_id = current_tenant, including create, bulk create, update, and delete operations. A scoped create fills tenant_id automatically and rejects an explicit conflicting tenant. Viewer::administrator() is the explicit cross-tenant escape hatch.

PostgreSQL RLS can provide an additional database-enforced boundary; Rent's migration catalog tracks RLS enablement and policies.

The executable tenancy example also tests cross-tenant reads, updates, deletes, transaction-bound clients, and a missing-viewer denial.