Most multi-tenant software keeps companies apart with a WHERE clause and good intentions. One forgotten filter in one query and a competitor sees your customer list. Scanified pushes the boundary down into the database, where forgetting is not possible.
Every tenant table has RLS enabled with FORCE, so the policy applies to the table owner too. There is no privileged path that skips it.
The application connects as a role created without BYPASSRLS and without schema rights. Even a full SQL injection cannot read another company’s rows, because the role is not permitted to.
The tenant is set inside the transaction and cleared with it. A connection returned to the pool carries nothing from the request before it.
Every table that holds customer data carries an organisation column and a policy that compares it to a value set on the connection at the start of each request. The policy is declared FORCE ROW LEVEL SECURITY, which is the part most implementations miss: without it, the role that owns the table is exempt from its own rules.
The application does not connect as an administrator. It uses a dedicated role created without BYPASSRLS, without CREATEDB, and without rights to alter schema. This is deliberate and it is the reason the guarantee holds: an attacker who achieves arbitrary SQL execution through the application still cannot read a row belonging to another company, because the role executing the query has never been permitted to.
This holds by construction, not by promise. Row-level security isFORCEd on every tenant table, so it binds even the table’s owner, and the application role has never been granted the right to bypass it — the refusal comes from the database, not from application code remembering to check. An automated two-organisation crossing suite is listed below with the other things we have not done yet, because a test we have not written is not something we will describe as if we run it.
Sign-in is handled by Supabase Auth. Passwords are hashed with bcrypt there; our application hands a password to Supabase when you sign up or sign in and never stores it. Sessions are carried in SameSite cookies, and the site is served over HTTPS only, with HSTS. Those cookies are not httpOnly: the sign-in library refreshes the session from the page, so the page can read them. What stands between a session and a hostile script is a Content-Security-Policy that limits where scripts may load from.
Permissions are read from the database on every request rather than trusted from the token. Deactivating a user takes effect on their next action, not whenever their token happens to expire.
The mobile apps hold a token in the operating system’s secure storage — Keychain on iOS, EncryptedSharedPreferences on Android — and present it as a bearer token. That token is validated against the auth server on every call. No shared secret and no service key is ever shipped to a device.
Four roles: owner, admin, manager and user. A driver can scan, and can look up your customers and cylinders, because finding the right account at a loading dock is the job. A manager can verify orders and settle discrepancies. Administrative actions — pricing, team, deleting anything — require admin or owner. Role is checked on the server for every action, not hidden in the interface, so a modified client gets a refusal rather than a result.
Invitations are single-use tokens tied to one email address and one organisation. Creating an account without an invitation or a company name gets you an account with no company attached, which can see nothing at all.
A scan that was wrong is voided, not erased, and a correction is a new entry that references the entry it corrects; both remain. Undoing a verification does remove the rentals that verification opened, and the undo is itself written to the audit trail with who did it and when. The audit trail is kept for the life of your account and you can export it whenever you like, so a dispute in November can still be settled with the record from March. The one thing that can be removed outright is the sample data you load to try the product.
Every scan carries who submitted it, when the device recorded it, when the server received it, and — where the device allows it — where. Duplicate submissions are recognised and discarded, so a replayed offline batch cannot inflate a bill.
Data is stored in Postgres on Supabase, encrypted at rest. Traffic is TLS 1.2 or better, end to end. The web application runs on Netlify. Secrets live in the platform’s encrypted environment store and are not present in the repository. The full list of who else touches your data, and what each one sees, is at /legal/subprocessors.
Scanified is a young product and it would be easy to imply more than is true, so plainly: we do not hold a SOC 2 report, we have not commissioned a third-party penetration test, we do not yet offer single sign-on, and we have not yet automated the two-organisation isolation test described above — the policies are live; the suite that proves them on every build is still on the list. The database is backed up every day by our database host and each backup is kept for seven days. We have not yet completed a restore drill, so we are not calling backups solved until we have; your whole account also exports from Settings at any time. The mobile app’s on-device token encryption is written and tested but has not finished rolling out to every installed copy of the app yet. We are not going to put badges on this page that we have not earned.
What we can offer today is a description precise enough to be checked, an isolation model that fails closed, and a straight answer to any question your IT team wants to send.
Email hello@scanified.com. Tell us what you found and how to reproduce it. We will confirm receipt within two business days, and we will not pursue anyone who reports a genuine issue in good faith and gives us a reasonable window to fix it before telling anyone else — 90 days is reasonable unless we ask you for more, and we will tell you why if we do.
In scope: scanified.com, the Scanified mobile app, and the API behind both. Out of scope: social engineering against our team, physical access, and anything that disrupts the service for other people — a proof of concept against your own test account is worth more to us than a load test against production.
If your IT team has a security review form, we will fill it in properly rather than leaving it to a salesperson.
hello@scanified.com