Skip to content

Data isolation

Every workspace’s data is isolated at the database level, using PostgreSQL row-level security. Membership decides which workspace you can view. It cannot reach another workspace’s data, because the isolation does not depend on the application asking the right question.

The usual way to get this wrong is to filter by workspace in application code. That works until one query forgets, and the query that forgets is never the one anybody reviews.

Keel puts the boundary underneath instead. Tenant-scoped data is read and written inside a transaction that sets the current workspace for the life of that transaction, and row-level security policies on the tables do the filtering. A query that forgets its filter returns nothing rather than returning somebody else’s rows.

  • A user’s membership is the whole story. There is no separate “can this user see this record” check layered on top that could disagree with the database.
  • An API key is scoped to one workspace, and carries no other identity.
  • Removing someone’s membership removes their access immediately — there is no cached view of another workspace to fall out of date.

A Trust Center is public on purpose. Publishing writes a curated snapshot — the sections you chose, as they were when you published — rather than opening a window onto the live workspace. Unpublishing removes it. Nothing else in a workspace is reachable without membership.

Keel can run behind a pooled, edge-cached database connection for latency. That pooling only caches non-transactional reads, and every piece of tenant data flows through the transactional path described above, so a cache layer never sees a row it could hand to the wrong workspace.

  • Team & roles: who inside a workspace can see and change what.
  • Privacy (GDPR): records of processing and the DPIA screener — a different question from tenant isolation, and often asked in the same breath.
  • Trust Center: what publishing does and does not expose.