# Authentication

This guide explains how to configure and use authentication with the Serverless API Gateway, supporting JWT, Auth0, and Supabase integrations.

The Serverless API Gateway supports multiple authentication strategies. You can protect any route by setting `"auth": true` in its path configuration, and the gateway will validate incoming tokens using the configured [authorizer](/configuration/authorizer.md).

## Supported Authentication Providers

| Provider     | Type                       | Use Case                                                                                                                |
| ------------ | -------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| **JWT**      | Token-based (HS256)        | Bring your own identity provider; validate tokens with a shared secret. See [Authorizer](/configuration/authorizer.md). |
| **Auth0**    | OAuth 2.0 / OpenID Connect | Managed identity with social logins, MFA, and enterprise connections. See [Auth0 Integration](/configuration/auth0.md). |
| **Supabase** | Passwordless OTP           | Email OTP, phone OTP, and magic link authentication. See [Supabase OTP Integration](/configuration/supabase-otp.md).    |

## Quick Start

### 1. Configuration Setup

Create your `src/api-config.json` file with one of the authentication providers:

**For Supabase:**

```json
{
  "$schema": "./api-config.schema.json",
  "title": "Supabase Integration",
  "description": "Configuration for Supabase authentication",
  "cors": {
    "allow_origins": ["https://app.example.com"],
    "allow_methods": ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
    "allow_headers": ["*"],
    "expose_headers": ["*"],
    "allow_credentials": true,
    "max_age": 3600
  },
  "authorizer": {
    "type": "supabase",
    "jwt_secret": "$env.SUPABASE_JWT_SECRET",
    "issuer": "https://YOUR_PROJECT_ID.supabase.co/auth/v1",
    "audience": "authenticated"
  },
  "paths": [
    { "method": "GET", "path": "/health", "response": { "status": "ok" } },
    { "method": "POST", "path": "/api/v1/supabase/auth", "integration": { "type": "supabase_passwordless_auth" } },
    { "method": "POST", "path": "/api/v1/supabase/verify", "integration": { "type": "supabase_passwordless_verify" } },
    {
      "method": "GET",
      "path": "/api/v1/protected",
      "response": {
        "status": "protected endpoint",
        "message": "You are successfully authenticated!"
      },
      "auth": true
    }
  ]
}
```

**For Auth0:**

```json
{
  "$schema": "./api-config.schema.json",
  "title": "Auth0 Integration",
  "description": "Configuration for Auth0 authentication",
  "cors": {
    "allow_origins": ["https://app.example.com"],
    "allow_methods": ["GET", "POST", "PUT", "DELETE", "OPTIONS"],
    "allow_headers": ["*"],
    "expose_headers": ["*"],
    "allow_credentials": true,
    "max_age": 3600
  },
  "authorizer": {
    "type": "auth0",
    "domain": "$env.AUTH0_DOMAIN",
    "client_id": "$env.AUTH0_CLIENT_ID",
    "client_secret": "$secrets.AUTH0_CLIENT_SECRET",
    "redirect_uri": "https://your-api.com/api/v1/auth0/callback",
    "callback_uri": "https://your-api.com/api/v1/auth0/callback-redirect",
    "jwks_uri": "https://your-domain.us.auth0.com/.well-known/jwks.json",
    "scope": "openid profile email"
  },
  "paths": [
    { "method": "GET", "path": "/health", "response": { "status": "ok" } },
    { "method": "GET", "path": "/api/v1/auth0/callback", "integration": { "type": "auth0_callback" } },
    { "method": "GET", "path": "/api/v1/auth0/profile", "integration": { "type": "auth0_userinfo" }, "auth": true },
    {
      "method": "GET",
      "path": "/api/v1/protected",
      "response": {
        "status": "protected endpoint",
        "message": "You are successfully authenticated!"
      },
      "auth": true
    }
  ]
}
```

**For JWT (custom provider):**

```json
{
  "authorizer": {
    "type": "jwt",
    "secret": "$env.JWT_SECRET",
    "algorithm": "HS256",
    "audience": "your-audience",
    "issuer": "your-issuer"
  },
  "paths": [
    {
      "method": "GET",
      "path": "/api/v1/protected",
      "response": { "status": "protected" },
      "auth": true
    }
  ]
}
```

