Tech USP: Tenant scoping is the default, not opt-in. Every entity is tenant-isolated unless you explicitly mark it cross-tenant. And on the platform side, each app gets its own database credentials — isolation isn’t just a filter clause, it’s enforced at the database layer.
Buyer’s view: One installation hosts any number of customers (or departments, or business units). Each one sees only their own data — automatically, without your engineers writing a single filter clause by hand. And the database itself doesn’t trust the app code: each app logs in with its own credentials, so a bug in App A physically cannot read App B’s data.
Two layers of isolation
Layer 1 — Tenant scoping inside one app.
When you build an internal tool that serves multiple customers (or departments), every record is automatically scoped to “the current tenant”. Your code says db.query("ticket") and the framework adds the tenant filter — you can’t forget it because there’s no way to write the query without it.
Cross-tenant queries are possible — but they have to be explicit. A developer writing db.crossTenant("ticket") is making a deliberate choice; a developer writing the normal query gets the safe default.
Layer 2 — Database isolation between apps. On the hosted platform, each app you run gets its own database with its own login credentials. App A literally doesn’t know how to log in to App B’s database — the credentials are pulled from a vault at boot, scoped per app. No “service-account-with-admin-rights-to-everything” setup.
What this means in failure modes:
- A SQL injection in App A can corrupt App A’s data. It cannot reach App B.
- A misconfigured query in App A returns its own data, never another app’s data — there’s no connection to make.
- A compromised dependency in App A is bounded to App A’s database scope.
Highlights
- Tenant resolution via header, cookie, resolver or default — fits subdomain, path and header-based setups
- Anonymous-access for public endpoints with tenant resolution via host
- Per tenant: own search index, own feature toggles, own configuration
- Per app (on hosted): own database, own credentials, own bucket for files
- Cross-tenant access is explicit, not implicit — the safe default is also the easy default
What you don’t have to do
- Write
WHERE tenant_id = ?in every query — it’s added for you - Manage per-app database users by hand — the platform provisions them
- Build a “tenant context” middleware — there’s already one, tested
- Audit cross-tenant queries to make sure no one forgot the filter — there’s nothing to forget
Architecture deep dive
tenant-db-context—ctx.dbscoping, cross-tenant escalationpermissions— roles + ownership filterscaling— multi-tenant scaling (DB-shared vs DB-per-tenant)
Where this lands in the pitch
- EU mid-market: “Multi-tenant by default — your departments don’t see each other’s data, and the database itself enforces it”
- Indie hackers: “Multi-tenant scoping is the #1 bug source in B2B SaaS. We removed the opportunity for that bug”
- Compliance / security review: Two layers (app-level filter + database-level credentials) means a single-line bug doesn’t become a data breach