feat(RAILIANCE-WP-0027): prepare operator-only OpenBao access
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a02b90-83bf-75c2-81c8-aa705414e4d4
This commit is contained in:
codex 2026-08-23 12:50:23 +02:00
parent 082c76979e
commit 517f68593d
13 changed files with 413 additions and 82 deletions

View file

@ -0,0 +1,68 @@
# OpenBao public-listener transition
Status: source implementation complete; live retraction held.
This is the S3-owner procedure for `RMASTER-WP-0020-T09`. It preserves the
OpenBao Deployment, the `openbao-ui-gateway` Deployment, and its ClusterIP
Service while removing the public `bao.coulomb.social` Ingress.
## Target access
- Exposure posture: `operator`
- Named tunnel: `openbao-ui-railiance01`
- Local UI: `http://127.0.0.1:18200`
- Cluster target: `openbao/openbao-ui-gateway:8080`
- Public Ingress: absent after the transition
The tunnel is an ops-bridge local forward to the current ClusterIP and does not
open a node port. If the Service is recreated with a new ClusterIP, update and
revalidate the tunnel before use.
Browser OIDC derives its callback from the local origin. Before retraction,
both the KeyCape `openbao-admin` client and OpenBao
`auth/netkingdom/role/platform-admin` must allow exactly:
```text
http://127.0.0.1:18200/ui/vault/auth/netkingdom/oidc/callback
```
Record only a value-safe attended-login result. Do not record the authorization
code, token, accessor, callback query, browser storage, or screenshots.
## Guarded sequence
```bash
make openbao-public-listener-dry-run
make openbao-public-listener-status
```
The status command deliberately fails if ops-bridge does not report the named
tunnel as lifecycle-healthy, even when an orphan forward still answers. Repair
that state before proceeding.
After KeyCape/OpenBao callback configuration and one attended MFA login through
the local URL, use the exact hold point:
```bash
OPENBAO_OPERATOR_LOGIN_VERIFIED=true \
OPENBAO_PUBLIC_LISTENER_CONFIRM='RETRACT RMASTER-WP-0020-T09 PUBLIC OPENBAO LISTENER' \
make openbao-public-listener-retract
```
The command pins the railiance01 cluster UID, rechecks the ClusterIP gateway and
tunnel, deletes only `openbao/openbao-ui-gateway` Ingress, then proves the
private path remains healthy and the public name no longer returns a successful
HTTP status.
## Rollback
During the bounded observation window:
```bash
OPENBAO_PUBLIC_LISTENER_CONFIRM='ROLLBACK RMASTER-WP-0020-T09 PUBLIC OPENBAO LISTENER' \
make openbao-public-listener-rollback
```
Rollback reapplies only the retained Traefik middleware and the explicitly
named rollback Ingress. It does not mutate OpenBao policy, Raft, PVCs, Secrets,
or the CoulombCore retention state.

View file

@ -29,8 +29,9 @@ S5 workloads / operators
-> audit storage PVC mounted at /openbao/audit
Platform operators with approved admin identity
-> https://bao.coulomb.social
-> Traefik Ingress + TLS
-> bridge up openbao-ui-railiance01
-> http://127.0.0.1:18200
-> SSH local forward to the ClusterIP
-> openbao-ui service
-> OpenBao UI/API
-> KeyCape OIDC at https://kc.coulomb.social for login
@ -39,7 +40,8 @@ Platform operators with approved admin identity
- OpenBao is the canonical Railiance S3 secrets service.
- SOPS/age remains the Git-at-rest bootstrap mechanism.
- The first Railiance01 deployment is single-replica Raft, not true HA.
- Browser UI/API exposure is declared for `https://bao.coulomb.social`.
- Browser UI exposure is operator-only through the named
`openbao-ui-railiance01` tunnel.
Operators authenticate through KeyCape/OIDC with MFA and the
`platform-admin` role. Do not use the root token through the browser UI.
- `kubectl exec` and port-forwarding remain valid break-glass/operator paths
@ -61,11 +63,11 @@ make openbao-deploy
make openbao-status
```
`make openbao-deploy` applies `helm/openbao-middleware.yaml` (Traefik
rate-limit and HSTS), upgrades the OpenBao Helm release, then applies the
KeyCape login overlay gateway (`helm/openbao-ui-overlay-k8s.yaml`). Public
ingress for `bao.coulomb.social` targets `openbao-ui-gateway`, not the chart
ingress (which stays disabled in `helm/openbao-values.yaml`).
`make openbao-deploy` upgrades the OpenBao Helm release, then applies the
KeyCape login overlay gateway (`helm/openbao-ui-overlay-k8s.yaml`) as a
ClusterIP-only surface. The chart ingress stays disabled. Public-listener
retraction and rollback are separate guarded commands documented in
`docs/openbao-public-listener-transition.md`.
On Railiance01 directly:
@ -107,8 +109,8 @@ Expected immediately after install:
- `openbao-0` is Running.
- `openbao`, `openbao-active`, `openbao-internal`, and `openbao-ui` services
exist as cluster-internal services.
- After DNS points at the cluster ingress, `https://bao.coulomb.social` serves
the OpenBao UI over valid TLS.
- With `openbao-ui-railiance01` healthy,
`http://127.0.0.1:18200` serves the operator UI.
- data and audit PVCs are Bound.
- `bao status` reports `Initialized: false` and `Sealed: true`.
@ -327,17 +329,17 @@ Initial auth model:
### Browser UI Login
The browser operator surface is:
The browser operator surface is the named local tunnel:
```text
https://bao.coulomb.social
http://127.0.0.1:18200
```
Operators see a streamlined **Sign in with KeyCape** mask. The raw OpenBao
fields (namespace, method, mount path, role) are hidden presets applied by the
UI overlay in `helm/openbao-ui-overlay/`. Public ingress targets the
`openbao-ui-gateway` nginx proxy, which injects overlay assets and forwards to
the OpenBao service.
Run `bridge up openbao-ui-railiance01` first. Operators then see a streamlined
**Sign in with KeyCape** mask. The raw OpenBao fields (namespace, method, mount
path, role) are hidden presets applied by the UI overlay in
`helm/openbao-ui-overlay/`. The ClusterIP-only `openbao-ui-gateway` nginx proxy
injects overlay assets and forwards to the OpenBao service.
Hidden defaults (also in `helm/openbao-ui-overlay/presets.json`):
@ -378,10 +380,10 @@ standalone page that exchanges the authorization code, stores the UI session
token, and redirects into the Ember app (no popup/`window.opener` flow).
The OpenBao UI redirects the browser to KeyCape at `kc.coulomb.social`, then
returns to:
returns through the same local tunnel to:
```text
https://bao.coulomb.social/ui/vault/auth/netkingdom/oidc/callback
http://127.0.0.1:18200/ui/vault/auth/netkingdom/oidc/callback
```
The legacy `keycape` mount remains a compatibility alias for existing
@ -394,7 +396,7 @@ The browser callback URI must be present in both:
- OpenBao `auth/netkingdom/role/platform-admin` `allowed_redirect_uris`.
If the compatibility alias is kept enabled, also keep
`https://bao.coulomb.social/ui/vault/auth/keycape/oidc/callback` in the
`http://127.0.0.1:18200/ui/vault/auth/keycape/oidc/callback` in the
KeyCape client and `auth/keycape/role/platform-admin`.
Use the browser UI for metadata inspection and attended operator workflows.