Review: Bug: Keycloak issuer mismatch blocks login via auth.palinks.app
Verdict: NEEDS_REFINEMENT
Template Completeness
- [x] Type -- Bug
- [x] Lineage -- Standalone, discovered during session
- [x] Repo -- ldraney/landscaping-assistant
- [x] What Broke -- Issuer mismatch error with log evidence and code reference
- [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 -- 4 criteria, testable
- [x] Related -- file paths and docs referenced
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.
- [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]
docs/auth-strategy.md-- verified: exists, documents Auth Code + PKCE architecture - [x]
docs/keycloak-setup.md-- verified: exists, documents realm/client config. Notes KEYCLOAK_URL ashttps://keycloak.tail5b443a.ts.net(the old value before custom domain)
Repo Placement
ISSUE: The fix may not be fully contained in
ldraney/landscaping-assistant. The issue states "KEYCLOAK_URL remains https://auth.palinks.app in the k8s secret (do NOT revert to Tailscale URL)." This means the fix must either:- Override the issuer in OmniAuth config to use a separate env var (e.g.,
KEYCLOAK_ISSUER_URL) pointing to the Tailscale URL, OR - Configure Keycloak's
KC_HOSTNAMEto recognizeauth.palinks.appas its frontend URL -- this is a pal-e-platform/pal-e-services change.
Option (1) is a Rails-only fix in this repo. Option (2) is the proper fix but spans pal-e-platform and/or pal-e-services. The issue body does not clarify which approach to take. [BODY] Add a "Root Cause Fix" section specifying whether this is a Rails-side workaround (issuer override) or a Keycloak-side fix (KC_HOSTNAME), and if cross-repo, reference the companion issues.
Note: board item #1504 (pal-e-platform#455, type:bug, story:custom-domain) is in backlog and may be the companion Keycloak-side fix. If so, these two tickets should reference each other.
Dependencies
- Board item #1504 (pal-e-platform#455, backlog, type:bug, story:custom-domain) -- likely the Keycloak server-side companion. If this ticket does a Rails-side workaround, #1504 may be the proper Keycloak fix. If this ticket expects a Keycloak fix, it is blocked by #1504.
- Board item #1478 (landscaping-assistant#246, done) -- the previous OmniAuth redirect_uri fix. This ticket is a continuation of the custom-domain story.
- Board item #1461 (landscaping-assistant#224, done) -- Rails config.hosts + Keycloak redirect URIs. Already completed, provides context.
- Dependencies are not documented in the issue body. [BODY] Add a Dependencies section noting the relationship to pal-e-platform#455 and whether this ticket is blocked or independent.
Acceptance Criteria
The 4 criteria are testable:
- AC1 (login via landscaping-assistant.app): verifiable by manual test or curl
- AC2 (login via Tailscale URL): verifiable, good regression check
- AC3 (endpoint specs pass): verifiable via
bundle exec rspec - AC4 (KEYCLOAK_URL stays as auth.palinks.app): verifiable by inspecting k8s secret
Missing: No AC for logout working correctly. The
sessions_controller.rb line 48 also uses KEYCLOAK_URL for the logout redirect URL. If the fix introduces a separate issuer URL, logout must also be verified. [BODY] Add AC: "Logout via auth.palinks.app still redirects correctly."Missing: No AC for KeycloakAdminService. The
app/services/keycloak_admin_service.rb uses KEYCLOAK_URL for admin API calls (profile updates). If a separate issuer env var is introduced, admin calls should still route through the correct URL. [BODY] Add AC: "Profile edit (KeycloakAdminService) still works via auth.palinks.app."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). All 4 use the same env var. If the fix splits issuer from base URL, onlyomniauth.rbshould change -- the others should continue using the proxy URL.- 12+ spec files mock
KEYCLOAK_URL. A new env var would need corresponding spec updates. docs/keycloak-setup.mdstill documentsKEYCLOAK_URLashttps://keycloak.tail5b443a.ts.net-- this is stale now that production usesauth.palinks.app. Not in scope for this bug fix but worth noting.
Decomposition Assessment
2 file targets in 1 repo, 4 acceptance criteria. Estimated agent work under 5 minutes IF the approach is a Rails-side issuer override (add env var, update omniauth.rb, update specs). No decomposition needed for that approach. If the fix requires Keycloak-side changes (KC_HOSTNAME), that is a separate ticket in pal-e-platform -- but this ticket's scope is the Rails side only, so no decomposition needed here.
Recommendations
- [BODY] Add a "Root Cause Fix" section specifying whether this is a Rails-side workaround (issuer override env var) or a Keycloak-side fix (KC_HOSTNAME), and if cross-repo, reference companion issues.
- [BODY] Add a Dependencies section noting the relationship to pal-e-platform#455 and whether this ticket is blocked or independent.
- [BODY] Add AC: "Logout via auth.palinks.app still redirects correctly."
- [BODY] Add AC: "Profile edit (KeycloakAdminService) still works via auth.palinks.app."
- [SCOPE] Create architecture note arch-rails-app for the Rails application component (missing from pal-e-docs).