> ## Documentation Index
> Fetch the complete documentation index at: https://docs.avyratech.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication

> How authentication works across the Tonnex platform.

# Authentication

Tonnex uses **Supabase Auth** for all authentication needs with **enterprise-grade optimizations** for performance and security.

## Architecture

| Component  | Client                           | Purpose                                  |
| ---------- | -------------------------------- | ---------------------------------------- |
| `apps/web` | `@supabase/ssr` (Anon Key)       | Login, signup, session management        |
| `apps/api` | `jose` + `@supabase/supabase-js` | Local JWT verification, admin operations |

## Web App Auth Flow (Next.js 16)

1. User enters credentials on `/login` or creates account on `/signup`
2. Upon success, user is redirected to `/home`
3. `@supabase/ssr` handles Supabase auth call
4. Session stored as HTTP-only cookies
5. **`proxy.ts`** refreshes session cookie on every request and calls `getUser()` for JWT verification
6. **`getAuthContext()`** reads from `getSession()` (local cookie, \~0ms) — safe because middleware already verified the token
7. Server actions and components use `getAuthContext()` for token + org context

> **⚠️ Performance Note:** `getAuthContext()` uses `getSession()` (local, \~0ms) instead of `getUser()` (network, \~150-300ms). The middleware already verifies the JWT, so re-verification in server actions is unnecessary. `getAuthContext()` is deduplicated via `React.cache()`.

## API Auth Flow

1. Web app includes JWT in `Authorization: Bearer <token>` header
2. `SupabaseGuard` extracts token and verifies it **locally using `jose` + `SUPABASE_JWT_SECRET`** (\~0.1ms)
3. Falls back to Supabase Auth API if local verification fails
4. Authenticated user attached to `request.user`
5. All downstream services can access the verified user + JWT claims

> **🔒 Security:** Swagger/API docs are only available in development (`NODE_ENV !== 'production'`). CORS requires `WEB_URL` to be set in production.

### User Logout

1. Click the **Sign out** button in the dashboard sidebar.
2. The `logout()` server action (in `apps/web/actions/auth.ts`) is triggered.
3. Supabase session is revoked.
4. User is redirected to `/login`.

## JWT Claims (Custom Access Token Hook)

The Supabase custom access token hook (`supabase/migrations/0001_custom_access_token_hook_onboarding.sql`) enriches the JWT with:

| Claim                           | Source            | Purpose              |
| ------------------------------- | ----------------- | -------------------- |
| `app_metadata.org_id`           | `org_memberships` | Tenant isolation     |
| `app_metadata.role`             | `org_memberships` | Admin fast-path      |
| `app_metadata.membership_id`    | `org_memberships` | RBAC lookups         |
| `app_metadata.location_id`      | `org_memberships` | Scope context        |
| `app_metadata.warehouse_id`     | `org_memberships` | Scope context        |
| `app_metadata.onboarding_stage` | `organizations`   | Onboarding redirects |

## RLS Functions

| Function                | JWT Fast-Path                           | Fallback                       |
| ----------------------- | --------------------------------------- | ------------------------------ |
| `is_org_member(org_id)` | ✅ Checks `app_metadata.org_id`          | DB lookup on `org_memberships` |
| `is_org_admin(org_id)`  | ✅ Checks `app_metadata.org_id` + `role` | DB lookup on `org_memberships` |

## RBAC Default Behavior

The `RbacProvider` defaults to **deny-by-default** — if a component is rendered outside the provider, `hasPermission()` returns `false`. This prevents accidental permission bypasses.

## Key Files

| File                                    | Purpose                                            |
| --------------------------------------- | -------------------------------------------------- |
| `apps/web/lib/auth-context.ts`          | Centralized auth context (getSession + JWT decode) |
| `apps/web/lib/supabase/client.ts`       | Browser Supabase client                            |
| `apps/web/lib/supabase/server.ts`       | Server-side Supabase client                        |
| `apps/web/lib/supabase/session.ts`      | Session refresh logic (middleware)                 |
| `apps/web/lib/get-sidebar-data.ts`      | Sidebar data (uses getAuthContext)                 |
| `apps/web/providers/rbac-provider.tsx`  | Client RBAC context (deny-by-default)              |
| `apps/api/src/auth/supabase.service.ts` | Local JWT verification + Supabase clients          |
| `apps/api/src/auth/supabase.guard.ts`   | JWT verification guard                             |

## UI Components

| Component    | Location     | usage                  |
| ------------ | ------------ | ---------------------- |
| `LoginForm`  | `@tonnex/ui` | Used in `/login` page  |
| `SignupForm` | `@tonnex/ui` | Used in `/signup` page |
