25 August 2024

Multi-tenancy: how we keep your data yours

Every flower shop on Floree is a tenant — a hard-isolated row in our database. Postgres Row-Level Security enforces that no tenant can see another tenant's data, even if our app code has a bug. Here's what that means in practice.

The promise

When you sign up to Floree, your data is yours. Your customer list, your supplier prices, your sales history, your storefront orders, your AI message history. We never see them mingled with another shop's data. We never expose them to another tenant. If we're served a subpoena, we hand over the rows that belong to one tenant; we can't accidentally hand over more.

How it works

Two layers:

  • Tenant scoping in the app code. Every database query includes tenant_id = ? in its filters. We have automated checks that fail CI if a query touches a tenant-scoped table without a tenant filter.
  • Postgres Row-Level Security (RLS). Every tenant-scoped table has policies on it. Even if a query forgets the tenant filter, RLS enforces it at the database level. The query returns rows belonging to the requesting user's tenant, and only those.

This is defence in depth. The app could have a bug and the database wouldn't leak. The database could have a bug and the app code is doing it right.

What we don't do

We don't train shared models on your customer data. We don't aggregate your sales with other shops' sales for benchmarking products without explicit consent. We don't resell your customer email list. The only thing that's aggregated is anonymized analytics for our own product development — a count of "how many shops have set a delivery time", never a specific shop's delivery times.

[Read the full Data Processing Agreement](/legal/dpa).

— Floree.ai · Sharjah, UAE