You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Tracks the Phase 1 rollout of the umbrella auth stack scaffolded in 6b3acd4.
Architecture and decisions: see the open-question discussion at CatholicOS/cdcf-website#98. Working assumptions are pinned in auth/README.md; will be revised if the Discussion thread shifts them.
Track 1 — Stand up the shared stack on the VPS
DNS: add A/AAAA records for auth.catholicdigitalcommons.org and authz.catholicdigitalcommons.org pointing at the existing VPS public IP.
Plesk subdomains: create both subdomains, enable Let's Encrypt, configure nginx reverse-proxy directives per auth/README.md (proxy to 127.0.0.1:8080 and 127.0.0.1:8081 respectively; pass X-Forwarded-Proto: https). (In practice routed via Plesk Docker Proxy Rules to the named containers — see docs/SYSADMIN.md §4.6. Equivalent outcome.)
VPS prep: create /var/lib/cdcf-auth/{zitadel-pgdata,zitadel-data,openfga-pgdata} bind-mount targets (zitadel-data must be world-writable per scratch-image PAT constraint). (Switched to host Postgres in PR refactor(auth): use host Postgres + make /opt/cdcf-auth/ paths explicit #2 — only /opt/cdcf-auth/runtime/zitadel-data/ is needed now; the *-pgdata dirs are no longer applicable.)
Secrets: copy auth/.env.production.example to .env.production on the VPS; generate ZITADEL_MASTERKEY (32 chars, NEVER rotated) and OPENFGA_PRESHARED_KEY; fill remaining DB passwords + admin credentials.
Bring-up: docker compose --env-file .env.production -f docker-compose.prod.yml up -d. Wait for healthchecks.
Smoke: curl http://127.0.0.1:8080/debug/ready and curl http://127.0.0.1:8081/healthz return 200. Public URLs serve the Zitadel console (/ui/console/) and OpenFGA health.
Backup wiring: install auth/backup/pg-dump.sh at /opt/cdcf-auth/backup/; add cron entry; copy first dump off-server within 24h. Confirm the masterkey is backed up separately, out-of-band. (Script tested manually 2026-05-16; cron not yet wired, no off-server copy yet. See docs/SYSADMIN.md §7.1 for procedure.)
The two setup-*.sh scripts are skeletons honouring the --target {local,production} convention from cdcf-website. They document the canonical operations and have the curl-based API helper plumbed, but the per-action calls are marked TODO. To complete:
Run the completed provisioning scripts on the VPS.
Write auth/handoffs/liturgicalcalendar.md per the template in auth/handoffs/README.md — issuer URL, Org name, Project ID, Client ID, OpenFGA store ID + model ID (all non-secret). Client secret + preshared key delivered out-of-band.
Open a follow-up issue on the LiturgicalCalendarAPI repo with the handoff embedded, asking the LitCal maintainer to point its prod env at the shared infra. (Liturgical-Calendar/LiturgicalCalendarAPI#597)
Track 4 — Pre-provision stubs for the other three properties
In the same --create-orgs run, the script also creates:
CDCF Org (no Project yet; cdcf-website wiring is deferred — prototype on feature/zitadel-integration needs rework to drop the v2 login UI before it can be merged against the shared infra).
BibleGet Org (no Project; BibleGet API at ~/development/BibleGet-I-O/endpoint currently has zero auth wiring — needs OIDC client work in its own repo before it can be wired).
OntoKit Org (no Project; OntoKit API has Zitadel client wiring in dev but no prod domain yet — defer until callbacks are stable).
Out of scope for this issue
Wiring cdcf-website / BibleGet / OntoKit (each in their own repo, separate phases).
E2E browser tests for the login flows (separate concern; LitCal validates JWTs server-side).
OpenFGA gRPC port exposure (HTTP-only at authz.*:443 for Phase 1; flip on if a consumer needs it).
pg_dump cron has produced ≥1 off-server backup of both DBs within 24h. ⏳ (script works manually; cron + off-server not yet wired — see remaining Track 1 checkbox)
Four Orgs visible in the Zitadel console: CDCF, LiturgicalCalendar, BibleGet, OntoKit. ✅
OpenFGA liturgical_calendar store exists with the lifted model applied. ✅ (store named LiturgicalCalendar)
Handoff doc exists; follow-up issue opened on the LitCal repo. ✅
Existing https://catholicdigitalcommons.org and https://cms.catholicdigitalcommons.org continue to serve normally (no regression). ✅
Status as of 2026-05-18: only remaining Phase 1 work is wiring the backup cron + off-server copy (Track 1 last checkbox + verification #4). Everything else complete.
Tracks the Phase 1 rollout of the umbrella auth stack scaffolded in 6b3acd4.
Architecture and decisions: see the open-question discussion at CatholicOS/cdcf-website#98. Working assumptions are pinned in
auth/README.md; will be revised if the Discussion thread shifts them.Track 1 — Stand up the shared stack on the VPS
auth.catholicdigitalcommons.organdauthz.catholicdigitalcommons.orgpointing at the existing VPS public IP.auth/README.md(proxy to127.0.0.1:8080and127.0.0.1:8081respectively; passX-Forwarded-Proto: https). (In practice routed via Plesk Docker Proxy Rules to the named containers — seedocs/SYSADMIN.md§4.6. Equivalent outcome.)/var/lib/cdcf-auth/{zitadel-pgdata,zitadel-data,openfga-pgdata}bind-mount targets (zitadel-data must be world-writable per scratch-image PAT constraint). (Switched to host Postgres in PR refactor(auth): use host Postgres + make /opt/cdcf-auth/ paths explicit #2 — only/opt/cdcf-auth/runtime/zitadel-data/is needed now; the*-pgdatadirs are no longer applicable.)auth/.env.production.exampleto.env.productionon the VPS; generateZITADEL_MASTERKEY(32 chars, NEVER rotated) andOPENFGA_PRESHARED_KEY; fill remaining DB passwords + admin credentials.docker compose --env-file .env.production -f docker-compose.prod.yml up -d. Wait for healthchecks.curl http://127.0.0.1:8080/debug/readyandcurl http://127.0.0.1:8081/healthzreturn 200. Public URLs serve the Zitadel console (/ui/console/) and OpenFGA health.auth/backup/pg-dump.shat/opt/cdcf-auth/backup/; add cron entry; copy first dump off-server within 24h. Confirm the masterkey is backed up separately, out-of-band. (Script tested manually 2026-05-16; cron not yet wired, no off-server copy yet. Seedocs/SYSADMIN.md§7.1 for procedure.)Track 2 — Bootstrap provisioning scripts (currently SKELETON)
The two
setup-*.shscripts are skeletons honouring the--target {local,production}convention from cdcf-website. They document the canonical operations and have the curl-based API helper plumbed, but the per-action calls are marked TODO. To complete:setup-zitadel.sh --create-orgs: implement the idempotent Org-create loop againstPOST /management/v1/orgs. List existing orgs first; skip names already present. (PR feat(scripts): flesh out setup-zitadel.sh + setup-openfga.sh; provision LitCal #5)setup-zitadel.sh --provision-litcal: implement Project + API OIDC app + roles under the LiturgicalCalendar Org. Lift role keys fromLiturgicalCalendarAPI/src/Services/ZitadelService.php. (PR feat(scripts): flesh out setup-zitadel.sh + setup-openfga.sh; provision LitCal #5 — plus--provision-litcal-frontendfor the PKCE app added in PR feat(setup-zitadel): --provision-litcal-frontend (Web/PKCE app) + handoff update #6)setup-openfga.sh --create-store liturgical_calendar: implement store create + authorization model upload. Addauth/models/liturgical_calendar.fga(or .json) lifted from LitCal's dev stack. (PR feat(scripts): flesh out setup-zitadel.sh + setup-openfga.sh; provision LitCal #5 — stored atauth/models/LiturgicalCalendar.json)Track 3 — Hand off LiturgicalCalendarAPI
auth/handoffs/liturgicalcalendar.mdper the template inauth/handoffs/README.md— issuer URL, Org name, Project ID, Client ID, OpenFGA store ID + model ID (all non-secret). Client secret + preshared key delivered out-of-band.Track 4 — Pre-provision stubs for the other three properties
In the same
--create-orgsrun, the script also creates:CDCFOrg (no Project yet; cdcf-website wiring is deferred — prototype onfeature/zitadel-integrationneeds rework to drop the v2 login UI before it can be merged against the shared infra).BibleGetOrg (no Project; BibleGet API at~/development/BibleGet-I-O/endpointcurrently has zero auth wiring — needs OIDC client work in its own repo before it can be wired).OntoKitOrg (no Project; OntoKit API has Zitadel client wiring in dev but no prod domain yet — defer until callbacks are stable).Out of scope for this issue
authz.*:443for Phase 1; flip on if a consumer needs it).Verification
Per
auth/README.md:https://auth.catholicdigitalcommons.org/debug/readyreturns 200 from the public internet. ✅https://auth.catholicdigitalcommons.org/ui/console/loads; IAM-OWNER credentials log in (forced password change works). ✅https://authz.catholicdigitalcommons.org/healthzreturns 200. ✅pg_dumpcron has produced ≥1 off-server backup of both DBs within 24h. ⏳ (script works manually; cron + off-server not yet wired — see remaining Track 1 checkbox)liturgical_calendarstore exists with the lifted model applied. ✅ (store namedLiturgicalCalendar)https://catholicdigitalcommons.organdhttps://cms.catholicdigitalcommons.orgcontinue to serve normally (no regression). ✅Status as of 2026-05-18: only remaining Phase 1 work is wiring the backup cron + off-server copy (Track 1 last checkbox + verification #4). Everything else complete.