← projects

[Born Closed]

Auth, Roles & Invitations

Google sign-in limited to the company domain, roles per dashboard, invitations for people who never logged in, and a dev shortcut that can't open production.

● In productionAuth & SecurityCompanySupabasePostgresReactTypeScript
01 /context

The dashboard hub shows margins, affiliate payouts and customer data. Different people need different dashboards — and different cuts of the same one.

02 /my role

Designed and built auth, roles, invitations, the settings modal and the role guard inside server functions.

03 /problem

Access had to be per dashboard, people had to be invited before their first login, and local development needed a way in that could never work in production.

04 /how it works
  1. 01 · Domain allowlist in the database

    Google OAuth with internal-only consent, plus a signup trigger that rejects other domains — enforced by Postgres, not the UI.

  2. 02 · Roles per dashboard

    owner / master / member, granted per dashboard by bootstrap owners.

  3. 03 · Invitations

    An invited e-mail shows as Pending until the signup trigger applies its roles on the first login.

  4. 04 · Born closed

    The mock user only works on development hostnames. In production the app stays closed even with the dev flag on, and a real session always wins over the mock.

  5. 05 · Guard inside the server function

    The function that queries the lake checks the role and cuts the SELECT's column list itself.

05 /architecture
01
Google OAuth
02
Signup trigger (domain)
03
Roles per dashboard
04
Invitations
05
Server-side role guard
06 /results
A settings modal (General · FX · Access) manages users and roles without touching the database.
07 /what broke and what I changed
  • ! brokeThe app builder's native lake connector looked like it made the server function unnecessary.

    → changedInvestigated it end to end: it doesn't replace a server-side guard, so the guard stayed.

08 /related