Tenant isolation by default: how the kit scopes every query
Every tenant-facing query is scoped to the current account, client-supplied account ids are rejected, and e2e tests prove it.
Multi-tenancy fails quietly. A missing where-clause does not throw — it leaks. The kit treats isolation as a default, not a convention.
One rule, enforced everywhere
Every tenant-facing query includes the current account id taken from the session, never from the request body. A client-supplied account id in a tenant action is ignored or rejected. The only code paths that may read across accounts are the system admin routes, which live in a separate route scope with their own guard.
Deny by default
Roles are a table, not a vibe. Owner, admin, and member each have an explicit allow list; anything outside the table is denied. Admins can switch roles between member and admin only — owner stays protected, and every role change lands in the audit log.
Tests that try to break it
The e2e suite signs in as tenant A and attempts to read tenant B's projects, users, and access keys. API tests send malicious account-id payloads on purpose. The suite fails the build if any of it succeeds. Isolation you cannot test is isolation you do not have.
Where to look
The schema and tenant helpers live in packages/db, the role policies in packages/rbac, and the evidence — env matrix, test commands, source map — is contained in the admin Developer surface, never on tenant screens.