Adr
ADR 0004 — Workspace-scoped RLS with security-definer helpers
How multi-tenant isolation is enforced in the database.
- Status: Accepted
- Date: 2026-07-13
Context
Kredal is multi-tenant: consultants manage many client companies, and no tenant may ever see
another's data. Enforcing this only in application code is fragile. Naive RLS policies that
query workspace_members recurse into that table's own RLS.
Decision
Enable RLS on every table and centralise the membership check in SECURITY DEFINER helper
functions: is_workspace_member (reads), is_workspace_writer (owner/admin/member writes),
is_workspace_admin (deletes and member management). Storage policies check membership on the
first path segment. audit_events is insert-only (no update/delete policy).
Consequences
- Positive: database-enforced tenancy that application bugs cannot bypass; no policy recursion; a clear four-role permission model.
- Negative: security-definer functions must be written carefully (fixed
search_path). Documented in the security model and verified by the Verify RLS runbook.