Claude-skill-registry authhub
Use when implementing authentication, user management, organization/tenant management, team invitations, role-based access control (RBAC), or multi-tenant architecture in a Supabase project. Provides complete schema, API templates, and frontend components for AuthHub-style authentication.
git clone https://github.com/majiayu000/claude-skill-registry
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/authhub" ~/.claude/skills/majiayu000-claude-skill-registry-authhub && rm -rf "$T"
skills/data/authhub/SKILL.mdAuthHub - Multi-Tenant Authentication System
A complete authentication and organization management system for Supabase projects. Use this skill when implementing:
- User signup/signin
- Organization (tenant) creation
- Multi-tenant data isolation
- Team invitations
- Role-based access control (RBAC)
- Organization switching
- Permission management
Explicit Triggers
authhubauthentication setupmulti-tenantorg switchingteam invitationsRBACtenant management
Quick Start
- Database Schema: See DATABASE_SCHEMA.md - Run migrations first
- Supabase Config: See SUPABASE_CONFIG.md - Configure auth settings
- API Templates: See API_TEMPLATES.md - Copy and customize
- Frontend Setup: See FRONTEND_SETUP.md - React context and hooks
- Checklist: See IMPLEMENTATION_CHECKLIST.md - Track progress
Deployment Modes
AuthHub supports two deployment modes. Choose based on your use case:
Mode 1: Standalone App (Most Common)
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:
- Single Supabase project per product
- Still uses
table (for future central AuthHub integration)products - Product tables in
schema withpublic
columnorganization_id - RLS policies filter data by organization
- Queries include
filter (your single product)product_id
Mode 2: Multi-Product Platform
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:
- Single Supabase project shared by multiple products
- Each product has unique
product_id - All queries MUST filter by
product_id - Enables cross-product features and central management
Future: Central AuthHub Dashboard
By keeping the
products table in all deployments, we enable future capabilities:
- Central dashboard to view all products across the ecosystem
- API integration to sync product/user data
- Cross-product analytics and management
- Single sign-on across products (future feature)
Data Isolation Strategies
Strategy 1: RLS with organization_id (RECOMMENDED)
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:
- Simple to implement
- Standard PostgreSQL pattern
- Easy to query across organizations (for admin dashboards)
- Works with Supabase's built-in RLS
Cons:
- All tenants share table structure
- Large tables may need additional indexing
Strategy 2: Schema-per-tenant (Advanced)
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:
- Complete data isolation
- Tenants can have different table structures
- Easier to export/delete tenant data
Cons:
- More complex to manage
- Can't easily query across tenants
- Schema migrations must run per-tenant
When to use Schema-per-tenant:
- Users create their own database tables (like DataSwim)
- Regulatory requirements demand physical data isolation
- Per-tenant backup/restore requirements
Architecture Overview
┌─────────────────────────────────────────────────────────┐ │ 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 │ └─────────────────────────────────────────────────────────┘
Key Concepts
1. Product-Scoped Roles
Each product has its own roles tied to a
product_id. Even in standalone mode, keep this structure for future compatibility.
2. Junction Tables
NEVER query
tenants directly for user access. Always go through:
- for user-org membershipuser_tenants
- for roles (always filter by product_id)user_role_assignments
3. Soft Deletes
All tables use
is_active boolean. Never hard delete - set is_active = false.
4. Organization ID in Product Tables
Every product table should have
organization_id column with appropriate RLS policies.
5. Always Filter by Product ID
Even in standalone apps, include
product_id in queries. This ensures:
- Consistent patterns across all AuthHub implementations
- Future compatibility with central management
- Clean separation if you add another product later
Tech Stack Assumptions
This skill assumes:
- Framework: Next.js 14/15 with App Router
- Language: TypeScript
- Database: Supabase (PostgreSQL)
- Auth: Supabase Auth
- Deployment: Netlify, Vercel, or similar
Files in This Skill
| 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 |