Design Rationale — Identity

Non-obvious design choices for the identity module — the WHY behind each decision.

Identity (locked 2026-06-09)

Identity owns authorization; Supabase Auth owns authentication

Decision: identity schema owns roles, permissions, assignments, site access, SSO config, and support grants. Password storage, session tokens, and OAuth flows are Supabase Auth's responsibility — no such tables exist in Vrida schemas.

Why: Rebuilding authentication is unnecessary and risky. Supabase Auth is battle-tested; Vrida adds the authorization model on top.

Guard: No password or session tables will ever appear in identity or any other Vrida schema. If an auth concern arises that looks like it needs a Vrida table, check whether Supabase's JWT claims or metadata can carry it first.


Security policy config lives in identity, not admin

Decision: password_policy, sso_provider, session_config, and ip_whitelist tables live in identity. The admin module is the UI surface; it writes these via IdentityService — it does not own the tables.

Why: Auth config belongs with auth ownership. Co-locating config with the service that enforces it means one team owns the full security surface.

Guard: Do not create admin.password_policy or similar. Admin reads and updates identity config through IdentityService; the tables stay in identity.


Support access via time-boxed grants, not permanent admin flags

Decision: Vrida staff access to tenant data is expressed through support_access_grant rows with explicit granted_until timestamps — not a permanent is_vrida_staff flag on identity_user.

Why: Principle of least privilege. Every support session is auditable, time-bounded, and revocable. A permanent flag creates an ever-present elevated-access pathway.


Last modified: Jun 17, 2026, 8:37 PM PT
On this page
Esc