The browser never talks to the database directly

Every read and write from the app passes through one server route that stamps the account, checks the role, applies each person's lead visibility, restricts which tables exist at all, and audits the result.

What it is

A single proxy is the only path from the browser to the data. It carries an explicit allowlist of tables, separate lists for admin-only reads and admin-only writes, tables the field-worker role cannot read, tables that can only be written through dedicated endpoints, and tables whose rows belong to one user and are filtered to that user automatically. Account scope is resolved server-side from the session — the client never supplies it. Lead visibility scope is applied on reads so a restricted rep only ever sees their own leads.

Also called: data security · can another company see my data · tenant isolation · permissions enforcement · data leak

See it
The browser never talks to the database directly
CustomerBuildingAmountStatus
Ronan PetschBarndominium$3,290Open
Marlin Hoover40×64 Shop$14,120Sent
Marlin HooverBarndominium$6,140Open
Gideon Alt30×40 Garage$1,200Draft
Marlin HooverEquipment Storage$11,650Paid
A gate diagram: browser → one proxy applying allowlist, role, self-scope, lead-scope, audit → database. src/app/api/db/route.ts. Sample data — no customer information appears here.
How it works
  1. 1Resolve the caller, their role and their account server-side from the session
  2. 2Reject any table not on the allowlist outright
  3. 3Apply the read rules: admin-only tables, worker-excluded tables, self-scoped tables filtered to the caller
  4. 4Apply the write rules: admin-only writes, tables writable by every approved role, tables blocked from direct writes entirely
  5. 5Stamp account and user onto every written row and enforce the caller's lead-visibility scope
  6. 6Snapshot rows before update/delete and write the audit entry
  7. 7Sanitise database errors so raw engine text cannot leak schema details
Why we built it

Every builder asks a version of the same question before he puts his customer list into someone else's software: what stops the wrong person seeing it. Trusting each screen to remember the rules is how that eventually goes wrong — one screen forgets, and a rep sees leads that were never his. Every read and write instead goes through a single door that stamps the account, checks the role, applies that person's lead visibility, and refuses to touch anything outside a fixed list of business records. Requests are cleaned so a crafted one cannot smuggle in a join to somewhere it has no business, and errors are scrubbed on the way back, because a raw database error describes the structure it came from.

The problem
  • Client-side database access lets anyone with a session query anything
  • Per-screen permission checks drift as screens are added
  • Restricted reps see leads that are not theirs
Sound familiar?
What you get
One enforcement point instead of a rule repeated in every screen
Role and lead-visibility limits are enforced on the server, not in the UI
Every write is attributed and audited on the way through

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 →