fix(oidc): register SPA clients from env-driven startup upsert (BUNYIP-57) #75
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fix/bunyip-57-env-driven-oidc-client-seed"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Problem
The static migration
20260603000010_register_mokosh_apps_and_drillmark_oidc_clients.sqlseeds themokosh-appsanddrillmarkOIDC clients with hardcoded staging (a8n.systems)redirect_uris,post_logout_redirect_uris, andaudience.sqlx::migrate!runs that SQL verbatim on every database regardless ofENVIRONMENT, so on the nc-01 production deployment (psa.systems) the authorize handler's exact-stringredirect_urimatch (crates/bunyip-oidc/src/handlers/oidc.rs) fails and production PKCE login breaks before any token is minted. The mintedat+jwtalso carries the stagingaudience, which mokosh-server rejects against itsOIDC_AUDIENCE. This blocks DEV-362.Change
Move per-environment client registration out of the env-blind migration into an idempotent, env-driven startup upsert in
bunyip-api/src/main.rs, mirroring the existingSETUP_DEFAULT_ADMINseed block. After migrations, for each SPA client read per-client env vars (MOKOSH_APPS_*,DRILLMARK_*) viasecret_env(so the{NAME}_FILEcompose-secret convention works and empty counts as unset) and upsert keyed on the fixedclient_idUUID. Onlyredirect_uris,post_logout_redirect_uris, andaudienceare written; all other columns keep their migration-defined values viaON CONFLICT (client_id) DO UPDATEof just those three columns. Startup is therefore authoritative and self-healing: it corrects the stale staging row in place.drillmarkstays unregistered on nc-01 until its vars are set, whilemokosh-appsis corrected.*_REDIRECT_URIS/*_POST_LOGOUT_REDIRECT_URISare split on commas because the columns areTEXT[].20260603000010stays as-is; itsON CONFLICT DO NOTHINGis harmless once the startup upsert is authoritative.Follow-up (DEV-362)
Set the
MOKOSH_APPS_*(and eventuallyDRILLMARK_*) values in each env'scompose-variables.yml:psa.systemsvalues for nc-01,a8n.systemsvalues for c-01 (no churn on staging).Verification
just check-containergreen:cargo fmt --check,cargo clippy --workspace --all-targets -D warnings,cargo test --workspace --liball pass.Closes BUNYIP-57.
The static migration 20260603000010 seeds the mokosh-apps and drillmark OIDC clients with hardcoded staging (a8n.systems) redirect_uris, post_logout_redirect_uris, and audience. sqlx::migrate! runs that SQL verbatim on every database regardless of ENVIRONMENT, so the authorize handler's exact-string redirect_uri match fails on psa.systems and production PKCE login breaks before any token is minted; the minted at+jwt also carries the wrong audience for the RS to verify. Move per-environment client registration out of the env-blind migration into an idempotent, env-driven startup upsert in main.rs, mirroring the SETUP_DEFAULT_ADMIN seed block. After migrations, for each SPA client read per-client env vars (MOKOSH_APPS_* and DRILLMARK_*, via secret_env so the {NAME}_FILE secret convention works and empty counts as unset) and upsert keyed on the fixed client_id UUID. Only redirect_uris, post_logout_redirect_uris, and audience are written; all other columns keep their migration-defined values via ON CONFLICT DO UPDATE of just those three columns. This makes startup authoritative and self-healing: it corrects the stale staging row in place. Each client is env-gated: with its vars unset the upsert is skipped and logged, so drillmark stays unregistered on nc-01 (not yet deployed) while mokosh-apps is corrected. The *_REDIRECT_URIS / *_POST_LOGOUT_REDIRECT_URIS vars are comma-separated since the columns are TEXT[]. Migration 20260603000010 stays as-is; its ON CONFLICT DO NOTHING is harmless once the startup upsert is authoritative. Companion deployment change (the MOKOSH_APPS_* / DRILLMARK_* compose-variables values per env) is tracked under DEV-362. #BUNYIP-57 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>Gate the SPA OIDC client registration on only the two env vars login actually requires, *_REDIRECT_URIS and *_AUDIENCE, and treat *_POST_LOGOUT_REDIRECT_URIS as optional (the column is TEXT[] DEFAULT '{}'). Previously the upsert required all three vars and skipped the whole client when any was unset; a partial config (redirect + audience set, post-logout forgotten) would silently log "env vars unset" and leave the stale a8n.systems row in place, masking the very bug this change fixes. Now an absent post-logout var upserts an empty array instead of aborting registration. #BUNYIP-57 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>