Keep the application and local recovery login available when OIDC discovery fails #2

Closed
opened 2026-10-24 13:24:18 +00:00 by jchapman · 4 comments
Owner

A saved OIDC issuer with a trailing slash did not match the issuer advertised by discovery. After restart, the application exited repeatedly, making local administrator login unavailable as well. Recovery required the operator’s ignore-saved-settings switch.

OIDC failure must disable only that sign-in method, not the whole application.

Acceptance criteria:

  • Keep the web application and enabled local recovery login available if discovery, connectivity or provider initialization fails.
  • Fail closed for SSO; preserve issuer, signature, audience, state, nonce and PKCE validation. Do not normalize away a genuine issuer mismatch.
  • Show a clear SSO-unavailable state and a safe administrator diagnostic.
  • Validate discovery before accepting configuration where practical, while handling later provider outages.
  • Make retry/recovery behavior explicit and bounded.
  • Test mismatched issuers, unavailable discovery, invalid discovery responses and recovery after the provider returns. No credentials or raw token responses in logs.
A saved OIDC issuer with a trailing slash did not match the issuer advertised by discovery. After restart, the application exited repeatedly, making local administrator login unavailable as well. Recovery required the operator’s ignore-saved-settings switch. OIDC failure must disable only that sign-in method, not the whole application. Acceptance criteria: - Keep the web application and enabled local recovery login available if discovery, connectivity or provider initialization fails. - Fail closed for SSO; preserve issuer, signature, audience, state, nonce and PKCE validation. Do not normalize away a genuine issuer mismatch. - Show a clear SSO-unavailable state and a safe administrator diagnostic. - Validate discovery before accepting configuration where practical, while handling later provider outages. - Make retry/recovery behavior explicit and bounded. - Test mismatched issuers, unavailable discovery, invalid discovery responses and recovery after the provider returns. No credentials or raw token responses in logs.
Author
Owner

Starting implementation of #2 after reading #14 and this issue (neither currently has comments). Scope: decouple OIDC provider availability from application/local recovery availability, retain strict SSO verification, expose safe availability diagnostics, validate changed OIDC settings before saving where practical, and add bounded recovery plus regression coverage. I will inspect current startup/authentication/settings behavior and run focused checks before recording results. No deployment, rebuild, or restart of running services is planned.

Starting implementation of #2 after reading #14 and this issue (neither currently has comments). Scope: decouple OIDC provider availability from application/local recovery availability, retain strict SSO verification, expose safe availability diagnostics, validate changed OIDC settings before saving where practical, and add bounded recovery plus regression coverage. I will inspect current startup/authentication/settings behavior and run focused checks before recording results. No deployment, rebuild, or restart of running services is planned.
Author
Owner

Implementation and local validation complete in commit b84688d (branch codex/issue-2-oidc-availability), published for review as draft PR #16: #16

Changes:

  • Discovery/configuration failures disable SSO without terminating Bridge or enabled local recovery login. No issuer normalization or verification bypasses were added.
  • Five-second discovery timeout; one background check one minute after each completed check, with automatic disable/recovery, synchronized provider snapshots and cancellable shutdown. Existing sessions survive provider outages; callbacks retain strict token/state/nonce/PKCE validation and their 15-second timeout.
  • Login availability message with periodic/focus refresh; administrator-only fixed diagnostics with last/next check times. No credentials, raw provider responses or token data are logged by these failure paths or returned in diagnostics.
  • Changed issuer/client/secret settings pass discovery before saving. Retained/cleared secrets use the same effective-value logic as saving. Preflight does not hold the import admission lock; revisions prevent stale writes. Unrelated changes and disabling SSO remain available during outages.
  • Added documentation and included auth race/browser regressions in CI.

