> ## Documentation Index
> Fetch the complete documentation index at: https://blue-chip.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Authentication

# Authentication

Users sign up and sign in with **Supabase Auth** in the web app. The API never handles passwords; it verifies the access token on each request.

## Flow

```mermaid theme={null}
sequenceDiagram
    participant C as Client (apps/web)
    participant S as Supabase Auth
    participant A as API
    participant J as Project JWKS

    C->>S: sign in
    S-->>C: access token (ES256)
    C->>A: request with Authorization: Bearer <token>
    A->>J: fetch signing key by kid (cached)
    A->>A: verify signature, exp, aud, iss
    A-->>C: response for AuthUser(id=sub)
```

## Verification (`app/utils/auth.py`)

* **Keys** — fetched by `kid` from `{SUPABASE_URL}/auth/v1/.well-known/jwks.json` and cached for `SUPABASE_JWKS_CACHE_SECONDS`. An unseen `kid` triggers a refetch, so key rotation needs no restart.
* **Algorithms** — `ES256` and `RS256` only. HS256 (legacy shared secret) tokens are rejected: enable asymmetric JWT signing keys in the Supabase project.
* **Claims** — `exp`, `sub`, `aud` (= `SUPABASE_JWT_AUDIENCE`, default `authenticated`), and `iss` (= `{SUPABASE_URL}/auth/v1`) are required.
* **Identity** — `sub` must be a UUID. It becomes `AuthUser.id` (along with optional `AuthUser.email`), binds `user_id` to the request logging context, and scopes user-specific database queries.

The JWKS fetch is blocking HTTP, so `get_current_user` runs verification in a worker thread.

## Using it in a route

```python theme={null}
from app.api.v1.auth import get_current_user

@router.get("/profile", response_model=ProfileResponse, tags=["Profile"])
@limiter.limit(settings.RATE_LIMIT_ENDPOINTS["read"][0])
async def get_profile(request: Request, user: AuthUser = Depends(get_current_user)) -> ProfileResponse:
    ...
```

## Errors

| Status | When |
| - | - |
| `401` | Malformed, expired, wrong audience or issuer, unknown signing key, or symmetric token |
| `503` | The JWKS could not be fetched |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.