See the [Authorizer](/configuration/authorizer.md) page for all JWT configuration options and supported error codes.

### 2. Environment Variables and Secrets

**For Supabase:**

```bash
# Environment Variables (in wrangler.toml)
SUPABASE_URL=https://YOUR_PROJECT_ID.supabase.co

# Secrets (use wrangler secret put)
wrangler secret put SUPABASE_JWT_SECRET
wrangler secret put SUPABASE_SERVICE_ROLE_KEY
```

**For Auth0:**

```bash
# Environment Variables (in wrangler.toml)
AUTH0_DOMAIN=your-domain.us.auth0.com
AUTH0_CLIENT_ID=your_client_id_here

# Secrets (use wrangler secret put)
wrangler secret put AUTH0_CLIENT_SECRET
## Optional if you use "jwks" instead of "jwks_uri" in authorizer:
wrangler secret put AUTH0_JWKS
```

**For JWT:**

```bash
wrangler secret put JWT_SECRET
```

### 3. Deploy

```bash
wrangler deploy
```

## Authentication Flows

### Supabase OTP Flow

1. **Send OTP**: `POST /api/v1/supabase/auth` with `{"email": "user@example.com"}` or `{"phone": "+1234567890"}`
2. **Verify OTP**: `POST /api/v1/supabase/verify` with the email/phone and the 6-digit token
3. **Use Token**: Include `Bearer YOUR_ACCESS_TOKEN` in the `Authorization` header

For detailed configuration, including magic link vs OTP differences and troubleshooting, see the [Supabase OTP Configuration Guide](/configuration/supabase-otp.md).

### Auth0 OAuth Flow

1. **Authorization URL**: Direct users to Auth0 login via the callback-redirect endpoint
2. **Callback**: Auth0 redirects to your callback URL with authorization code
3. **Token Exchange**: Callback endpoint exchanges code for tokens automatically
4. **Use Token**: Include the ID token in the `Authorization` header

For setup steps, required fields, and path configuration, see the [Auth0 Integration Guide](/configuration/auth0.md).

### JWT Flow

1. **Obtain Token**: Generate a JWT from your own identity provider or auth server
2. **Include Token**: Send it in the `Authorization: Bearer <token>` header
3. **Validation**: The gateway validates the signature, audience, and issuer

For JWT configuration details, see [Authorizer](/configuration/authorizer.md).

## Protecting Routes

Any path can require authentication by adding `"auth": true`:

```json
{
  "method": "GET",
  "path": "/api/v1/protected-resource",
  "integration": {
    "type": "http_proxy",
    "url": "https://backend.example.com/resource"
  },
  "auth": true
}
```

When `"auth": true` is set, the gateway validates the `Authorization` header using the configured authorizer before forwarding the request. If validation fails, the gateway returns a `401 Unauthorized` response.

## Security Best Practices

* Keep JWT secrets secure by storing them as [Wrangler secrets](https://developers.cloudflare.com/workers/configuration/secrets/)
* Use HTTPS for all callback URLs
* Rotate credentials regularly
* Send access tokens only in the `Authorization: Bearer <token>` header
* Send refresh tokens in `X-Refresh-Token` header or JSON body, never in URL query parameters
* Configure [CORS](/configuration/cors.md) to restrict allowed origins to your frontend domain

For additional Supabase OTP tips, see the [Supabase OTP Configuration Guide](/configuration/supabase-otp.md).

For production-ready schema-valid examples, use:

* `serverlessapigateway/docs/config-examples/auth0.json`
* `serverlessapigateway/docs/config-examples/supabase.json`

## Related Pages

* [Authorizer Configuration](/configuration/authorizer.md) -- JWT validation, error codes, and supported algorithms
* [Auth0 Integration](/configuration/auth0.md) -- Auth0-specific setup and OAuth flow
* [Supabase OTP Integration](/configuration/supabase-otp.md) -- Supabase email/phone OTP and magic link configuration
* [CORS Configuration](/configuration/cors.md) -- cross-origin settings for browser-based auth flows
* [Integrations Overview](/configuration/integrations.md) -- all available integration types


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.serverlessapigateway.com/configuration/authentication.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
