Skip to content

Design: Auth & Admin Roles

Authentication

  • Provider: Supabase Auth.
  • Method: JWT (JSON Web Token) passed in the Authorization: Bearer <token> header.
  • Verification: The backend calls supabase.auth.get_user(token) to verify the token is valid and not expired.

Admin Authorization (Updated 2026-02-16)

We are moving toward JWT + role as the primary source of truth for admin authorization. The static X-Admin-Key is now a secondary bootstrap mechanism and will be phased out.

Primary: Supabase JWT Role

  • Implementation: get_current_admin dependency.
  • Check: Validates Supabase JWT and ensures user_metadata.role == 'admin'.
  • Status: Production default.

Secondary: X-Admin-Key

  • Purpose: Internal scripts or bootstrap if Supabase Auth is unavailable.
  • Header: x-admin-key.
  • Status: Deprecated (Transition Phase).

Roles Model

Roles are stored in the user's app_metadata or user_metadata in Supabase. - student: Default role. Can chat and view their own wallet. - teacher: (Future) Can view analytics for their classes. - admin: Can trigger scrapers, upload curriculum, manage the vector index, and manage users.

Admin Dashboard API

The following endpoints support the Admin Dashboard: - GET /admin/users: List all users with pagination. - PATCH /admin/users/{user_id}/role: Update a user's role (admin, student, teacher). - GET /admin/references: List all curriculum references found by scrapers. - GET /admin/scrape-runs: Monitor scraping history. - POST /admin/vector-embedding: Trigger ingestion for a specific reference. - POST /admin/upload-curriculum: Manual PDF upload and ingestion.

Future: Custom Claims

Plan to migrate roles into JWT Custom Claims via Supabase Postgres Hooks for faster authorization checks without a DB lookup.

Back to Index