Files
stack/docs/scratchpads/p8-001-sso-providers.md
Jarvis 774b76447d
Some checks failed
ci/woodpecker/pr/ci Pipeline failed
ci/woodpecker/push/ci Pipeline failed
fix: rename all packages from @mosaic/* to @mosaicstack/*
- Updated all package.json name fields and dependency references
- Updated all TypeScript/JavaScript imports
- Updated .woodpecker/publish.yml filters and registry paths
- Updated tools/install.sh scope default
- Updated .npmrc registry paths (worktree + host)
- Enhanced update-checker.ts with checkForAllUpdates() multi-package support
- Updated CLI update command to show table of all packages
- Added KNOWN_PACKAGES, formatAllPackagesTable, getInstallAllCommand
- Marked checkForUpdate() with @deprecated JSDoc

Closes #391
2026-04-04 21:43:23 -05:00

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

  1. Refactor createAuth to build oauthProviders[] conditionally
  2. Add WorkOS provider (explicit URLs, no discovery)
  3. Add Keycloak provider (discoveryUrl pattern)
  4. Add genericOAuthClient() to auth-client.ts
  5. Add SSO buttons to login page gated by NEXT_PUBLIC_WORKOS_ENABLED / NEXT_PUBLIC_KEYCLOAK_ENABLED
  6. Update .env.example
  7. Write auth.test.ts with env-var gating tests
  8. Quality gates: typecheck + lint + format:check + test
  9. Commit + push + PR

Decisions

  • WorkOS: Uses explicit authorizationUrl, tokenUrl, userInfoUrl (no discovery endpoint available)
  • Keycloak: Uses discoveryUrl pattern ({URL}/realms/{REALM}/.well-known/openid-configuration)
  • UI gating: Login page uses NEXT_PUBLIC_WORKOS_ENABLED / NEXT_PUBLIC_KEYCLOAK_ENABLED feature 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=true must 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 var
  • auth.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 (@mosaicstack/auth) 8/8 tests passed

Verification Evidence

  • pnpm typecheck — FULL TURBO, 32 tasks successful
  • pnpm lint — FULL TURBO, 18 tasks successful
  • pnpm format:check — All matched files use Prettier code style!
  • pnpm --filter=@mosaicstack/auth test — 8 tests passed, 0 failed