From f5537d8365eb60c35bb5c7cf56c14d2a94f3012a Mon Sep 17 00:00:00 2001 From: tegwick Date: Sun, 9 Aug 2026 23:20:30 +0200 Subject: [PATCH] Serve the rebuild on app.coulomb.social; defer apex Bubble cutover Document parallel-host strategy: Railiance on app.*, Bubble remains on coulomb.social until data and self-registration are ready. --- INTENT.md | 2 +- docs/deploy.md | 113 ++++++++++------------------------- docs/identity/oidc-client.md | 3 +- docs/identity/smoke.md | 17 +++--- 4 files changed, 46 insertions(+), 89 deletions(-) diff --git a/INTENT.md b/INTENT.md index e97e3cc..b74fcdf 100644 --- a/INTENT.md +++ b/INTENT.md @@ -23,7 +23,7 @@ This repository is the **owning home** for the rebuild: 1. **Parity capture** — inventory and export everything that matters in the bubble.io app (UI surfaces, workflows, data types, content, integrations). 2. **Cut decisions** — decide rebuild-as-is vs reduced v1 with an explicit human gate. 3. **Implementation** — deliver a standalone service on the proven business delivery lane (`vergabe-teilnahme` evidence), under the business-app service contract. -4. **Cutover** — migrate members and content off bubble.io when the new stack is ready. +4. **Cutover** — serve the rebuild on **`app.coulomb.social`** in parallel with Bubble on apex `coulomb.social`; retire Bubble only when data, self-registration, and content parity are ready. Binky Hedgehog GmbH is **client #1** of its own platform (DR-2 B). The app is not a Core Hub extension; it is a normal client-facing business application. diff --git a/docs/deploy.md b/docs/deploy.md index 96c6a83..a43f6a6 100644 --- a/docs/deploy.md +++ b/docs/deploy.md @@ -9,118 +9,71 @@ railiance01 (same lane as `vergabe-teilnahme`). Chart/values/ingress live in **`railiance-apps`** (`helm/coulomb-social-values.yaml`, `docs/coulomb-social.md`). -## Current cluster status (2026-08-09) +## Host strategy + +| Host | Role | +|------|------| +| **`https://app.coulomb.social`** | **Live** Railiance rebuild (identity shell now; product later) | +| **`https://coulomb.social`** | **Bubble.io** until data + self-registration + content ready | +| `http://127.0.0.1:8008` | Local OIDC/dev | + +Apex DNS cutover is **deferred**. Retire Bubble only after an explicit decision. + +## Current cluster status | Item | State | |------|--------| -| Namespace | `coulomb-social` Active | -| Deployment | 1/1 Ready, image `:7067145` | -| Service | ClusterIP :80 | -| Ingress | `coulomb.social` → Traefik, cert-manager annotation | -| Env secret | `coulomb-social-env` (`SECRET_KEY`, `DATABASE_URL`, `USER_ENGINE_PROXY_SECRET`) | -| OIDC | enabled; issuer `https://kc.coulomb.social`; public client | -| Public DNS | **still Cloudflare / Bubble** | -| TLS secret | **pending** HTTP-01 until DNS points at the cluster | - -In-cluster smoke (with `Host: coulomb.social`): `/healthz` ok, landing 200, -`/auth/login/` → KeyCape authorize. Full browser session needs cutover. +| Namespace | `coulomb-social` | +| Public host | **`app.coulomb.social`** | +| OIDC redirect | `https://app.coulomb.social/auth/callback/` | +| Apex Bubble | unchanged | ## Runtime secrets (names only) -K8s Secret `coulomb-social-env` in namespace `coulomb-social` (chart `envFrom`): - -| Key | Source | -|-----|--------| -| `SECRET_KEY` | generated by env-secret script | -| `DATABASE_URL` | cnpg app role secret (URL-encoded password) | -| `USER_ENGINE_PROXY_SECRET` | `user-engine/user-engine-runtime` | +K8s Secret `coulomb-social-env` (`SECRET_KEY`, `DATABASE_URL`, `USER_ENGINE_PROXY_SECRET`). ```bash -# from railiance-apps: +# railiance-apps: make coulomb-social-env-secret-dry-run make coulomb-social-env-secret - -# from this repo: -./scripts/create-env-secret.sh --dry-run -./scripts/create-env-secret.sh ``` OIDC is a **public** client — no client secret. -Non-secret env (OIDC, ALLOWED_HOSTS, user-engine URL) lives in Helm values. - ## Health - `GET /healthz` → `{"status":"ok","service":"coulomb-social"}` -- Probes use `Host: coulomb.social` (`probes.hostHeader`) +- Probes use `Host: app.coulomb.social` ## Build / deploy ```bash SHA=$(git rev-parse --short HEAD) docker build -t forgejo.coulomb.social/coulomb/coulomb-social:$SHA . -# push, then: # COULOMB_SOCIAL_IMAGE_TAG=$SHA make coulomb-social-deploy # in railiance-apps +# make coulomb-social-ingress-deploy ``` -## Cutover checklist (DNS → live Railiance) +## Parallel host go-live checklist -**Goal:** `https://coulomb.social` serves this app (identity shell), not Bubble. +1. [x] Helm env / ingress use `app.coulomb.social` +2. [x] KeyCape redirects include `https://app.coulomb.social/auth/callback/` +3. [ ] DNS: `app.coulomb.social` **A → `92.205.62.239`** (prefer DNS-only for LE) +4. [ ] `certificate/coulomb-social-tls` Ready for `app.coulomb.social` +5. [ ] `curl -fsS https://app.coulomb.social/healthz` +6. [ ] Browser Sign in as tegwick → `/app/` -### Preconditions +## Future apex cutover (not now) -1. [x] Image + Helm release healthy -2. [x] KeyCape client `coulomb-social` with prod redirect `https://coulomb.social/auth/callback/` -3. [x] In-cluster OIDC start redirect works -4. [ ] Local browser OIDC + MFA completed once (proves IdP + user-engine path) -5. [ ] Operator accepts brief public outage / Bubble freeze during DNS switch -6. [ ] Optional: export Bubble data if still needed (CSOC-WP-0001) — not required for identity-only cutover +When Bubble can retire: -### DNS switch +1. Point `coulomb.social` A at the cluster (or reverse-proxy) +2. Switch Helm `ALLOWED_HOSTS` / `OIDC_REDIRECT_URI` / ingress host if apex becomes canonical +3. Keep or drop `app.` as redirect alias -1. In Cloudflare (or DNS host): lower TTL on `coulomb.social` if possible (e.g. 300s) ahead of time. -2. Point apex (and `www` if used) **A** to **`92.205.62.239`** (railiance01 ingress). - - Prefer DNS-only (grey cloud) first so LE HTTP-01 and Traefik see real traffic; re-enable proxy only if you understand TLS termination path. -3. Wait for propagation: `dig +short coulomb.social A` → `92.205.62.239`. -4. cert-manager should finish HTTP-01; confirm: - - ```bash - kubectl -n coulomb-social get certificate coulomb-social-tls - # READY=True - ``` - -5. Smoke public HTTPS: - - ```bash - curl -fsS https://coulomb.social/healthz - curl -sI https://coulomb.social/auth/login/ | grep -i location - # Location: https://kc.coulomb.social/authorize?... - ``` - -6. **Browser:** Sign in → Authelia MFA → land on `/app/` with principal. -7. Sign out; confirm `/app/` requires login. -8. Second login: same member row / user-engine user_id. - -### Rollback - -- Point DNS A (or Cloudflare origin) back to Bubble/Cloudflare target. -- Cluster release can stay; it only receives traffic when DNS aims at the node. - -### After cutover residuals - -| Item | Note | -|------|------| -| Bubble freeze | Stop editing live Bubble as source of truth | -| Content/UI | CSOC-WP-0001 + design extract — not required for identity shell | -| flex-auth Service | leave `FLEX_AUTH_BASE_URL` unset (local vocabulary) until PDP exists | -| apps-pg backup/HA | business-app contract | -| OpenBao CCR | replace kubectl-sourced env secret when ready | -| Image CI | Forgejo/Gitea pipeline for SHA tags | - -## Local verification (no cutover) +## Local verification ```bash make test -make run # offline identity -# or OIDC vars from docs/identity/oidc-client.md +make run # offline or local OIDC redirect ``` diff --git a/docs/identity/oidc-client.md b/docs/identity/oidc-client.md index 2dedd7f..c3d05b0 100644 --- a/docs/identity/oidc-client.md +++ b/docs/identity/oidc-client.md @@ -10,7 +10,8 @@ Non-secret registration checklist for NetKingdom IAM Profile issuers. | client_id | `coulomb-social` | | client_type | **public** (no client secret; PKCE only) | | redirect_uri (dev) | `http://127.0.0.1:8008/auth/callback/` · `http://localhost:8008/auth/callback/` | -| redirect_uri (prod) | `https://coulomb.social/auth/callback/` | +| redirect_uri (public app) | `https://app.coulomb.social/auth/callback/` (**live** host while Bubble keeps apex) | +| redirect_uri (apex future) | `https://coulomb.social/auth/callback/` (registered; cutover deferred) | | scopes | `openid profile email groups` | | grant | authorization_code | | wildcard redirects | **forbidden** | diff --git a/docs/identity/smoke.md b/docs/identity/smoke.md index 0d1cca2..3739f32 100644 --- a/docs/identity/smoke.md +++ b/docs/identity/smoke.md @@ -90,12 +90,15 @@ Unregistered redirects still fail with `invalid_profile_usage` (T03). make test ``` -## Blockers for production hostname smoke +## Public host (parallel to Bubble) -| Blocker | Detail | -|---------|--------| -| Public DNS | `coulomb.social` → Cloudflare `104.*` (Bubble), not `92.205.62.239` | -| TLS cert | `certificate/coulomb-social-tls` **not Ready**; HTTP-01 challenge gets **404** from public edge (LE never reaches cluster solver) | -| Secure cookies | prod `SESSION_COOKIE_SECURE=True` — need HTTPS after cutover | +**Strategy:** live Railiance app on **`app.coulomb.social`**; apex **`coulomb.social`** stays Bubble until content + self-registration cutover. -See cutover steps in `docs/deploy.md`. +| Check | Detail | +|-------|--------| +| Cluster host | `app.coulomb.social` (Helm + ingress) | +| OIDC redirect | `https://app.coulomb.social/auth/callback/` | +| DNS | operator: `app.coulomb.social` A → `92.205.62.239` | +| Apex | **do not** repoint until Bubble retirement | + +See `docs/deploy.md`. \ No newline at end of file