One company cannot reach another's data.
The separation between companies is applied by the database on every single query, not by the application remembering to ask correctly.
The usual arrangement.
Most multi-tenant software filters by company in application code. That works right up until one query somewhere forgets its filter, and the failure is silent: the data was always reachable, it just was not asked for.
What is actually there.
Every table, without exception
All 127 tables have row-level security enabled, verified by listing the live database rather than by reading a policy document.
Permission belongs to the person in that company
The same person can be a full administrator of one carrier and read-only in another. Capabilities are evaluated for the company they are working in, not attached to the person.
Eleven role templates, thirty-nine permissions
The money desk is split on purpose: the clerk who enters an invoice or a carrier bill is not automatically the person who can approve, void or pay it.
A history that would show tampering
Tracked changes are written by the database itself, recording who, when, and the value before and after, with each entry sealed to the one before it.
What it means on a Tuesday.
A holding group runs several carriers on one system. A dispatcher at one of them opens a load list and sees their own company's loads, because the other company's rows are not reachable from that session at all. If a developer wrote a query that forgot to filter, it would return nothing rather than everything.
Where this claim stops.
Not every screen is permission-gated, and that is a documented decision rather than an oversight. Money and privileged screens are gated; operational screens are open to any signed-in member of the company. Their rows are still company-scoped by the database and their writes are still permission-checked on the server, but telling the system that a particular dispatcher may not open Customers at all is not yet possible.