Tenant isolation on every public portal route

Every unauthenticated portal endpoint resolves its tenant from the link itself and refuses to serve when it cannot, instead of falling back to a default org.

What it is

A consistent rule across the public portal APIs: the link's own org id is the authority for everything read downstream, queries re-stamp that org id even though the service client bypasses row-level security, and a link with no tenant binding is refused rather than served.

Also called: another builder's data showed up · multi tenant safety · data leak

See it, piece by piece
02

Every read is re-stamped with the account the link belongs to

The link's own account is the authority for the project, the invoices, the change orders and the branding, and each query re-applies it even though the server key could reach past the database's own isolation rules. Defence in depth, because a project identifier that collides across two builders should be a nothing event rather than a disclosure.

04

Public endpoints carry a budget sized to a real customer

The link is the credential and there is no login to throttle against, so every public action gets a per-address request budget: about sixty reads a minute on the billing lists, far fewer on sign-in and approval attempts. Sized so a customer refreshing their dashboard never notices, and a script hammering a leaked link does.

How it works
  1. 1The project endpoint refuses with an error when the link has no org id
  2. 2The config endpoint requires either a link id or a signed-in user and 400s otherwise
  3. 3The change-orders query re-applies the link's org id as defence in depth
  4. 4Passworded links additionally require a valid session token on the project feed
Why we built it

Two public routes fell back to one particular company's account whenever they could not work out whose portal was being requested, so an unauthenticated request could return another builder's branding and copy, and an unrelated settings screen could render it too. Both refuse now rather than guessing. Every public portal route resolves the account from the link and serves nothing at all if it cannot, because a customer seeing another company's name on their own project is not something a builder gets to explain away.

The problem
  • Default-tenant fallbacks silently serving one builder's data to another
  • Public endpoints readable without any tenant binding
  • Build progress on a passworded link readable from the link id alone
Sound familiar?
What you get
A misconfigured link fails loudly rather than leaking
Tenant scope is enforced at every public read
Password protection extends to the project data feed, not just the page
What's inside

See it on your own jobs

Twenty minutes, your numbers, no slide deck. We’ll build one of your real buildings in front of you and send you the estimate link at the end — yours to keep either way.

or keep browsing features →