Products / SaaS / Backend Infrastructure

Live

TenantScope

Multi-tenant Postgres: orgs, memberships, orgId-scoped queries

Users, organizations, memberships (owner/admin/member), invite stubs, JWT starter auth, and middleware that resolves tenant then scopes every Notes query by orgId.

Value

Problem. B2B SaaS needs organizations and memberships. Without a trusted tenant resolve + orgId filter, Customer A can see Customer B’s rows.

How it helps. Users, organizations, memberships (owner/admin/member), invite stubs, JWT starter auth, and middleware that resolves tenant then scopes every Notes query by orgId.

Why buy. Ship the multi-tenant membership spine most starters skip — without bolting on a full IdP or billing product.

How it works

flowchart LR
  User[User] -->|membership| Membership
  Membership -->|role: owner/admin/member| Org[Organization]
  Org --> Notes[Notes / resources]
  Request[HTTP request] -->|JWT| Auth[requireAuth]
  Auth -->|X-Tenant-Id / slug| Tenant[requireTenant]
  Tenant -->|membership check| Scoped[orgId-scoped queries]
  Scoped --> Notes

Mermaid flowchart (render in GitHub / VS Code / mermaid.live).

Use case

Alice creates Org A, Bob is in Org B; Alice’s JWT + X-Tenant-Id for Org A lists only Org A notes — Bob’s token cannot read Alice’s rows.

What you get

Project structure

tenantscope/
  src/
    middleware/   auth, tenant
    routes/       auth, orgs, notes, health
    services/     auth, orgs, notes
    lib/          config, prisma, slug, logger
  prisma/         schema + migrations
  tests/          auth, tenant, slug
  docker-compose.yml

Quick start

docker compose up -d
cp .env.example .env  # JWT_SECRET ≥ 32 chars
npm install && npm run prisma:generate && npm run prisma:migrate
npm run dev

Example

From src/middleware/tenant.ts

// Resolve tenant from trusted header/slug, verify membership, then:
// always query with orgId from req.tenant — never from unchecked body fields.
const notes = await prisma.note.findMany({
  where: { orgId: req.tenant.orgId },
});

Tested

17 Vitest tests — password hashing, register/login, slug helpers, and cross-tenant note access rejection.

npm test

2026-09-20 — 17 passed; npm run build OK

Design decisions

Limitations

Who it’s for

Indie founders building B2B multi-tenant APIs on Postgres + TypeScript.

Not for: Teams that need an all-in-one auth/billing platform or RLS-only Postgres policies out of the box.

What you own

Full MIT-licensed TypeScript source via Gumroad ZIP. Fork it, ship it commercially, keep the license notice. You are responsible for secrets, hardening, and production ops.

Related

HookQueue · RateGuard · IdemKey · CronLock

Demo

TenantScope demo
Live Postgres demo — alice@acme note visible; bob with X-Tenant-Id=acme → 403 not_a_member; bob@beta sees empty list.
Buy TenantScope — $25 All products