# 06 — Authentik install + OIDC integration ## Goal Bring up Authentik in the compose stack and integrate famapp as an OIDC client. Logging in at `fam.ginnoir.com` redirects to `auth.ginnoir.com`, returns, and creates a session. ## Depends on - 04 (registry, so we have a `users` table to map into) - 05 (compose stack) ## Scope ### Authentik bootstrap - Tune env in `deploy/compose.yaml` for authentik-server/worker/db/redis per Authentik's official docs. - `deploy/authentik/README.md` — manual one-time steps Matt runs after first boot: 1. Visit `auth.ginnoir.com/if/flow/initial-setup/`, set the akadmin password. 2. Create an OIDC Provider for famapp (RS256, redirect URI `https://fam.ginnoir.com/api/auth/callback/authentik`). 3. Create an Application bound to it; copy client ID + secret into famapp's `.env`. 4. Create the two user accounts (Matt + wife) with passkeys. ### famapp OIDC client - Install `next-auth@beta` (v5) — Auth.js. - `src/lib/auth.ts` configures Auth.js with a generic OIDC provider pointed at `AUTH_OIDC_ISSUER`. - On first login, upsert into `users` table by email; create-or-attach to the single seeded household (task 07 owns the seeding; this task assumes it). - Middleware (`src/middleware.ts`) protects everything except `/s/*` (share viewer), `/api/auth/*`, and static assets. - A signed-in user is available via a `getCurrentUser()` server helper. ### Login UX - `/login` page with a single "Sign in with SSO" button. - After login, redirect to `/`. ## Out of scope - Forward-auth / Outpost wiring for the rest of Matt's stack (separate later task). - Account self-service in famapp (Authentik owns identity). - Automating Authentik provider creation via Terraform/blueprints — manual is fine for now; document it well. ## Acceptance criteria - [ ] Hitting `/` while signed out redirects to `/login`. - [ ] Signing in with an Authentik account creates/updates a row in `users` and returns to `/`. - [ ] `getCurrentUser()` works in server components and server actions. - [ ] `/s/` is reachable signed-out (placeholder is fine — real viewer is task 31). - [ ] Auth secret comes from `AUTH_SECRET` env, not committed. ## Notes - Authentik's OIDC issuer URL takes the form `https://auth.ginnoir.com/application/o//`. Document this in the README so Matt copies it correctly. - Use Auth.js's database session strategy with the Drizzle adapter so the `users` row is the source of truth.