diff --git a/.planning/ROADMAP.md b/.planning/ROADMAP.md index df6153c..0284a6b 100644 --- a/.planning/ROADMAP.md +++ b/.planning/ROADMAP.md @@ -656,3 +656,22 @@ Plans: Plans: - [ ] TBD (run /gsd-plan-phase 18 to break down) + +### Phase 19: Local Auth (No-OIDC Mode) + +**Goal:** Let an operator run FamilySync entirely on **local DB users with no OIDC** — username/password accounts and a local login flow that coexists with the Authelia OIDC path — and **optionally wire OIDC in later** by claiming/linking an existing local user to an OIDC identity. Removes the hard dependency on a deployed Authelia for small/solo self-hosters. +**Mode:** standard +**Depends on:** Phase 12 (Initial Setup Wizard) — builds directly on the pre-OIDC **local-user foundation** introduced there: nullable `users.oidc_iss`/`oidc_sub` + the claimed/pending marker, and the first-login-claims merge. Phase 19 generalizes that single bootstrap local user into a full local-account model + login. +**Requirements**: TBD (derive an AUTH-LOCAL-0x set during discuss/spec — local credential storage with proper password hashing, local login session issuance reusing the existing session-cookie path, coexistence with the OIDC middleware, and OIDC-link of an existing local user). +**Plans:** 0 plans + +**Provenance:** Deferred from the Phase 12 discussion (2026-06-15) — see `.planning/phases/12-initial-setup-wizard/12-CONTEXT.md` §Deferred Ideas. The operator runs FamilySync this way themselves and wants no-OIDC operation as a first-class mode. + +**Open questions for discuss/spec:** +- Password hashing/storage choice (e.g. argon2id/bcrypt) and how it sits alongside the env-only secret kernel from Phase 12. +- How local login coexists with `oidcAuthMiddleware` ordering in `apps/api/src/index.ts` (route-level auth strategy selection vs. a mode flag in `app_config`). +- The OIDC-link flow: claiming an existing local user into an `oidc_iss+oidc_sub` identity without violating the D-10 "identity is OIDC, never email" rule. +- Whether "local mode vs OIDC mode" is a deploy-time switch or both can be live simultaneously. + +Plans: +- [ ] TBD (run /gsd-plan-phase 19 to break down) diff --git a/.planning/STATE.md b/.planning/STATE.md index 5f8163e..6bf1122 100644 --- a/.planning/STATE.md +++ b/.planning/STATE.md @@ -195,6 +195,7 @@ Recent decisions affecting current work: - **Phase 16 added (2026-06-12, /gsd-phase):** CI Dependency Audit, Security Checks & Image Hygiene — extend the Phase 8 Gitea CI workflow with outdated-dependency reporting (`pnpm outdated`), a vulnerability audit (`pnpm audit` at a chosen severity), and a baseline of additional security checks (secret scan / image scan). User requested a 16 integer phase (not a decimal insert) — they've been running independent/CI phases ahead of the admin chain. **Depends on Phase 8; independent of the admin chain (10–12).** Scope still needs definition — run /gsd-discuss-phase 16. Milestone window now Phases 7–16. - **Backlog 999.17 folded into Phase 16 + removed (2026-06-12, /gsd-phase):** the dev/prod image-boundary item (confine `DEV_AUTH_BYPASS` to dev via build/boot-time enforcement; ensure no `.env`/secrets/encryption keys/`DEV_USER` seed/family data ship in published images; CI assertion in the publish job) was pulled into Phase 16 — shared CI surface and overlapping secret/image scanning made a separate phase redundant. The 999.17 backlog entry + its phase dir were **deleted** (not retained-for-history) since the scope now lives in an active phase; this also clears the recycled-number collision with Phase 15's historical "promoted from 999.17" provenance (the markdown-lint item that became Phase 15 had reused 999.17 first). - **Phase 18 added (2026-06-13, /gsd-phase):** Auto timezone detection and ability to change timezone — let the app auto-detect the household timezone and allow changing it. User invoked `/gsd-phase --insert 18` but Phase 18 didn't exist (17 was the last integer phase), so after confirmation it was added as an integer phase at the end of the milestone, not a decimal insert. Motivated by the Phase 11 all-day-reminder dependency on a correct server `TZ` (all-day reminders fire at 9 AM local, computed from `process.env.TZ`). Scope still needs definition — run /gsd-discuss-phase 18. Milestone window now Phases 7–18. +- **Phase 19 added (2026-06-15, /gsd-phase):** Local Auth (No-OIDC Mode) — run FamilySync entirely on local DB users with no OIDC, optionally wiring OIDC in later. Deferred from the Phase 12 discuss-phase (the operator runs it this way and wants no-OIDC as a first-class mode). **Depends on Phase 12** — builds on the pre-OIDC local-user foundation introduced there (nullable `oidc_iss`/`oidc_sub` + claimed marker + first-login-claims merge). Scope still needs definition — run /gsd-discuss-phase 19. Milestone window now Phases 7–19. ### Pending Todos diff --git a/.planning/phases/19-local-auth-no-oidc-mode/.gitkeep b/.planning/phases/19-local-auth-no-oidc-mode/.gitkeep new file mode 100644 index 0000000..e69de29