3.4 KiB
3.4 KiB
P8-001 — WorkOS + Keycloak SSO Providers
Branch: feat/p8-001-sso-providers Started: 2026-03-18 Mode: Delivery
Objective
Add WorkOS and Keycloak as optional SSO providers to the BetterAuth configuration, following the existing Authentik pattern.
Scope
| Surface | Change |
|---|---|
packages/auth/src/auth.ts |
Refactor provider array, add WorkOS + Keycloak conditional registration |
apps/web/src/lib/auth-client.ts |
Add genericOAuthClient() plugin |
apps/web/src/app/(auth)/login/page.tsx |
WorkOS + Keycloak SSO buttons gated by NEXT_PUBLIC_* env vars |
.env.example |
Document WorkOS + Keycloak env vars |
packages/auth/src/auth.test.ts |
Unit tests verifying env-var gating |
Plan
- ✅ Refactor
createAuthto buildoauthProviders[]conditionally - ✅ Add WorkOS provider (explicit URLs, no discovery)
- ✅ Add Keycloak provider (discoveryUrl pattern)
- ✅ Add
genericOAuthClient()to auth-client.ts - ✅ Add SSO buttons to login page gated by
NEXT_PUBLIC_WORKOS_ENABLED/NEXT_PUBLIC_KEYCLOAK_ENABLED - ✅ Update
.env.example - ⏳ Write
auth.test.tswith env-var gating tests - ⏳ Quality gates: typecheck + lint + format:check + test
- ⏳ Commit + push + PR
Decisions
- WorkOS: Uses explicit
authorizationUrl,tokenUrl,userInfoUrl(no discovery endpoint available) - Keycloak: Uses
discoveryUrlpattern ({URL}/realms/{REALM}/.well-known/openid-configuration) - UI gating: Login page uses
NEXT_PUBLIC_WORKOS_ENABLED/NEXT_PUBLIC_KEYCLOAK_ENABLEDfeature flags (safer than exposing secret env var names client-side) - Refactor: Authentik moved into same
oauthProviders[]array pattern — cleaner, more extensible - Feature flag design:
NEXT_PUBLIC_*flags are opt-in alongside credentials (prevents accidental button render when creds not set)
Assumptions
ASSUMPTION:WorkOS OIDC discovery URL is not publicly documented; using direct URL pattern from WorkOS SSO docs.ASSUMPTION:NEXT_PUBLIC_WORKOS_ENABLED=truemust be explicitly set — this is intentional (credential presence alone doesn't enable the button since NEXT_PUBLIC vars are baked at build time).
Tests
auth.test.ts: Mocks betterAuth stack, verifies WorkOS included/excluded based on env varauth.test.ts: Verifies Keycloak discoveryUrl constructed correctly
Quality Gate Results
| Gate | Status |
|---|---|
| typecheck | ✅ 32/32 cached green |
| lint | ✅ 18/18 cached green |
| format:check | ✅ All matched files use Prettier code style |
| test (@mosaic/auth) | ✅ 8/8 tests passed |
Verification Evidence
pnpm typecheck— FULL TURBO, 32 tasks successfulpnpm lint— FULL TURBO, 18 tasks successfulpnpm format:check— All matched files use Prettier code style!pnpm --filter=@mosaic/auth test— 8 tests passed, 0 failed