fix(consuldemocracy): verify end-to-end + harden seed/OIDC [#653]

Seed verification over marker trust (observed exit-0 no-op seed),
first-boot-only OIDC auto-enable, logo added, docs synced (JOURNAL
s17, counts 17/~57). grind-stack verified: homepage 200, OIDC SSO
button live.

Detail: https://projects.knownelement.com/issues/653#note-5044
This commit is contained in:
2026-09-06 18:23:54 -05:00
parent 7c65dc18d3
commit 1bf9810071
7 changed files with 112 additions and 15 deletions
@@ -7,7 +7,17 @@
- postgresql + localstorage addons; Rails server on :3000
- Generated configs (database.yml / secrets.yml) under /app/data,
regenerated each boot; persisted secret_key_base
- First-boot db:create/migrate/seed with marker; gated delayed_job
worker; in-container memcached
- Platform OIDC wired into secrets.yml; local admin seeded
- First-boot db:create/migrate/seed with marker + empty-DB verification
(a stale marker against a fresh database re-seeds); gated delayed_job
worker; in-container memcached; assets:precompile at start (the app's
environment needs the DB, so precompile cannot run at build time)
- Platform OIDC wired into secrets.yml; `feature.oidc_login` auto-enabled
on first boot when the provider is present; local admin seeded
(admin@consul.dev — password change required on first login)
## Verification (2026-09-06)
Full-stack grind-stack test against ephemeral postgres: build green,
first boot ~5 min (migrate → seed [123 settings, admin] → OIDC enable →
precompile → delayed_job → Rails), homepage 200, login page renders the
`/users/auth/oidc` SSO button.
@@ -18,6 +18,9 @@ regenerates secrets.yml on every boot with the Cloudron platform
provider values (`CLOUDRON_OIDC_*`).
- SSO redirect: `https://<app-domain>/users/auth/oidc/callback`
- The SSO button (`feature.oidc_login`, default off upstream) is
auto-enabled on FIRST boot when the platform provider is present —
after that it's yours to toggle in Admin → Settings → Features.
- Local login stays available alongside SSO.
- SAML is also supported (saml_* keys in secrets.yml) if an external
IdP is preferred.
Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

@@ -97,11 +97,30 @@ memcached -d -p 11211 -u consul -m 64
# --- 3. database lifecycle -------------------------------------------------------
wait_tcp "${DB_HOST}" "${DB_PORT}" "PostgreSQL"
if [[ ! -f "${MARKER}" ]]; then
echo "First boot: creating + migrating + seeding the database ..."
# seed decision: the marker alone is not trusted - a marker left by a
# previous database (restore, migration, fresh test DB) must not skip
# seeding an empty one (observed: seed chain exits 0 yet persists
# nothing when re-run in the same first-boot process; a standalone
# re-seed lands fine, so verify + retry instead of debugging ghosts)
SEED_COUNT="$(bundle exec rails runner 'print Setting.count' 2>/dev/null || echo 0)"
if [[ ! -f "${MARKER}" || "${SEED_COUNT}" = "0" ]]; then
echo "First boot (or empty database): creating + migrating + seeding ..."
bundle exec rails db:create db:migrate db:seed
SEED_COUNT="$(bundle exec rails runner 'print Setting.count' 2>/dev/null || echo 0)"
if [[ "${SEED_COUNT}" = "0" ]]; then
echo "seed pass 1 did not persist - retrying standalone seed"
bundle exec rails db:seed
fi
touch "${MARKER}"
echo "Database seeded (local admin: admin@consul.dev - change the password!)"
# first-boot only: expose the SSO button when the platform provider is
# wired (feature.oidc_login defaults to false; operators can toggle it
# later in Admin > Settings > Features without us re-enabling it)
if [[ -n "${CLOUDRON_OIDC_CLIENT_ID:-}" ]]; then
bundle exec rails runner 'Setting["feature.oidc_login"] = true' || true
echo "OIDC login enabled (admin panel can toggle it)"
fi
else
bundle exec rails db:migrate
fi