Review: Bug: Keycloak issuer mismatch blocks login via auth.palinks.app (re-review)
Verdict: APPROVED
Re-review of board item #1572 after refinement. All 4 [BODY] recommendations from review-1572-2026-06-23 have been addressed. 1 [SCOPE] item (arch-rails-app note) carried forward but does not block this ticket.
Template Completeness
- [x] Type -- Bug
- [x] Lineage -- Standalone, discovered during session. Now includes cross-reference to pal-e-platform#455 with explicit independence statement.
- [x] Repo -- ldraney/landscaping-assistant
- [x] What Broke -- Issuer mismatch error with log evidence and code reference
- [x] Root Cause Fix -- NEW. Clearly specifies Rails-side fix with two options (discovery fetch vs KEYCLOAK_ISSUER env var). Explicitly scopes out Keycloak-side KC_HOSTNAME changes.
- [x] Repro Steps -- Clear 5-step repro
- [x] Expected Behavior -- present
- [x] Environment -- Cluster, pod env vars, Keycloak discovery issuer all documented
- [x] Acceptance Criteria -- 6 criteria, all testable (expanded from 4)
- [x] Related -- file paths, docs, and cross-repo reference to pal-e-platform#455
All required sections for a Bug template are present and well-filled.
Traceability
- [x] story:custom-domain label -- verified: "custom-domain" entry exists in project-landscaping-assistant user-stories section. Summary: "Access app via landscaping-assistant.app instead of Tailscale hostname."
- [x] story note verified -- found in project-landscaping-assistant user-stories table
- [ ] arch:rails-app label -- no matching arch note found in pal-e-docs (search for "arch-rails-app" returned empty). [SCOPE] Create architecture note arch-rails-app for the Rails application component. Carried forward from first review -- does not block this ticket since arch:rails-app is a shared label used on 30+ board items; the fix is fully scoped without it.
- [x] Forgejo issue -- ldraney/landscaping-assistant#259, open
File Targets
- [x]
config/initializers/omniauth.rb(line 20) -- verified: line 20 containsissuer: keycloak_configured ? "#{ENV["KEYCLOAK_URL"]}/realms/#{ENV["KEYCLOAK_REALM"]}" : "https://keycloak.test/realms/test". This is exactly where the mismatch originates. - [x]
app/controllers/sessions_controller.rb(line 48) -- verified: line 48 builds logout_url fromENV["KEYCLOAK_URL"]. Issue correctly notes this should continue using KEYCLOAK_URL. - [x]
app/services/keycloak_admin_service.rb-- verified: line 7 fetchesENV.fetch("KEYCLOAK_URL")as base_url. Admin API calls should not be affected by issuer-only fix. - [x]
docs/auth-strategy.md-- verified: exists, documents Auth Code + PKCE architecture - [x]
docs/keycloak-setup.md-- verified: exists, documents realm/client config
Repo Placement
OK. The Root Cause Fix section now explicitly states "Rails-side fix (this repo only)" and scopes out Keycloak hostname reconfiguration. The relationship to pal-e-platform#455 is documented in Lineage as independent.
Dependencies
- Board item #1504 (pal-e-platform#455, backlog, type:bug, story:custom-domain) -- documented in Lineage as the Keycloak server-side companion. Issue explicitly states this ticket does NOT depend on #455.
- Board item #1478 (landscaping-assistant#246, done) -- previous OmniAuth redirect_uri fix. Provides context for the custom-domain story arc.
- No blocking dependencies. Independent fix.
Acceptance Criteria
6 criteria, all testable:
- AC1 (login via landscaping-assistant.app): verifiable by manual test
- AC2 (login via Tailscale URL): regression check, verifiable
- AC3 (logout works): NEW -- addresses previous review finding. Verifiable by checking end-session redirect.
- AC4 (KeycloakAdminService): NEW -- addresses previous review finding. Verifiable by testing profile edit.
- AC5 (endpoint specs pass): verifiable via
bundle exec rspec - AC6 (KEYCLOAK_URL stays as auth.palinks.app): verifiable by inspecting k8s secret
All criteria are clear and agent-verifiable.
Blast Radius
KEYCLOAK_URLis referenced in 4 production files:omniauth.rb,application_controller.rb(presence check only),sessions_controller.rb(logout URL),keycloak_admin_service.rb(admin API base URL). The fix only changes issuer derivation inomniauth.rb-- other files continue using KEYCLOAK_URL as-is.- 8 spec files mock
KEYCLOAK_URL(12+ references). Specs should not need changes unless a new env var is introduced, in which case onlyomniauth.rb-related specs need updating. - Root Cause Fix section correctly identifies that KEYCLOAK_URL must remain usable for logout and admin API -- only issuer validation changes.
Decomposition Assessment
2-3 file targets in 1 repo, 6 acceptance criteria. Estimated agent work under 5 minutes for the Rails-side issuer override. No decomposition needed.
Refinement Verification (re-review)
Previous review: review-1572-2026-06-23 (NEEDS_REFINEMENT, 5 items)
- [x] [BODY] Root Cause Fix section added -- specifies Rails-side fix with two options, scopes out Keycloak-side changes
- [x] [BODY] Dependencies documented in Lineage -- pal-e-platform#455 referenced, independence stated
- [x] [BODY] AC for logout added -- AC3 covers end-session redirect
- [x] [BODY] AC for KeycloakAdminService added -- AC4 covers profile edit
- [ ] [SCOPE] arch-rails-app note still missing -- carried forward, does not block ticket
Recommendations
- [SCOPE] Create architecture note arch-rails-app for the Rails application component (carried forward from first review -- low priority, affects 30+ board items, not specific to this ticket).
No other action needed. Ticket is APPROVED for implementation.