Skip to content
diviteb

Guide · 7 chapters

Multi-tenant SaaS, end to end

Postgres RLS, RBAC, metered billing, and a SOC 2-ready audit trail — wired in before the first tenant signs.

Chapter 01

Why multi-tenant

Multi-tenant scales sublinearly with customer count — one stack, many tenants. Single-tenant scales with each customer. The trade-offs are economic, regulatory, and operational, and they should be picked deliberately, not by accident. This guide walks the multi-tenant pattern we ship every time.

Chapter 02

Tenant isolation in Postgres RLS

We enforce tenant isolation at the database, not the application. Every tenanted table has a tenant_id column NOT NULL. Every connection sets a current_tenant() session variable on connect. Every table has an RLS policy that filters by current_tenant() = tenant_id.

  • Connection middleware sets current_tenant() on every connection.
  • Policies are CREATE POLICY, not table grants — auditors see them in pg_policies.
  • We test the RLS policies with a deny-by-default test for every table.
  • Admin queries use a separate database role that bypasses RLS — gated by IAM.

Chapter 03

RBAC — roles inside the tenant

Inside a tenant, you need a roles model. We default to three roles (owner, member, billing) with the ability to add custom roles. Permissions are checked in the application layer for UX, then re-checked at the database via RLS for safety.

Chapter 04

Metered billing with Stripe

Usage-based billing is wired into the business logic, not patched in later with a webhook. We meter the actions that matter (API calls, seats, storage) at the source — emit events to Stripe in batches, reconcile nightly. Billing failures alert engineering, not just finance.

Chapter 05

Audit logs the way SOC 2 expects them

Append-only log of every action, with actor, target, and changeset. Stored separately from the operational database so a tenant compromise doesn't taint the audit trail. Retained for the period the contract requires.

Chapter 06

Provisioning a new tenant

Self-serve where possible, sales-assisted for enterprise. The provisioning flow creates the tenant record, seeds default config, sends the welcome email, and emits an analytics event — all in one transaction.

Chapter 07

Handling tenant data export and deletion

GDPR and SOC 2 both require this. We model tenant export as a long-running job, with progress visible to the customer. Deletion is soft-delete with a 30-day window, then hard-delete with audit. Export and deletion both produce a signed PDF receipt.

Run this with your team

Book the workshop version.

A half-day workshop with your team — same content, your codebase. We tailor the chapters to where your team is today.