Kaiten
Self-Hosting

Clerk Setup

Step-by-step guide to using Clerk as your identity provider with Kaiten.

Clerk Setup Guide

Clerk is the recommended identity provider for Kaiten. This guide walks you through the complete setup.

Create a Clerk Application

  1. Go to clerk.com and create an account
  2. Create a new application
  3. Enable Organizations in Settings → Organizations

Get Your API Keys

In your Clerk dashboard, go to API Keys and copy:

  • Secret Key: sk_test_xxxxx or sk_live_xxxxx
  • Publishable Key: pk_test_xxxxx or pk_live_xxxxx

Configure Environment Variables

Add to your .env file:

CLERK_SECRET_KEY=sk_test_xxxxx
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_xxxxx

Configure JWT Validation in Traefik

The compose.yml already includes the Clerk JWT middleware configuration. Verify these labels on your Traefik service:

- "traefik.http.middlewares.clerk-jwt.plugin.jwt.Keys.0.URL=https://${CLERK_DOMAIN}/.well-known/jwks.json"
- "traefik.http.middlewares.clerk-jwt.plugin.jwt.Alg=RS256"
- "traefik.http.middlewares.clerk-jwt.plugin.jwt.Issuers=https://${CLERK_DOMAIN}"

The CLERK_DOMAIN is automatically derived from your Clerk application. It typically looks like xxxxx.clerk.accounts.dev.

Configure Clerk Webhooks

Kaiten syncs organizations and users from Clerk via webhooks:

  1. In Clerk Dashboard → WebhooksAdd Endpoint
  2. Set URL: https://your-kaiten-domain/api/webhooks/clerk
  3. Select events:
    • organization.created
    • organization.updated
    • organization.deleted
    • user.created
    • user.updated
    • organizationMembership.created
    • organizationMembership.updated
    • organizationMembership.deleted
  4. Copy the signing secret → add to .env as CLERK_WEBHOOK_SECRET

Test the Integration

  1. Start Kaiten: make up
  2. Open the dashboard: http://localhost:6000
  3. You should see the Clerk sign-in page
  4. After signing in, your organization and user profile are synced automatically

How Clerk Auth Flows in Kaiten

  1. User signs in via Clerk → receives a session JWT
  2. Frontend sends JWT in Authorization: Bearer header
  3. Traefik validates the JWT against Clerk's JWKS endpoint
  4. API extracts Principal from JWT claims (user_id, org_id, scopes)
  5. All database queries are scoped to the organization

On this page