Professional Services

May 27, 2026

How workspace-scoped RLS hardened a multi-tenant portal

Workspace-scoped write controls and preference-aware notification dispatch were added to the portal codebase.

BeforeAfter
Write paths needed explicit tenant boundariesWorkspace-scoped write policies across core records
Notification events needed recipient preference checksPreference-aware dispatch functions for documented events
Infrastructure assumptions needed a testable handoffAuth, storage, backup, and security checks recorded with limitations

Put the tenant boundary below the application

A shared portal can filter records in every page and server action, but that leaves isolation dependent on every future code path remembering the rule. This build moved the critical boundary into PostgreSQL row-level security, where policies can restrict which rows a role may read or modify.

The migration applied workspace-aware write policies to projects, tasks, notes, files, folders, channels, channel membership, messages, and clips. Some records inherited workspace access through a parent record, while shared team rooms used a separate role check. That kept each policy close to the relationship it protected.

Treat notifications as preference-aware dispatch

The notification module did more than call an email function. It resolved eligible recipients, excluded the person who caused the event, loaded each recipient's saved preference, and then dispatched the matching message.

Documented dispatchers covered chat messages, task assignment and completion, task updates, approval requests, program changes, shared files, and room membership. Errors were logged without blocking the user action that triggered them.

That code is evidence of implemented routing logic. It is not evidence that a mail provider was configured or that every message reached an inbox.

Make the handoff state what remains unfinished

The infrastructure guide recorded authentication checks, tenant-scoped row-level security behavior, private storage access, a database backup job, and restore procedures. It also named two material limits: outbound email was not yet enabled, and backup copies remained on the same host.

Those limits matter. A configured dispatcher is not an operational notification system until a live message succeeds. A local backup is not disaster recovery until a copy survives loss of the application host.

What the live send test found

The later live test is why that distinction matters. The first test notification never left the server. The portal runs on serverless hosting, which shuts a function down as soon as it sends its response, and the notification sends were still in flight when that happened. Keeping each function alive until its send finished fixed it, and the next test notification reached a real inbox.

The same pass found three database migrations that had never been applied to production, which had broken task creation. They were applied, and every migration was then checked against the live schema, object by object.

The reusable decision

For multi-tenant portals, place access control in the database, keep event dispatch aware of user preferences, and write handoff documentation that distinguishes implemented code from verified operations. That produces a system another engineer can inspect without turning unfinished work into a success claim.

FAQ

Frequently asked questions

01Why enforce tenant boundaries in Postgres?

Database policies protect shared records even when an application action forgets a workspace check. The migration added scoped insert, update, and delete rules to the main write paths.

02What did the notification layer implement?

The code resolved recipients, read their saved preferences, and dispatched documented message, task, approval, program-change, file, and room-membership events. A later live send test found that serverless hosting stopped sends before they finished. After the fix, a test notification reached a real inbox.

03What did the infrastructure handoff verify?

It recorded working authentication, row-level security behavior, private storage access, and a local backup job. It also listed email delivery and off-host backup copies as unfinished. Email delivery was later proven with a live send; off-host backups stayed a separate item.

Next step

Want this for your business?

Run the 90-second AI Operations X-Ray and I'll show you where to start.