Checks actually run and passed:

  • Complete Go backend suite (go test -count=1 -timeout 120s ./cmd/... ./internal/...) in a disposable Linux AMD64 container with Go 1.27.3 and the existing pinned importer test binary.
  • Final focused authentication/configuration/admin-settings race tests and go vet ./cmd/... ./internal/.... Coverage includes issuer/trailing-slash mismatch, unavailable/invalid discovery, invalid endpoints/algorithms, timeout/shutdown, local recovery, concurrent availability changes, signed login after automatic recovery, session continuity and token/correlation rejection.
  • UI lint and production build; focused Playwright browser regression, including mobile recovery controls, outage/recovery refresh, no-local-login/unconfigured states, administrator diagnostics and distinction between saved/running settings. Screenshots inspected locally.
  • All nine CI contract/policy tests, documentation link/encoding checks and git diff --check. The initial system-Python contract run lacked PyYAML; rerunning with the repository's hash-pinned dependency in an ignored test folder passed. The UI build has its existing large-chunk advisory.

State and limits: committed, locally tested and published as a draft; not merged or deployed. No running service or upload/import was restarted or interrupted. Native AMD64/ARM64 release gates, full container/production walkthroughs and the real deployed provider walkthrough were not run here. Discovery is not a client-secret, provider-assignment or complete endpoint-health test; test the actual assigned-user sign-in after applying settings.

Next handoff: review #16. It is stacked on #15 to preserve the current checkout baseline; after #15 merges, retarget #16 to main, verify the resulting diff and required native CI gates, and then coordinate any deployment/restart with active work. Validate real-provider outage/recovery and local administrator access before closing #2. This issue remains open.

Implementation and local validation complete in commit `b84688d` (branch `codex/issue-2-oidc-availability`), published for review as draft PR #16: https://git.sharedroot.net/jchapman/Immich-Bridge/pulls/16 Changes: - Discovery/configuration failures disable SSO without terminating Bridge or enabled local recovery login. No issuer normalization or verification bypasses were added. - Five-second discovery timeout; one background check one minute after each completed check, with automatic disable/recovery, synchronized provider snapshots and cancellable shutdown. Existing sessions survive provider outages; callbacks retain strict token/state/nonce/PKCE validation and their 15-second timeout. - Login availability message with periodic/focus refresh; administrator-only fixed diagnostics with last/next check times. No credentials, raw provider responses or token data are logged by these failure paths or returned in diagnostics. - Changed issuer/client/secret settings pass discovery before saving. Retained/cleared secrets use the same effective-value logic as saving. Preflight does not hold the import admission lock; revisions prevent stale writes. Unrelated changes and disabling SSO remain available during outages. - Added documentation and included auth race/browser regressions in CI. Checks actually run and passed: - Complete Go backend suite (`go test -count=1 -timeout 120s ./cmd/... ./internal/...`) in a disposable Linux AMD64 container with Go 1.27.3 and the existing pinned importer test binary. - Final focused authentication/configuration/admin-settings race tests and `go vet ./cmd/... ./internal/...`. Coverage includes issuer/trailing-slash mismatch, unavailable/invalid discovery, invalid endpoints/algorithms, timeout/shutdown, local recovery, concurrent availability changes, signed login after automatic recovery, session continuity and token/correlation rejection. - UI lint and production build; focused Playwright browser regression, including mobile recovery controls, outage/recovery refresh, no-local-login/unconfigured states, administrator diagnostics and distinction between saved/running settings. Screenshots inspected locally. - All nine CI contract/policy tests, documentation link/encoding checks and `git diff --check`. The initial system-Python contract run lacked PyYAML; rerunning with the repository's hash-pinned dependency in an ignored test folder passed. The UI build has its existing large-chunk advisory. State and limits: committed, locally tested and published as a draft; not merged or deployed. No running service or upload/import was restarted or interrupted. Native AMD64/ARM64 release gates, full container/production walkthroughs and the real deployed provider walkthrough were not run here. Discovery is not a client-secret, provider-assignment or complete endpoint-health test; test the actual assigned-user sign-in after applying settings. Next handoff: review #16. It is stacked on #15 to preserve the current checkout baseline; after #15 merges, retarget #16 to `main`, verify the resulting diff and required native CI gates, and then coordinate any deployment/restart with active work. Validate real-provider outage/recovery and local administrator access before closing #2. This issue remains open.
Author
Owner

