Access is enforced where the data lives
Interface role-awareness is a usability feature. Authorization is enforced in the database and in server-side checks, so a manipulated client cannot reach records it is not entitled to.
Row-level security on every exposed table
Policies bind reads and writes to tenant, membership, role, fund, offering, and investor scope. Roles are stored in a dedicated table, never in user-editable metadata.
Server-side authorization
Privileged operations run in server functions that re-verify the caller's identity and role. Service credentials never reach the browser.
Private document storage
Documents and Deal Rooms are stored privately with per-object policies. Access is granted by entitlement and logged; there are no public document URLs.
Append-only evidence
Investor admission, subscriptions, capital calls, ownership changes, distributions, payments, signatures, publication, and provider calls each write an immutable evidence record.
Fail-closed external effects
Effects require an execution manifest, bound identity and scope, pre-effect admission, and idempotency. If admission is unavailable in production, the effect is blocked rather than attempted.
Honest integration status
Unconfigured or unreachable providers report UNCONFIGURED, BLOCKED, or DISCONNECTED. No integration is displayed as healthy without a live check.
Authentication
Sign-in supports email verification, password reset, multi-factor authentication, and invite-based provisioning. Sessions expire and can be revoked. Administrators can review memberships and roles per organisation.
Data segregation
Every canonical record carries a tenant binding. Cross-tenant reads are denied by policy, and that denial is covered by tests rather than assumed.
Change management
Schema changes ship as reproducible, committed migrations. Generated types keep application code aligned with the database, so a drift between the two surfaces as a build failure rather than a runtime surprise.
