Review: Keycloak SMTP (phase note)

review-285-2026-03-27 Review

review needs-refinement

Verdict: NEEDS_REFINEMENT

Template Completeness

This is a phase note (not a Forgejo issue), so template check is against phase note structure:
  • [x] Goal
  • [x] Owner
  • [x] Repo
  • [x] Depends on
  • [x] Scope
  • [x] Acceptance Criteria (5 criteria)
  • [x] Deliverables
  • [x] Related
  • [ ] Forgejo issue — No Forgejo issue exists on forgejo_admin/pal-e-platform for this work. The board item has forgejo_issue_url: null. Per kanban flow convention, work items moving to next_up need a Forgejo issue as the execution spec.

Traceability

  • [x] story:WS-S21 — "As a parent, I want to manage my login credentials so that I control my own access" (verified in project-westside-basketball user stories, Parent section)
  • [ ] arch:X label — Missing. No architecture component label. Suggest arch:keycloak to match the platform's identity provider component.
  • [ ] Forgejo issue — Missing. No Forgejo issue exists for this phase. The board item references only the phase note slug.

File Targets

The phase note explicitly states this is NOT a Terraform change. The work is a one-time Keycloak Admin API call (PUT /admin/realms/westside-basketball with smtpServer payload). No file modifications in pal-e-platform repo.
  • [x] terraform/modules/keycloak/main.tf — verified exists (249 lines). Confirms no SMTP config in Terraform currently. Phase correctly identifies this as out-of-scope for Terraform.
  • [x] sop-secrets-management — verified exists in pal-e-docs. Procedures section has no Gmail app password rotation runbook yet. Deliverable to add one is valid.
  • [ ] Pre-requisite gap: No ~/secrets/keycloak/ or ~/secrets/gmail/ directory exists. The Gmail app password has not been generated yet. The phase lists "Pre-req: Gmail account must have 2FA enabled and an app password generated" but does not document how to create the app password or where to store it. This is a manual Lucas step that should be called out explicitly.

Repo Placement

Repo is listed as forgejo_admin/pal-e-platform. The actual work is a Keycloak Admin API call (runtime config, not code change). The SOP update is in pal-e-docs. The phase note correctly identifies the repo as the platform repo even though no code changes are expected — Keycloak is a platform-managed service.
OK — repo placement is correct.

Dependencies

  • basketball-api #131 ("Bug: Keycloak SMTP not configured") — closed. This was the bug that exposed the gap.
  • basketball-api #129 ("Enterprise login: Keycloak SMTP + self-service password reset") — closed. Code changes to basketball-api were merged (PR #167). The SMTP configuration is the remaining platform-level piece.
  • Board item #270 (Forgejo issue #142: "Keycloak realm config via Terraform provider") — in backlog. The phase explicitly excludes Terraform management of SMTP. These are independent: #142 is about declarative realm config broadly, this phase is about one-time SMTP setup.
  • Board item #276 ("Phase 28: Keycloak Declarative Onboarding") — done. Successfully imported Keycloak realms/clients into Terraform via pal-e-services. Does not conflict.
  • No blockers in in_progress. The only in-progress item (#411) is a Harbor CI bug, unrelated.

Acceptance Criteria

5 criteria, all testable:
  • [x] "Keycloak realm has SMTP configured" — verifiable via curl .../admin/realms/westside-basketball checking smtpServer field
  • [x] "Forgot Password sends a real email" — manual test, clear pass/fail
  • [x] "Player can click link and set new password" — manual test, clear pass/fail
  • [x] "From address is westsidebasketball@gmail.com" — verifiable from received email headers
  • [x] "Tested with a real email address" — explicit requirement, good
  • [ ] Missing criterion: No acceptance criterion for the SOP deliverable ("Runbook added to sop-secrets-management for Gmail app password rotation"). The deliverable is listed but not in AC.

Blast Radius

  • Other realms: Only westside-basketball realm needs SMTP now. The mcd-tracker realm exists but that project is archive-candidate per memory (feedback_archive_mcd_palemail.md). No blast radius concern.
  • Gmail account: The app password is scoped to Keycloak SMTP only. Gmail OAuth for app-level email sending (basketball-api, pal-e-mail) is a separate credential path. No conflict.
  • Downstream consumers: westside-app login flow, basketball-api execute-actions-email — both already expect SMTP to work. This unblocks them, does not break them.

Decomposition Check

  • 0 file targets in repo (API call only)
  • 1 SOP update in pal-e-docs
  • 5 acceptance criteria
  • Single realm, single API call
  • Fits single agent pass — no decomposition needed

Recommendation

Four items to resolve before moving to next_up:
  • Create a Forgejo issue on forgejo_admin/pal-e-platform for this work. The phase note is the design doc, but execution needs a Forgejo issue per kanban flow. Type: Task. The issue should reference the phase note and include the acceptance criteria.
  • Add arch:keycloak label to the board item to complete the traceability triangle.
  • Document the pre-requisite step: Lucas must manually generate a Gmail app password (requires Google account 2FA + app password generation in Google security settings). The phase note mentions this as a pre-req but does not specify who does it or the exact steps. Add a note that this is a manual Lucas gate before agent execution.
  • Add SOP deliverable to acceptance criteria: "Runbook for Gmail app password rotation added to sop-secrets-management" should be an AC, not just a deliverable.