Files
famapp/docs/tasks/06-authentik-oidc.md
ginnoir b89690a9f2 Initial scaffold: tooling, plan, task briefs
- pnpm 10 workspace + TypeScript strict + ESLint flat + Prettier
- CLAUDE.md as canonical brief
- docs/tasks/ — 22 task briefs broken out by phase for sub-sessions
- docs/decisions/ — ADR scaffold

Implements task 01 (repo-init).
2026-05-06 00:05:50 -05:00

2.4 KiB

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/<token> 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/<app-slug>/. 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.