Integration handoff: PR #16 is merged into main in fc14673. The final combined source passed local backend/vet/race, UI/browser, container/isolation/HTTPS, source/image policy and secret checks. Detailed merge/conflict evidence and limitations: #14 (comment). Native Forgejo AMD64/ARM64 release validation remains queued; no release images or deployment are claimed. This issue remains open for its pilot checkpoint. Verify real-provider outage/recovery and local administrator access after a coordinated idle deployment. No active upload/task or pilot service was interrupted.

Integration handoff: PR #16 is merged into main in `fc14673`. The final combined source passed local backend/vet/race, UI/browser, container/isolation/HTTPS, source/image policy and secret checks. Detailed merge/conflict evidence and limitations: https://git.sharedroot.net/jchapman/Immich-Bridge/issues/14#issuecomment-175. Native Forgejo AMD64/ARM64 release validation remains queued; no release images or deployment are claimed. This issue remains open for its pilot checkpoint. Verify real-provider outage/recovery and local administrator access after a coordinated idle deployment. No active upload/task or pilot service was interrupted.
Author
Owner

Final development handoff: PR #16 is merged into main in fc14673, preserving feature commit(s) b84688d.

OIDC discovery failures now disable SSO while Bridge and enabled local recovery remain available. Strict issuer/token/state/nonce/PKCE checks, bounded discovery/retry, safe administrator diagnostics and configuration preflight are preserved.

Validation: Authentication/configuration regressions and races, signed recovery/rejection fixtures and the OIDC browser suite passed, including mismatch, invalid discovery, outage and automatic recovery. The combined application also passed backend/vet/race, UI lint/build, container/HTTPS, source/image policies and secret checks; integration evidence.

Documentation is updated on main through PR #21, merge 5ed7191: feature guide, merged scope/evidence, and remaining pilot checks. All nine documentation/policy tests and link/anchor/workflow checks passed.

Closing at the owner's explicit request after merge, local validation and documentation review. This supersedes the earlier request to keep this development issue open through deployment. Native Forgejo AMD64/ARM64 release gates, coordinated idle installation and applicable real-provider/owner pilot checks remain in the release checklist and coordination issue #14. No deployment, native ARM64 pass, real-library capacity result or gate waiver is claimed. PR #19 and scanning remain on hold.

Final development handoff: [PR #16](https://git.sharedroot.net/jchapman/Immich-Bridge/pulls/16) is merged into main in `fc14673`, preserving feature commit(s) `b84688d`. OIDC discovery failures now disable SSO while Bridge and enabled local recovery remain available. Strict issuer/token/state/nonce/PKCE checks, bounded discovery/retry, safe administrator diagnostics and configuration preflight are preserved. Validation: Authentication/configuration regressions and races, signed recovery/rejection fixtures and the OIDC browser suite passed, including mismatch, invalid discovery, outage and automatic recovery. The combined application also passed backend/vet/race, UI lint/build, container/HTTPS, source/image policies and secret checks; [integration evidence](https://git.sharedroot.net/jchapman/Immich-Bridge/issues/14#issuecomment-175). Documentation is updated on main through [PR #21](https://git.sharedroot.net/jchapman/Immich-Bridge/pulls/21), merge `5ed7191`: [feature guide](https://git.sharedroot.net/jchapman/Immich-Bridge/src/branch/main/docs/oidc.md), [merged scope/evidence](https://git.sharedroot.net/jchapman/Immich-Bridge/src/branch/main/docs/integration-status.md), and [remaining pilot checks](https://git.sharedroot.net/jchapman/Immich-Bridge/src/branch/main/docs/deployment.md#merged-pilot-feature-checks). All nine documentation/policy tests and link/anchor/workflow checks passed. Closing at the owner's explicit request after merge, local validation and documentation review. This supersedes the earlier request to keep this development issue open through deployment. Native Forgejo AMD64/ARM64 release gates, coordinated idle installation and applicable real-provider/owner pilot checks remain in the release checklist and coordination issue #14. No deployment, native ARM64 pass, real-library capacity result or gate waiver is claimed. PR #19 and scanning remain on hold.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set

Reference
jchapman/Immich-Bridge#2
No description provided.