Add Authentik OIDC integration (task 06)

- next-auth@beta + @auth/drizzle-adapter wired up with database sessions
- src/lib/auth.ts: OIDC provider, authorized callback, signIn household-attach, getCurrentUser()
- src/middleware.ts: protects all routes except /login, /s/*, /api/auth/*
- src/app/api/auth/[...nextauth]/route.ts: mounts Auth.js handlers
- src/app/login/page.tsx: single SSO sign-in button (server action)
- Schema: users extended (name/emailVerified/image), accounts/sessions/verificationTokens added
- drizzle/0001_auth_tables.sql: migration for schema changes
- deploy/authentik/README.md: manual bootstrap steps for Authentik
- src/lib/db.ts: pass schema to drizzle for relational query builder

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
ginnoir
2026-05-06 02:37:41 -05:00
co-authored by Claude Sonnet 4.6
parent f59753404e
commit 5da472d6ff
11 changed files with 392 additions and 4 deletions
+91
View File
@@ -0,0 +1,91 @@
# Authentik — manual bootstrap
Run these steps once after the first `docker compose up -d` in the `deploy/` directory.
---
## 1. Set the admin password
Visit `https://auth.ginnoir.com/if/flow/initial-setup/` and set the **akadmin** password.
---
## 2. Create the OIDC provider
1. Log in to the Authentik Admin UI at `https://auth.ginnoir.com/if/admin/`.
2. Go to **Applications → Providers → Create**.
3. Choose **OAuth2/OpenID Provider**.
4. Configure:
- **Name:** `famapp`
- **Authorization flow:** `default-provider-authorization-explicit-consent`
- **Client type:** `Confidential`
- **Client ID:** (auto-generated — copy this)
- **Client Secret:** (auto-generated — copy this)
- **Redirect URIs:** `https://fam.ginnoir.com/api/auth/callback/authentik`
- **Signing Key:** `authentik Self-signed Certificate`
- **Token validity:** 24 hours (or your preference)
5. Save and note the **Issuer URL** shown on the provider detail page.
The issuer URL will look like:
```
https://auth.ginnoir.com/application/o/famapp/
```
Set this (and the client ID/secret) in famapp's `.env` / production secrets:
```env
AUTH_OIDC_ISSUER=https://auth.ginnoir.com/application/o/famapp/
AUTH_OIDC_CLIENT_ID=<client-id>
AUTH_OIDC_CLIENT_SECRET=<client-secret>
```
---
## 3. Create the Application
1. Go to **Applications → Applications → Create**.
2. Configure:
- **Name:** `famapp`
- **Slug:** `famapp`
- **Provider:** select the `famapp` provider created above
- **Launch URL:** `https://fam.ginnoir.com`
3. Save.
---
## 4. Create user accounts
1. Go to **Directory → Users → Create**.
2. Create accounts for Matt and wife. Recommended fields:
- **Username / Email:** use real email addresses (famapp uses email as the identity key)
- **Name:** display name shown in the app
3. Optionally invite them via email to set their own passwords.
---
## 5. Set up passkeys (optional but recommended)
Each user can enroll a passkey from their Authentik profile:
1. Sign in as the user at `https://auth.ginnoir.com`.
2. Go to **Settings → MFA Devices → Add → WebAuthn Device**.
3. Follow the browser prompt to register a Touch ID / Face ID / hardware key.
---
## 6. Generate AUTH_SECRET
Run this locally and put the output in your `.env` / production secrets:
```sh
openssl rand -base64 32
```
---
## Notes
- The Authentik image in `compose.yaml` is currently pinned to `latest`. Before production, pin to a specific version tag (e.g. `ghcr.io/goauthentik/server:2024.12.3`).
- famapp uses **database sessions** (Auth.js). Sessions are stored in the `sessions` table and expire according to Auth.js defaults (30 days).
- The forward-auth / Outpost wiring for other services (Sonarr, Radarr, etc.) is a separate future task.