--- id: RPF-WP-0025 type: workplan title: "Retract public OpenBao listener behind operator-only access" domain: financials repo: railiance-platform status: finished flavor: implementation owner: codex topic_slug: railiance created: "2026-08-23" updated: "2026-09-22" related: - RMASTER-WP-0020-T09 - RAPP-OPENBAO-WP-0002 state_hub_workstream_id: "6dda6039-295e-5cac-aef6-3183c3218649" --- # RPF-WP-0025 — OpenBao operator-only access ## Goal Implement the S3-owner half of RMASTER-WP-0020-T09 without coupling it to destructive CoulombCore cleanup. ## T01 — Align the retained compatibility source ```task id: RPF-WP-0025-T01 status: done priority: high state_hub_task_id: "80f9638f-707f-5038-bc77-5962b535949e" ``` The retained platform manifest now matches the canonical package posture: Deployment plus ClusterIP Service only. Ordinary deploy no longer applies the public-only middleware. The old Ingress remains solely in an explicitly named rollback artifact. ## T02 — Add guarded retraction and rollback ```task id: RPF-WP-0025-T02 status: done priority: high state_hub_task_id: "685aba0f-2594-5b99-903a-8c9cd16f6539" ``` `scripts/openbao-public-listener-transition.sh` pins the cluster UID, verifies source and runtime packet posture, requires a lifecycle-healthy named tunnel, and gates live deletion on exact confirmation plus attended-login verification. It deletes only the Ingress and provides an exact rollback path. ## T03 — Complete the attended operator cutover ```task id: RPF-WP-0025-T03 status: done priority: high state_hub_task_id: "8850d742-7cd7-5a1b-ba52-4dbc4bdeba7e" ``` KeyCape revision `d150be1` now admits exactly `http://127.0.0.1:18200/ui/vault/auth/netkingdom/oidc/callback` in the source-owned `openbao-admin` client and pins it in configuration tests. The OpenBao `auth/netkingdom/role/platform-admin` role must still independently admit that exact callback, and an attended MFA login must pass. The host-namespace preflight already proves `openbao-ui-railiance01` lifecycle-healthy and reaches the expected overlay. Then execute the guarded retraction, coordinate public DNS withdrawal with railiance-infra, and return non-secret acceptance evidence to Railiance Master. Net Kingdom revision `61aeafe` additionally applied the exact KeyCape callback live and proved the public authorization endpoint accepts it. Railiance Platform now carries the silent, narrowly scoped `scripts/openbao-apply-operator-loopback-callback.sh` owner command for the governed `openbao-platform-admin-login` lane. The remaining hold is one attended OIDC/MFA execution of that command followed by one loopback UI login. An attended attempt on 2026-08-23 failed closed before command handoff. Warden contained all login output and did not execute the role update; its cleanup could not confirm self-revocation, so the attempt is terminal NO-GO and must not be treated as callback evidence. No public-listener or OpenBao role change was made. T03 remains `wait` for a fresh attended execution after the operator is ready to complete the browser/MFA act. This workplan authorizes no OpenBao seal/unseal, policy broadening, PVC or Secret mutation, reboot, restore, or RMASTER-WP-0020-T08 cleanup. ## Portfolio review — 2026-09-05 INTENT binding: secure custody and an operable operator access path. Retain T03 as the one attended cutover task; do not merge its approval/window with incident rotation or reboot. Platform owns the exact OpenBao callback and custody acceptance; rapp-openbao owns package exposure, KeyCape/NetKingdom the issuer callback, ops-bridge the tunnel, and S1/S2 DNS/network primitives. Unblock with a fresh attended OIDC/MFA callback update and loopback login, then the guarded retraction and owner-specific DNS handoff. Existing source readiness is not evidence of a completed live cutover. ## Callback preservation repair — 2026-09-06 T03 advanced locally: the attended callback helper now reads and preserves the existing platform-admin role, appends only the exact loopback callback, skips writes when already present, detects observed drift before writing, and verifies all settings on readback. `--check-only` is silent and returns 3 if absent. The role endpoint has no CAS; exclusive attended administration is still needed. Tests cover settings preservation, idempotence, drift, readback failure and unexpected roles. No live role update or ingress retraction was performed in this follow-up; attended loopback UI login remains the cutover gate. ## Attended retry — 2026-09-15 Plan selected `openbao-platform-admin-login` / `founder_required` / `oidc_login`. Contained login reached a helper-backed session, then `warden access ... --exec -- scripts/openbao-apply-operator-loopback-callback.sh` failed with `attended command could not start; the login session was revoked`. That Warden string is OSError spawning the child after successful login, not an OIDC or MFA refusal. Relative `scripts/...` is missing unless cwd is this repo; the session was revoked and private storage cleaned. No role write, Ingress change, or retained helper. Retry only through `python3 scripts/openbao-attended-exec.py --` and the absolute owner command. Do not reuse the failed relative-path attempt as callback evidence. A second attended attempt used the absolute owner command. Login reached a helper-backed session and the child started, then Warden reported `attended command failed closed because it returned a failure or unexpected output; the login session was revoked`. That string means the silent helper exited non-zero. The helper previously posted the entire role read-back and required exact dict equality; that path was never live-proven and can fail on read-only/normalized fields. No retained helper. Retry uses the same envelope with `--receipt` and a field-preserving write. Do not retract Ingress from this failed attempt. Third attended attempt, 2026-09-15T00:25:52Z: Warden exit 0. Receipt status `already_present` for `http://127.0.0.1:18200/ui/vault/auth/netkingdom/oidc/callback` on `auth/netkingdom/role/platform-admin`. No role write. Session revoked by the envelope. Public Ingress still present. CLI `bao login` used the contained OIDC callback, not the UI loopback origin. T03 still needs one MFA login at `http://127.0.0.1:18200` before guarded retraction. Evidence: `docs/evidence/2026-09-15-openbao-loopback-callback-already-present.json`. Operator reported 2026-09-15 loopback UI MFA at `http://127.0.0.1:18200` succeeded (boolean only; no token or screenshot). Named tunnel remains lifecycle-healthy. Guarded retraction ran after the exact confirm phrase `RETRACT RMASTER-WP-0020-T09 PUBLIC OPENBAO LISTENER`. Ingress `openbao/openbao-ui-gateway` is absent; ClusterIP gateway 1/1 Ready; named tunnel healthy; private presets HTTP 200; public `https://bao.coulomb.social/` HTTP 404. Evidence: `docs/evidence/2026-09-15-openbao-public-listener-retract.json`. Remaining T03: public DNS withdrawal with railiance-infra and non-secret acceptance to Railiance Master. Rollback phrase remains available during the observation window. ## Closure — 2026-09-22 T03 done. The operator-only cutover is complete on the platform side: loopback MFA login passed, and the public Ingress was retracted on 2026-09-15 (`docs/evidence/2026-09-15-openbao-public-listener-retract.json`). **Intended end state: `bao.coulomb.social` is retired.** The named tunnel `openbao-ui-railiance01` (`http://127.0.0.1:18200`) is the only operator path, and workloads use `openbao.openbao.svc:8200`. No certificate or route will be restored for the public name. The dangling DNS record (it still resolves to 92.205.62.239, where Traefik serves its default certificate and returns 404) was handed to its S1 publisher, railiance-infra, for withdrawal. Non-secret acceptance went to railiance-master for RMASTER-WP-0020-T09, and the end state was sent to user-engine (hub message `e8ccbc2f`). Operator scripts no longer default `BAO_ADDR` to the public name. The one exception is `scripts/audit-core-database-lease-recovery.py`: the WP-0024 owner-review contract pins its digest, so it keeps the old literal until the next owner review.