Use when implementing authentication, user management, organization/tenant management, team invitations, role-based access control (RBAC), or multi-tenant architecture in a Supabase project...
A complete authentication and organization management system for Supabase projects. Use this skill when implementing:
authhubauthentication setupmulti-tenantorg switchingteam invitationsRBACtenant managementAuthHub supports two deployment modes. Choose based on your use case:
Use this if: Building a single SaaS product with its own Supabase project.
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā Your Supabase Project ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¤
ā AuthHub Tables (public schema) ā
ā āāā products (your single product entry) ā
ā āāā user_profiles ā
ā āāā tenants (organizations) ā
ā āāā user_tenants ā
ā āāā roles (for your product) ā
ā āāā user_role_assignments ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¤
ā Product Tables (public schema with RLS) ā
ā āāā customers (has organization_id + RLS) ā
ā āāā orders (has organization_id + RLS) ā
ā āāā ... all your product tables ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
Characteristics:
products table (for future central AuthHub integration)public schema with organization_id columnproduct_id filter (your single product)Use this if: Multiple products share the same Supabase database (like DataSwim + Onboard).
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā Shared Supabase Project ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¤
ā AuthHub Tables (public schema) ā
ā āāā products (DataSwim, Onboard, etc.) ā
ā āāā user_profiles ā
ā āāā tenants ā
ā āāā user_tenants ā
ā āāā roles (per product) ā
ā āāā user_role_assignments (includes product_id) ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¤
ā Product A Tables ā Product B Tables ā
ā (public or schema) ā (public or schema) ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
Characteristics:
product_idproduct_idBy keeping the products table in all deployments, we enable future capabilities:
Best for: Most SaaS applications with fixed schemas.
Every product table includes organization_id and RLS policies:
-- Example: customers table
CREATE TABLE public.customers (
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
organization_id UUID NOT NULL REFERENCES public.tenants(id),
name TEXT NOT NULL,
email TEXT,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- RLS Policy
ALTER TABLE public.customers ENABLE ROW LEVEL SECURITY;
CREATE POLICY "Users can view their org's customers"
ON public.customers FOR SELECT
USING (
organization_id IN (
SELECT tenant_id FROM public.user_tenants
WHERE user_id = auth.uid() AND is_active = true
)
);
Pros:
Cons:
Best for: Applications where tenants define their own data structures (like DataSwim).
Each organization gets its own PostgreSQL schema:
-- Creates: tenant_abc123def456...
SELECT create_tenant_schema('abc123-def4-5678-...');
Pros:
Cons:
When to use Schema-per-tenant:
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā Supabase Auth ā
ā (auth.users - managed by Supabase) ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā
ā¼
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā public.user_profiles ā
ā (extended user info, links to auth.users) ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā
āāāāāāāāāāāāāāā“āāāāāāāāāāāāāā
ā¼ ā¼
āāāāāāāāāāāāāāāāāāāāāāā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā public.user_tenants ā ā public.user_role_assignments ā
ā (user ā org link) ā ā (user ā org ā product ā role)ā
āāāāāāāāāāāāāāāāāāāāāāā āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā ā
āāāāāāāāāāāāāāā¬āāāāāāāāāāāāāā
ā¼
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā public.tenants ā
ā (organizations) ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā
ā¼
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā Product Tables (with organization_id) ā
ā customers, orders, projects, etc. + RLS policies ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
Each product has its own roles tied to a product_id. Even in standalone mode, keep this structure for future compatibility.
NEVER query tenants directly for user access. Always go through:
user_tenants - for user-org membershipuser_role_assignments - for roles (always filter by product_id)All tables use is_active boolean. Never hard delete - set is_active = false.
Every product table should have organization_id column with appropriate RLS policies.
Even in standalone apps, include product_id in queries. This ensures:
This skill assumes:
| File | Purpose |
|---|---|
| DATABASE_SCHEMA.md | Complete SQL migrations |
| SUPABASE_CONFIG.md | Supabase dashboard settings |
| API_TEMPLATES.md | Next.js API route templates |
| FRONTEND_SETUP.md | React context and components |
| IMPLEMENTATION_CHECKLIST.md | Step-by-step checklist |