feat(RAILIANCE-WP-0027): prepare operator-only OpenBao access
Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a02b90-83bf-75c2-81c8-aa705414e4d4
This commit is contained in:
parent
082c76979e
commit
517f68593d
13 changed files with 413 additions and 82 deletions
25
Makefile
25
Makefile
|
|
@ -32,6 +32,7 @@ OPENBAO_VALUES ?= helm/openbao-values.yaml
|
||||||
OPENBAO_MIDDLEWARE ?= helm/openbao-middleware.yaml
|
OPENBAO_MIDDLEWARE ?= helm/openbao-middleware.yaml
|
||||||
OPENBAO_UI_OVERLAY_DIR ?= helm/openbao-ui-overlay
|
OPENBAO_UI_OVERLAY_DIR ?= helm/openbao-ui-overlay
|
||||||
OPENBAO_UI_OVERLAY_K8S ?= helm/openbao-ui-overlay-k8s.yaml
|
OPENBAO_UI_OVERLAY_K8S ?= helm/openbao-ui-overlay-k8s.yaml
|
||||||
|
OPENBAO_PUBLIC_INGRESS_ROLLBACK ?= helm/openbao-public-ingress.rollback.yaml
|
||||||
OPENBAO_VERIFY_AUTH_ARGS ?=
|
OPENBAO_VERIFY_AUTH_ARGS ?=
|
||||||
OPENBAO_RESTORE_EVIDENCE ?= /tmp/netkingdom-openbao-restore-drill/evidence.json
|
OPENBAO_RESTORE_EVIDENCE ?= /tmp/netkingdom-openbao-restore-drill/evidence.json
|
||||||
OPENBAO_EMERGENCY_EVIDENCE ?= /tmp/netkingdom-openbao-emergency-drill/evidence.json
|
OPENBAO_EMERGENCY_EVIDENCE ?= /tmp/netkingdom-openbao-emergency-drill/evidence.json
|
||||||
|
|
@ -215,7 +216,6 @@ openbao-verify-login-overlay: ## Verify public KeyCape login overlay is active
|
||||||
|
|
||||||
openbao-deploy: openbao-repo ## Deploy / upgrade OpenBao to the openbao namespace
|
openbao-deploy: openbao-repo ## Deploy / upgrade OpenBao to the openbao namespace
|
||||||
$(KUBECTL) create namespace $(OPENBAO_NAMESPACE) --dry-run=client -o yaml | $(KUBECTL) apply -f -
|
$(KUBECTL) create namespace $(OPENBAO_NAMESPACE) --dry-run=client -o yaml | $(KUBECTL) apply -f -
|
||||||
$(KUBECTL) apply -f $(OPENBAO_MIDDLEWARE)
|
|
||||||
$(HELM) upgrade --install $(OPENBAO_RELEASE) openbao/openbao \
|
$(HELM) upgrade --install $(OPENBAO_RELEASE) openbao/openbao \
|
||||||
--version $(OPENBAO_CHART_VERSION) \
|
--version $(OPENBAO_CHART_VERSION) \
|
||||||
--namespace $(OPENBAO_NAMESPACE) \
|
--namespace $(OPENBAO_NAMESPACE) \
|
||||||
|
|
@ -223,6 +223,29 @@ openbao-deploy: openbao-repo ## Deploy / upgrade OpenBao to the openbao namespac
|
||||||
--wait --timeout 5m
|
--wait --timeout 5m
|
||||||
$(MAKE) openbao-overlay-apply
|
$(MAKE) openbao-overlay-apply
|
||||||
|
|
||||||
|
.PHONY: openbao-public-listener-dry-run openbao-public-listener-status openbao-public-listener-retract openbao-public-listener-rollback
|
||||||
|
|
||||||
|
openbao-public-listener-dry-run: ## Validate the guarded public-listener retraction without mutation
|
||||||
|
KUBECTL='$(KUBECTL)' OPENBAO_NAMESPACE=$(OPENBAO_NAMESPACE) \
|
||||||
|
OPENBAO_UI_OVERLAY_K8S=$(OPENBAO_UI_OVERLAY_K8S) \
|
||||||
|
OPENBAO_PUBLIC_INGRESS_ROLLBACK=$(OPENBAO_PUBLIC_INGRESS_ROLLBACK) \
|
||||||
|
scripts/openbao-public-listener-transition.sh dry-run
|
||||||
|
|
||||||
|
openbao-public-listener-status: ## Report public Ingress and private tunnel readiness
|
||||||
|
KUBECTL='$(KUBECTL)' OPENBAO_NAMESPACE=$(OPENBAO_NAMESPACE) \
|
||||||
|
scripts/openbao-public-listener-transition.sh status
|
||||||
|
|
||||||
|
openbao-public-listener-retract: ## Attended deletion after exact tunnel/login confirmation
|
||||||
|
KUBECTL='$(KUBECTL)' OPENBAO_NAMESPACE=$(OPENBAO_NAMESPACE) \
|
||||||
|
OPENBAO_PUBLIC_INGRESS_ROLLBACK=$(OPENBAO_PUBLIC_INGRESS_ROLLBACK) \
|
||||||
|
scripts/openbao-public-listener-transition.sh apply
|
||||||
|
|
||||||
|
openbao-public-listener-rollback: ## Attended restoration of the prior public Ingress
|
||||||
|
KUBECTL='$(KUBECTL)' OPENBAO_NAMESPACE=$(OPENBAO_NAMESPACE) \
|
||||||
|
OPENBAO_MIDDLEWARE=$(OPENBAO_MIDDLEWARE) \
|
||||||
|
OPENBAO_PUBLIC_INGRESS_ROLLBACK=$(OPENBAO_PUBLIC_INGRESS_ROLLBACK) \
|
||||||
|
scripts/openbao-public-listener-transition.sh rollback
|
||||||
|
|
||||||
openbao-status: ## Show OpenBao pods, services, PVCs, and seal/init status
|
openbao-status: ## Show OpenBao pods, services, PVCs, and seal/init status
|
||||||
$(KUBECTL) get pods,svc,pvc -n $(OPENBAO_NAMESPACE) \
|
$(KUBECTL) get pods,svc,pvc -n $(OPENBAO_NAMESPACE) \
|
||||||
-l app.kubernetes.io/instance=$(OPENBAO_RELEASE) -o wide
|
-l app.kubernetes.io/instance=$(OPENBAO_RELEASE) -o wide
|
||||||
|
|
|
||||||
|
|
@ -24,11 +24,12 @@
|
||||||
| workplan | RAILIANCE-WP-0023 | finished | — | workplans/RAILIANCE-WP-0023-hub-core-candidate-credential-lanes.md |
|
| workplan | RAILIANCE-WP-0023 | finished | — | workplans/RAILIANCE-WP-0023-hub-core-candidate-credential-lanes.md |
|
||||||
| workplan | RAILIANCE-WP-0024 | active | — | workplans/RAILIANCE-WP-0024-audit-core-custody-and-recovery-coordination.md |
|
| workplan | RAILIANCE-WP-0024 | active | — | workplans/RAILIANCE-WP-0024-audit-core-custody-and-recovery-coordination.md |
|
||||||
| workplan | RAILIANCE-WP-0025 | finished | — | workplans/RAILIANCE-WP-0025-versioned-ephemeral-custody-lifecycle.md |
|
| workplan | RAILIANCE-WP-0025 | finished | — | workplans/RAILIANCE-WP-0025-versioned-ephemeral-custody-lifecycle.md |
|
||||||
| workplan | RAILIANCE-WP-0026 | ready | — | workplans/RAILIANCE-WP-0026-attended-login-output-containment.md |
|
| workplan | RAILIANCE-WP-0026 | finished | — | workplans/RAILIANCE-WP-0026-attended-login-output-containment.md |
|
||||||
| workplan | RPF-WP-0018 | finished | — | workplans/RPF-WP-0018-policy-surface-alignment.md |
|
| workplan | RPF-WP-0018 | finished | — | workplans/RPF-WP-0018-policy-surface-alignment.md |
|
||||||
| workplan | RPF-WP-0019 | finished | — | workplans/RPF-WP-0019-apps-pg-recoverability-and-controls.md |
|
| workplan | RPF-WP-0019 | finished | — | workplans/RPF-WP-0019-apps-pg-recoverability-and-controls.md |
|
||||||
| workplan | RPF-WP-0020 | finished | — | workplans/RPF-WP-0020-ccr-schema-drift.md |
|
| workplan | RPF-WP-0020 | finished | — | workplans/RPF-WP-0020-ccr-schema-drift.md |
|
||||||
| workplan | RPF-WP-0021 | finished | — | workplans/RPF-WP-0021-core-hub-platform-onboarding.md |
|
| workplan | RPF-WP-0021 | finished | — | workplans/RPF-WP-0021-core-hub-platform-onboarding.md |
|
||||||
|
| workplan | RAILIANCE-WP-0027 | blocked | — | workplans/RAILIANCE-WP-0027-openbao-operator-only-access.md |
|
||||||
| task | RAILIANCE-WP-0005-T01 | done | — | workplans/RAILIANCE-WP-0005-credential-request-and-lease-broker.md |
|
| task | RAILIANCE-WP-0005-T01 | done | — | workplans/RAILIANCE-WP-0005-credential-request-and-lease-broker.md |
|
||||||
| task | RAILIANCE-WP-0005-T02 | done | — | workplans/RAILIANCE-WP-0005-credential-request-and-lease-broker.md |
|
| task | RAILIANCE-WP-0005-T02 | done | — | workplans/RAILIANCE-WP-0005-credential-request-and-lease-broker.md |
|
||||||
| task | RAILIANCE-WP-0005-T03 | done | — | workplans/RAILIANCE-WP-0005-credential-request-and-lease-broker.md |
|
| task | RAILIANCE-WP-0005-T03 | done | — | workplans/RAILIANCE-WP-0005-credential-request-and-lease-broker.md |
|
||||||
|
|
@ -109,7 +110,7 @@
|
||||||
| task | RAILIANCE-WP-0025-T04 | done | — | workplans/RAILIANCE-WP-0025-versioned-ephemeral-custody-lifecycle.md |
|
| task | RAILIANCE-WP-0025-T04 | done | — | workplans/RAILIANCE-WP-0025-versioned-ephemeral-custody-lifecycle.md |
|
||||||
| task | RAILIANCE-WP-0025-T05 | done | — | workplans/RAILIANCE-WP-0025-versioned-ephemeral-custody-lifecycle.md |
|
| task | RAILIANCE-WP-0025-T05 | done | — | workplans/RAILIANCE-WP-0025-versioned-ephemeral-custody-lifecycle.md |
|
||||||
| task | RAILIANCE-WP-0025-T06 | done | — | workplans/RAILIANCE-WP-0025-versioned-ephemeral-custody-lifecycle.md |
|
| task | RAILIANCE-WP-0025-T06 | done | — | workplans/RAILIANCE-WP-0025-versioned-ephemeral-custody-lifecycle.md |
|
||||||
| task | RAILIANCE-WP-0026-T01 | todo | — | workplans/RAILIANCE-WP-0026-attended-login-output-containment.md |
|
| task | RAILIANCE-WP-0026-T01 | done | — | workplans/RAILIANCE-WP-0026-attended-login-output-containment.md |
|
||||||
| task | RPF-WP-0018-T01 | done | — | workplans/RPF-WP-0018-policy-surface-alignment.md |
|
| task | RPF-WP-0018-T01 | done | — | workplans/RPF-WP-0018-policy-surface-alignment.md |
|
||||||
| task | RPF-WP-0018-T02 | done | — | workplans/RPF-WP-0018-policy-surface-alignment.md |
|
| task | RPF-WP-0018-T02 | done | — | workplans/RPF-WP-0018-policy-surface-alignment.md |
|
||||||
| task | RPF-WP-0018-T03 | done | — | workplans/RPF-WP-0018-policy-surface-alignment.md |
|
| task | RPF-WP-0018-T03 | done | — | workplans/RPF-WP-0018-policy-surface-alignment.md |
|
||||||
|
|
@ -130,3 +131,6 @@
|
||||||
| task | RPF-WP-0021-T03 | done | — | workplans/RPF-WP-0021-core-hub-platform-onboarding.md |
|
| task | RPF-WP-0021-T03 | done | — | workplans/RPF-WP-0021-core-hub-platform-onboarding.md |
|
||||||
| task | RPF-WP-0021-T04 | done | — | workplans/RPF-WP-0021-core-hub-platform-onboarding.md |
|
| task | RPF-WP-0021-T04 | done | — | workplans/RPF-WP-0021-core-hub-platform-onboarding.md |
|
||||||
| task | RPF-WP-0021-T05 | done | — | workplans/RPF-WP-0021-core-hub-platform-onboarding.md |
|
| task | RPF-WP-0021-T05 | done | — | workplans/RPF-WP-0021-core-hub-platform-onboarding.md |
|
||||||
|
| task | RAILIANCE-WP-0027-T01 | done | — | workplans/RAILIANCE-WP-0027-openbao-operator-only-access.md |
|
||||||
|
| task | RAILIANCE-WP-0027-T02 | done | — | workplans/RAILIANCE-WP-0027-openbao-operator-only-access.md |
|
||||||
|
| task | RAILIANCE-WP-0027-T03 | wait | — | workplans/RAILIANCE-WP-0027-openbao-operator-only-access.md |
|
||||||
|
|
|
||||||
68
docs/openbao-public-listener-transition.md
Normal file
68
docs/openbao-public-listener-transition.md
Normal 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.
|
||||||
|
|
@ -29,8 +29,9 @@ S5 workloads / operators
|
||||||
-> audit storage PVC mounted at /openbao/audit
|
-> audit storage PVC mounted at /openbao/audit
|
||||||
|
|
||||||
Platform operators with approved admin identity
|
Platform operators with approved admin identity
|
||||||
-> https://bao.coulomb.social
|
-> bridge up openbao-ui-railiance01
|
||||||
-> Traefik Ingress + TLS
|
-> http://127.0.0.1:18200
|
||||||
|
-> SSH local forward to the ClusterIP
|
||||||
-> openbao-ui service
|
-> openbao-ui service
|
||||||
-> OpenBao UI/API
|
-> OpenBao UI/API
|
||||||
-> KeyCape OIDC at https://kc.coulomb.social for login
|
-> 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.
|
- OpenBao is the canonical Railiance S3 secrets service.
|
||||||
- SOPS/age remains the Git-at-rest bootstrap mechanism.
|
- SOPS/age remains the Git-at-rest bootstrap mechanism.
|
||||||
- The first Railiance01 deployment is single-replica Raft, not true HA.
|
- 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
|
Operators authenticate through KeyCape/OIDC with MFA and the
|
||||||
`platform-admin` role. Do not use the root token through the browser UI.
|
`platform-admin` role. Do not use the root token through the browser UI.
|
||||||
- `kubectl exec` and port-forwarding remain valid break-glass/operator paths
|
- `kubectl exec` and port-forwarding remain valid break-glass/operator paths
|
||||||
|
|
@ -61,11 +63,11 @@ make openbao-deploy
|
||||||
make openbao-status
|
make openbao-status
|
||||||
```
|
```
|
||||||
|
|
||||||
`make openbao-deploy` applies `helm/openbao-middleware.yaml` (Traefik
|
`make openbao-deploy` upgrades the OpenBao Helm release, then applies the
|
||||||
rate-limit and HSTS), upgrades the OpenBao Helm release, then applies the
|
KeyCape login overlay gateway (`helm/openbao-ui-overlay-k8s.yaml`) as a
|
||||||
KeyCape login overlay gateway (`helm/openbao-ui-overlay-k8s.yaml`). Public
|
ClusterIP-only surface. The chart ingress stays disabled. Public-listener
|
||||||
ingress for `bao.coulomb.social` targets `openbao-ui-gateway`, not the chart
|
retraction and rollback are separate guarded commands documented in
|
||||||
ingress (which stays disabled in `helm/openbao-values.yaml`).
|
`docs/openbao-public-listener-transition.md`.
|
||||||
|
|
||||||
On Railiance01 directly:
|
On Railiance01 directly:
|
||||||
|
|
||||||
|
|
@ -107,8 +109,8 @@ Expected immediately after install:
|
||||||
- `openbao-0` is Running.
|
- `openbao-0` is Running.
|
||||||
- `openbao`, `openbao-active`, `openbao-internal`, and `openbao-ui` services
|
- `openbao`, `openbao-active`, `openbao-internal`, and `openbao-ui` services
|
||||||
exist as cluster-internal services.
|
exist as cluster-internal services.
|
||||||
- After DNS points at the cluster ingress, `https://bao.coulomb.social` serves
|
- With `openbao-ui-railiance01` healthy,
|
||||||
the OpenBao UI over valid TLS.
|
`http://127.0.0.1:18200` serves the operator UI.
|
||||||
- data and audit PVCs are Bound.
|
- data and audit PVCs are Bound.
|
||||||
- `bao status` reports `Initialized: false` and `Sealed: true`.
|
- `bao status` reports `Initialized: false` and `Sealed: true`.
|
||||||
|
|
||||||
|
|
@ -327,17 +329,17 @@ Initial auth model:
|
||||||
|
|
||||||
### Browser UI Login
|
### Browser UI Login
|
||||||
|
|
||||||
The browser operator surface is:
|
The browser operator surface is the named local tunnel:
|
||||||
|
|
||||||
```text
|
```text
|
||||||
https://bao.coulomb.social
|
http://127.0.0.1:18200
|
||||||
```
|
```
|
||||||
|
|
||||||
Operators see a streamlined **Sign in with KeyCape** mask. The raw OpenBao
|
Run `bridge up openbao-ui-railiance01` first. Operators then see a streamlined
|
||||||
fields (namespace, method, mount path, role) are hidden presets applied by the
|
**Sign in with KeyCape** mask. The raw OpenBao fields (namespace, method, mount
|
||||||
UI overlay in `helm/openbao-ui-overlay/`. Public ingress targets the
|
path, role) are hidden presets applied by the UI overlay in
|
||||||
`openbao-ui-gateway` nginx proxy, which injects overlay assets and forwards to
|
`helm/openbao-ui-overlay/`. The ClusterIP-only `openbao-ui-gateway` nginx proxy
|
||||||
the OpenBao service.
|
injects overlay assets and forwards to the OpenBao service.
|
||||||
|
|
||||||
Hidden defaults (also in `helm/openbao-ui-overlay/presets.json`):
|
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).
|
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
|
The OpenBao UI redirects the browser to KeyCape at `kc.coulomb.social`, then
|
||||||
returns to:
|
returns through the same local tunnel to:
|
||||||
|
|
||||||
```text
|
```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
|
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`.
|
- OpenBao `auth/netkingdom/role/platform-admin` `allowed_redirect_uris`.
|
||||||
|
|
||||||
If the compatibility alias is kept enabled, also keep
|
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`.
|
KeyCape client and `auth/keycape/role/platform-admin`.
|
||||||
|
|
||||||
Use the browser UI for metadata inspection and attended operator workflows.
|
Use the browser UI for metadata inspection and attended operator workflows.
|
||||||
|
|
|
||||||
33
helm/openbao-public-ingress.rollback.yaml
Normal file
33
helm/openbao-public-ingress.rollback.yaml
Normal file
|
|
@ -0,0 +1,33 @@
|
||||||
|
# Rollback-only public listener for an attended RMASTER-WP-0020-T09 reversal.
|
||||||
|
# This file is never applied by the ordinary platform deployment path.
|
||||||
|
apiVersion: networking.k8s.io/v1
|
||||||
|
kind: Ingress
|
||||||
|
metadata:
|
||||||
|
name: openbao-ui-gateway
|
||||||
|
namespace: openbao
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: openbao-ui-gateway
|
||||||
|
app.kubernetes.io/part-of: railiance-platform
|
||||||
|
railiance-platform/component: secrets
|
||||||
|
annotations:
|
||||||
|
cert-manager.io/cluster-issuer: letsencrypt-prod
|
||||||
|
traefik.ingress.kubernetes.io/router.middlewares: >-
|
||||||
|
openbao-openbao-rate-limit@kubernetescrd,
|
||||||
|
openbao-openbao-hsts@kubernetescrd
|
||||||
|
spec:
|
||||||
|
ingressClassName: traefik
|
||||||
|
tls:
|
||||||
|
- secretName: bao-tls
|
||||||
|
hosts:
|
||||||
|
- bao.coulomb.social
|
||||||
|
rules:
|
||||||
|
- host: bao.coulomb.social
|
||||||
|
http:
|
||||||
|
paths:
|
||||||
|
- path: /
|
||||||
|
pathType: Prefix
|
||||||
|
backend:
|
||||||
|
service:
|
||||||
|
name: openbao-ui-gateway
|
||||||
|
port:
|
||||||
|
number: 8080
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
# OpenBao browser UI gateway — injects the KeyCape login overlay and proxies
|
# OpenBao browser UI gateway — injects the KeyCape login overlay and proxies
|
||||||
# to the OpenBao service. Public ingress for bao.coulomb.social targets this
|
# to the OpenBao service. The gateway is ClusterIP-only and is reached through
|
||||||
# gateway instead of the chart-managed OpenBao ingress.
|
# the named openbao-ui-railiance01 operator tunnel.
|
||||||
#
|
#
|
||||||
# ConfigMap data is applied by scripts/openbao-ui-overlay-apply.sh from
|
# ConfigMap data is applied by scripts/openbao-ui-overlay-apply.sh from
|
||||||
# helm/openbao-ui-overlay/*.
|
# helm/openbao-ui-overlay/*.
|
||||||
|
|
@ -87,35 +87,3 @@ spec:
|
||||||
port: 8080
|
port: 8080
|
||||||
targetPort: http
|
targetPort: http
|
||||||
protocol: TCP
|
protocol: TCP
|
||||||
---
|
|
||||||
apiVersion: networking.k8s.io/v1
|
|
||||||
kind: Ingress
|
|
||||||
metadata:
|
|
||||||
name: openbao-ui-gateway
|
|
||||||
namespace: openbao
|
|
||||||
labels:
|
|
||||||
app.kubernetes.io/name: openbao-ui-gateway
|
|
||||||
app.kubernetes.io/part-of: railiance-platform
|
|
||||||
railiance-platform/component: secrets
|
|
||||||
annotations:
|
|
||||||
cert-manager.io/cluster-issuer: letsencrypt-prod
|
|
||||||
traefik.ingress.kubernetes.io/router.middlewares: >-
|
|
||||||
openbao-openbao-rate-limit@kubernetescrd,
|
|
||||||
openbao-openbao-hsts@kubernetescrd
|
|
||||||
spec:
|
|
||||||
ingressClassName: traefik
|
|
||||||
tls:
|
|
||||||
- secretName: bao-tls
|
|
||||||
hosts:
|
|
||||||
- bao.coulomb.social
|
|
||||||
rules:
|
|
||||||
- host: bao.coulomb.social
|
|
||||||
http:
|
|
||||||
paths:
|
|
||||||
- path: /
|
|
||||||
pathType: Prefix
|
|
||||||
backend:
|
|
||||||
service:
|
|
||||||
name: openbao-ui-gateway
|
|
||||||
port:
|
|
||||||
number: 8080
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
# OpenBao KeyCape login overlay
|
# OpenBao KeyCape login overlay
|
||||||
|
|
||||||
Streamlines the browser login mask at `https://bao.coulomb.social` to a single
|
Streamlines the browser login mask reached through the named
|
||||||
**Sign in with KeyCape** action. Namespace, auth method, mount path, and role
|
`openbao-ui-railiance01` operator tunnel at `http://127.0.0.1:18200` to a
|
||||||
are preset in `presets.json` and hidden by `overlay.css` / `overlay.js`.
|
single **Sign in with KeyCape** action. Namespace, auth method, mount path, and
|
||||||
|
role are preset in `presets.json` and hidden by `overlay.css` / `overlay.js`.
|
||||||
|
|
||||||
## Mechanism (T01 decision)
|
## Mechanism (T01 decision)
|
||||||
|
|
||||||
|
|
@ -54,9 +55,9 @@ make openbao-verify-login-overlay
|
||||||
3. Fetch live UI assets and compare hashes:
|
3. Fetch live UI assets and compare hashes:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
curl -sS https://bao.coulomb.social/ui/ -o /tmp/index.html
|
curl -sS http://127.0.0.1:18200/ui/ -o /tmp/index.html
|
||||||
# locate vault-*.js path in /tmp/index.html, then:
|
# locate vault-*.js path in /tmp/index.html, then:
|
||||||
curl -sS "https://bao.coulomb.social/ui/assets/vault-....js" -o /tmp/vault.js
|
curl -sS "http://127.0.0.1:18200/ui/assets/vault-....js" -o /tmp/vault.js
|
||||||
sha256sum /tmp/index.html /tmp/vault.js
|
sha256sum /tmp/index.html /tmp/vault.js
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -64,6 +65,9 @@ make openbao-verify-login-overlay
|
||||||
`overlay.css` / `overlay.js` selectors against the new Ember templates.
|
`overlay.css` / `overlay.js` selectors against the new Ember templates.
|
||||||
5. Write `patches/<new-version>/manifest.sha256`, update `VERSION`.
|
5. Write `patches/<new-version>/manifest.sha256`, update `VERSION`.
|
||||||
6. Run `make openbao-verify-login-overlay CHECK_UPSTREAM_DRIFT=1`.
|
6. Run `make openbao-verify-login-overlay CHECK_UPSTREAM_DRIFT=1`.
|
||||||
7. Attended browser login through KeyCape MFA.
|
7. Attended browser login through KeyCape MFA. The OpenBao role and KeyCape
|
||||||
|
client must both allow the exact loopback callback
|
||||||
|
`http://127.0.0.1:18200/ui/vault/auth/netkingdom/oidc/callback` before the
|
||||||
|
former public listener is retracted.
|
||||||
|
|
||||||
Workplan: `helix-forge/workplans/HF-WP-0003-openbao-keycape-login-overlay.md`
|
Workplan: `helix-forge/workplans/HF-WP-0003-openbao-keycape-login-overlay.md`
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,8 @@
|
||||||
# OpenBao UI asset fingerprints for image tag 2.5.4.
|
# OpenBao UI asset fingerprints for image tag 2.5.4.
|
||||||
# Regenerate after an OpenBao image bump when login markup drifts.
|
# Regenerate after an OpenBao image bump when login markup drifts.
|
||||||
# Compare vault.js only — index.html is intentionally modified by the gateway.
|
# Compare vault.js only — index.html is intentionally modified by the gateway.
|
||||||
# curl -sS https://bao.coulomb.social/ui/ -o /tmp/index.html
|
# curl -sS http://127.0.0.1:18200/ui/ -o /tmp/index.html
|
||||||
# vault_path=$(rg -o '/ui/assets/vault-[a-f0-9]+\\.js' /tmp/index.html | head -1)
|
# vault_path=$(rg -o '/ui/assets/vault-[a-f0-9]+\\.js' /tmp/index.html | head -1)
|
||||||
# curl -sS "https://bao.coulomb.social${vault_path}" -o /tmp/vault.js
|
# curl -sS "http://127.0.0.1:18200${vault_path}" -o /tmp/vault.js
|
||||||
# sha256sum /tmp/vault.js
|
# sha256sum /tmp/vault.js
|
||||||
f0214b5be89377395f8d6521c34139877529bd95ba703901c78b527ab0f1c231 ui/assets/vault-bae6b876038fbf475728f993b5a62002.js
|
f0214b5be89377395f8d6521c34139877529bd95ba703901c78b527ab0f1c231 ui/assets/vault-bae6b876038fbf475728f993b5a62002.js
|
||||||
|
|
|
||||||
153
scripts/openbao-public-listener-transition.sh
Executable file
153
scripts/openbao-public-listener-transition.sh
Executable file
|
|
@ -0,0 +1,153 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
ACTION="${1:-status}"
|
||||||
|
OPENBAO_NAMESPACE="${OPENBAO_NAMESPACE:-openbao}"
|
||||||
|
KUBECTL="${KUBECTL:-kubectl}"
|
||||||
|
INGRESS_NAME="${OPENBAO_PUBLIC_INGRESS_NAME:-openbao-ui-gateway}"
|
||||||
|
SERVICE_NAME="${OPENBAO_UI_SERVICE_NAME:-openbao-ui-gateway}"
|
||||||
|
DEPLOYMENT_NAME="${OPENBAO_UI_DEPLOYMENT_NAME:-openbao-ui-gateway}"
|
||||||
|
TUNNEL_NAME="${OPENBAO_UI_TUNNEL_NAME:-openbao-ui-railiance01}"
|
||||||
|
TUNNEL_URL="${OPENBAO_UI_BASE_URL:-http://127.0.0.1:18200}"
|
||||||
|
PUBLIC_URL="${OPENBAO_PUBLIC_URL:-https://bao.coulomb.social/}"
|
||||||
|
EXPECTED_CLUSTER_UID="${RAILIANCE01_CLUSTER_UID:-a553c742-0115-43d4-99a4-a5ca56fe0786}"
|
||||||
|
PRIVATE_MANIFEST="${OPENBAO_UI_OVERLAY_K8S:-helm/openbao-ui-overlay-k8s.yaml}"
|
||||||
|
ROLLBACK_MANIFEST="${OPENBAO_PUBLIC_INGRESS_ROLLBACK:-helm/openbao-public-ingress.rollback.yaml}"
|
||||||
|
MIDDLEWARE_MANIFEST="${OPENBAO_MIDDLEWARE:-helm/openbao-middleware.yaml}"
|
||||||
|
CONFIRM_RETRACT="RETRACT RMASTER-WP-0020-T09 PUBLIC OPENBAO LISTENER"
|
||||||
|
CONFIRM_ROLLBACK="ROLLBACK RMASTER-WP-0020-T09 PUBLIC OPENBAO LISTENER"
|
||||||
|
|
||||||
|
usage() {
|
||||||
|
cat <<'USAGE'
|
||||||
|
Usage: scripts/openbao-public-listener-transition.sh status|dry-run|preflight|apply|rollback
|
||||||
|
|
||||||
|
`apply` requires both:
|
||||||
|
OPENBAO_OPERATOR_LOGIN_VERIFIED=true
|
||||||
|
OPENBAO_PUBLIC_LISTENER_CONFIRM='RETRACT RMASTER-WP-0020-T09 PUBLIC OPENBAO LISTENER'
|
||||||
|
|
||||||
|
`rollback` requires:
|
||||||
|
OPENBAO_PUBLIC_LISTENER_CONFIRM='ROLLBACK RMASTER-WP-0020-T09 PUBLIC OPENBAO LISTENER'
|
||||||
|
|
||||||
|
The script never reads OpenBao credentials or secret values.
|
||||||
|
USAGE
|
||||||
|
}
|
||||||
|
|
||||||
|
fail() { printf '[ERR] %s\n' "$*" >&2; exit 1; }
|
||||||
|
ok() { printf '[OK] %s\n' "$*"; }
|
||||||
|
|
||||||
|
kube() {
|
||||||
|
# KUBECTL may include an explicit --kubeconfig argument from Make.
|
||||||
|
# shellcheck disable=SC2086
|
||||||
|
$KUBECTL "$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
require_cluster() {
|
||||||
|
local observed
|
||||||
|
observed="$(kube get namespace kube-system -o jsonpath='{.metadata.uid}')"
|
||||||
|
[ "$observed" = "$EXPECTED_CLUSTER_UID" ] ||
|
||||||
|
fail "cluster identity mismatch: expected $EXPECTED_CLUSTER_UID, observed $observed"
|
||||||
|
ok "railiance01 cluster identity pinned"
|
||||||
|
}
|
||||||
|
|
||||||
|
require_private_source() {
|
||||||
|
[ -f "$PRIVATE_MANIFEST" ] || fail "missing private gateway manifest: $PRIVATE_MANIFEST"
|
||||||
|
if grep -Eq '^kind:[[:space:]]*Ingress[[:space:]]*$' "$PRIVATE_MANIFEST"; then
|
||||||
|
fail "ordinary gateway manifest still contains an Ingress"
|
||||||
|
fi
|
||||||
|
ok "ordinary gateway manifest is Ingress-free"
|
||||||
|
}
|
||||||
|
|
||||||
|
require_private_runtime() {
|
||||||
|
local service_type service_port
|
||||||
|
service_type="$(kube -n "$OPENBAO_NAMESPACE" get service "$SERVICE_NAME" -o jsonpath='{.spec.type}')"
|
||||||
|
service_port="$(kube -n "$OPENBAO_NAMESPACE" get service "$SERVICE_NAME" -o jsonpath='{.spec.ports[?(@.name=="http")].port}')"
|
||||||
|
[ "$service_type" = "ClusterIP" ] || fail "gateway Service type is $service_type, not ClusterIP"
|
||||||
|
[ "$service_port" = "8080" ] || fail "gateway Service http port is $service_port, not 8080"
|
||||||
|
kube -n "$OPENBAO_NAMESPACE" rollout status "deployment/$DEPLOYMENT_NAME" --timeout=30s >/dev/null
|
||||||
|
ok "gateway Deployment Ready behind ClusterIP"
|
||||||
|
}
|
||||||
|
|
||||||
|
require_tunnel() {
|
||||||
|
command -v bridge >/dev/null || fail "bridge CLI not found"
|
||||||
|
command -v jq >/dev/null || fail "jq not found"
|
||||||
|
local report
|
||||||
|
if ! report="$(bridge check "$TUNNEL_NAME" --json 2>/dev/null)"; then
|
||||||
|
fail "named tunnel $TUNNEL_NAME is not lifecycle-healthy"
|
||||||
|
fi
|
||||||
|
jq -e --arg name "$TUNNEL_NAME" '.[] | select(.tunnel == $name and .ok == true)' \
|
||||||
|
<<<"$report" >/dev/null || fail "named tunnel $TUNNEL_NAME did not report ok=true"
|
||||||
|
curl -fsS --max-time 10 "$TUNNEL_URL/ui/platform-overlay/presets.json" >/dev/null ||
|
||||||
|
fail "operator UI is not reachable through $TUNNEL_NAME"
|
||||||
|
ok "named operator tunnel is healthy and reaches the UI"
|
||||||
|
}
|
||||||
|
|
||||||
|
status() {
|
||||||
|
require_cluster
|
||||||
|
require_private_source
|
||||||
|
require_private_runtime
|
||||||
|
if kube -n "$OPENBAO_NAMESPACE" get ingress "$INGRESS_NAME" >/dev/null 2>&1; then
|
||||||
|
printf '[INFO] public Ingress is present\n'
|
||||||
|
else
|
||||||
|
printf '[INFO] public Ingress is absent\n'
|
||||||
|
fi
|
||||||
|
require_tunnel
|
||||||
|
}
|
||||||
|
|
||||||
|
dry_run() {
|
||||||
|
require_cluster
|
||||||
|
require_private_source
|
||||||
|
[ -f "$ROLLBACK_MANIFEST" ] || fail "missing rollback manifest: $ROLLBACK_MANIFEST"
|
||||||
|
kube apply --server-side --dry-run=server -f "$PRIVATE_MANIFEST" >/dev/null
|
||||||
|
kube apply --server-side --dry-run=server -f "$ROLLBACK_MANIFEST" >/dev/null
|
||||||
|
kube -n "$OPENBAO_NAMESPACE" delete ingress "$INGRESS_NAME" --dry-run=server >/dev/null
|
||||||
|
ok "private apply, rollback apply, and Ingress deletion pass server dry-run"
|
||||||
|
}
|
||||||
|
|
||||||
|
preflight() {
|
||||||
|
status
|
||||||
|
kube -n "$OPENBAO_NAMESPACE" get ingress "$INGRESS_NAME" >/dev/null 2>&1 ||
|
||||||
|
fail "public Ingress is already absent; use status"
|
||||||
|
ok "public Ingress is present for attended transition"
|
||||||
|
}
|
||||||
|
|
||||||
|
apply_retraction() {
|
||||||
|
[ "${OPENBAO_OPERATOR_LOGIN_VERIFIED:-false}" = "true" ] ||
|
||||||
|
fail "attended operator login has not been explicitly verified"
|
||||||
|
[ "${OPENBAO_PUBLIC_LISTENER_CONFIRM:-}" = "$CONFIRM_RETRACT" ] ||
|
||||||
|
fail "exact retraction confirmation is missing"
|
||||||
|
preflight
|
||||||
|
kube -n "$OPENBAO_NAMESPACE" delete ingress "$INGRESS_NAME" --wait=true
|
||||||
|
require_private_runtime
|
||||||
|
require_tunnel
|
||||||
|
if kube -n "$OPENBAO_NAMESPACE" get ingress "$INGRESS_NAME" >/dev/null 2>&1; then
|
||||||
|
fail "public Ingress still exists after deletion"
|
||||||
|
fi
|
||||||
|
local code
|
||||||
|
code="$(curl -kLsS --max-time 10 -o /dev/null -w '%{http_code}' "$PUBLIC_URL" || true)"
|
||||||
|
case "$code" in
|
||||||
|
2??|3??) fail "public hostname still returns successful HTTP status $code" ;;
|
||||||
|
esac
|
||||||
|
ok "public Ingress absent; private gateway and named tunnel remain healthy"
|
||||||
|
}
|
||||||
|
|
||||||
|
rollback() {
|
||||||
|
[ "${OPENBAO_PUBLIC_LISTENER_CONFIRM:-}" = "$CONFIRM_ROLLBACK" ] ||
|
||||||
|
fail "exact rollback confirmation is missing"
|
||||||
|
require_cluster
|
||||||
|
[ -f "$MIDDLEWARE_MANIFEST" ] || fail "missing middleware manifest: $MIDDLEWARE_MANIFEST"
|
||||||
|
[ -f "$ROLLBACK_MANIFEST" ] || fail "missing rollback manifest: $ROLLBACK_MANIFEST"
|
||||||
|
kube apply -f "$MIDDLEWARE_MANIFEST"
|
||||||
|
kube apply -f "$ROLLBACK_MANIFEST"
|
||||||
|
kube -n "$OPENBAO_NAMESPACE" get ingress "$INGRESS_NAME" >/dev/null
|
||||||
|
ok "prior public Ingress restored from rollback-only manifest"
|
||||||
|
}
|
||||||
|
|
||||||
|
case "$ACTION" in
|
||||||
|
status) status ;;
|
||||||
|
dry-run) dry_run ;;
|
||||||
|
preflight) preflight ;;
|
||||||
|
apply) apply_retraction ;;
|
||||||
|
rollback) rollback ;;
|
||||||
|
-h|--help|help) usage ;;
|
||||||
|
*) usage >&2; exit 2 ;;
|
||||||
|
esac
|
||||||
|
|
@ -11,8 +11,9 @@ usage() {
|
||||||
cat <<'USAGE'
|
cat <<'USAGE'
|
||||||
Usage: scripts/openbao-ui-overlay-apply.sh
|
Usage: scripts/openbao-ui-overlay-apply.sh
|
||||||
|
|
||||||
Builds and applies the OpenBao KeyCape login overlay ConfigMaps and gateway
|
Builds and applies the OpenBao KeyCape login overlay ConfigMaps and private
|
||||||
Deployment/Service/Ingress. Idempotent — safe to run on every openbao-deploy.
|
gateway Deployment/ClusterIP Service. Idempotent — safe on every deploy. It
|
||||||
|
does not create or delete a public Ingress.
|
||||||
|
|
||||||
Environment:
|
Environment:
|
||||||
OPENBAO_NAMESPACE Kubernetes namespace. Default: openbao
|
OPENBAO_NAMESPACE Kubernetes namespace. Default: openbao
|
||||||
|
|
@ -71,4 +72,4 @@ $KUBECTL rollout restart deployment/openbao-ui-gateway -n "$OPENBAO_NAMESPACE"
|
||||||
# shellcheck disable=SC2086
|
# shellcheck disable=SC2086
|
||||||
$KUBECTL rollout status deployment/openbao-ui-gateway -n "$OPENBAO_NAMESPACE" --timeout=120s
|
$KUBECTL rollout status deployment/openbao-ui-gateway -n "$OPENBAO_NAMESPACE" --timeout=120s
|
||||||
|
|
||||||
printf '[OK] OpenBao UI overlay applied from %s\n' "$OVERLAY_DIR"
|
printf '[OK] OpenBao UI overlay applied from %s\n' "$OVERLAY_DIR"
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
|
|
||||||
BASE_URL="${OPENBAO_UI_BASE_URL:-https://bao.coulomb.social}"
|
BASE_URL="${OPENBAO_UI_BASE_URL:-http://127.0.0.1:18200}"
|
||||||
OVERLAY_DIR="${OPENBAO_UI_OVERLAY_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/helm/openbao-ui-overlay}"
|
OVERLAY_DIR="${OPENBAO_UI_OVERLAY_DIR:-$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)/helm/openbao-ui-overlay}"
|
||||||
CHECK_DRIFT="${CHECK_UPSTREAM_DRIFT:-0}"
|
CHECK_DRIFT="${CHECK_UPSTREAM_DRIFT:-0}"
|
||||||
|
|
||||||
|
|
@ -13,11 +13,11 @@ usage() {
|
||||||
cat <<'USAGE'
|
cat <<'USAGE'
|
||||||
Usage: scripts/openbao-verify-login-overlay.sh [--check-upstream-drift]
|
Usage: scripts/openbao-verify-login-overlay.sh [--check-upstream-drift]
|
||||||
|
|
||||||
Verifies the public OpenBao UI serves the KeyCape login overlay assets and
|
Verifies the operator-tunneled OpenBao UI serves the KeyCape login overlay
|
||||||
that index.html injection is present.
|
assets and that index.html injection is present.
|
||||||
|
|
||||||
Environment:
|
Environment:
|
||||||
OPENBAO_UI_BASE_URL Public UI base URL. Default: https://bao.coulomb.social
|
OPENBAO_UI_BASE_URL Operator UI base URL. Default: http://127.0.0.1:18200
|
||||||
OPENBAO_UI_OVERLAY_DIR Local overlay directory for drift fingerprints
|
OPENBAO_UI_OVERLAY_DIR Local overlay directory for drift fingerprints
|
||||||
CHECK_UPSTREAM_DRIFT Set to 1 to compare live UI hashes with patches/
|
CHECK_UPSTREAM_DRIFT Set to 1 to compare live UI hashes with patches/
|
||||||
USAGE
|
USAGE
|
||||||
|
|
@ -170,4 +170,4 @@ if [ "$CHECK_DRIFT" = "1" ]; then
|
||||||
ok "vault bundle hash matches patches/$version/manifest.sha256 (${expected_vault_path:-$vault_asset})"
|
ok "vault bundle hash matches patches/$version/manifest.sha256 (${expected_vault_path:-$vault_asset})"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
printf '\nOpenBao login overlay verification passed for %s\n' "$BASE_URL"
|
printf '\nOpenBao login overlay verification passed for %s\n' "$BASE_URL"
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@ type: workplan
|
||||||
title: "Contain attended OpenBao login output before authentication"
|
title: "Contain attended OpenBao login output before authentication"
|
||||||
domain: financials
|
domain: financials
|
||||||
repo: railiance-platform
|
repo: railiance-platform
|
||||||
status: ready
|
status: finished
|
||||||
owner: codex
|
owner: codex
|
||||||
topic_slug: railiance
|
topic_slug: railiance
|
||||||
created: "2026-08-23"
|
created: "2026-08-23"
|
||||||
|
|
@ -50,7 +50,7 @@ seal/unseal ceremony, or reuse of the terminal drill scenario.
|
||||||
|
|
||||||
```task
|
```task
|
||||||
id: RAILIANCE-WP-0026-T01
|
id: RAILIANCE-WP-0026-T01
|
||||||
status: todo
|
status: done
|
||||||
priority: high
|
priority: high
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
@ -90,10 +90,19 @@ both reviewers, and `railiance-platform` accepts the exact revision. Completion
|
||||||
of this task still does not authorize a live drill; that requires fresh owner
|
of this task still does not authorize a live drill; that requires fresh owner
|
||||||
receipts, current preflight, and a new human decision under a new scenario id.
|
receipts, current preflight, and a new human decision under a new scenario id.
|
||||||
|
|
||||||
|
Completed 2026-08-23. Railiance Platform accepts ops-warden revision
|
||||||
|
`0fae0904ce8d8694338dd53a8a79abec5fec788d`. The committed owner receipt at
|
||||||
|
ops-warden revision `bc1966da825fbeaa4d83947a4f942b5d5f085408` has SHA-256
|
||||||
|
`d2ba444ed16989590325697e69d25283dc75a9432c29a72e627e80bf9fd987e4`,
|
||||||
|
reports 42 focused tests and 390 repository tests passing, and records all
|
||||||
|
seven containment outcomes without sensitive material. Independent
|
||||||
|
railiance-infra review at revision `186b030` approves the same implementation.
|
||||||
|
This is source acceptance only and authorizes no live OIDC or drill.
|
||||||
|
|
||||||
## Acceptance
|
## Acceptance
|
||||||
|
|
||||||
- [ ] The adapter refuses unsafe storage before OIDC.
|
- [x] The adapter refuses unsafe storage before OIDC.
|
||||||
- [ ] No underlying login output can reach the agent transcript.
|
- [x] No underlying login output can reach the agent transcript.
|
||||||
- [ ] Any issued credential is contained and revoked on failure.
|
- [x] Any issued credential is contained and revoked on failure.
|
||||||
- [ ] Focused success and failure-path tests pass without credential material.
|
- [x] Focused success and failure-path tests pass without credential material.
|
||||||
- [ ] Both direct reviewers receive and accept the value-safe fix receipt.
|
- [x] Both direct reviewers receive and accept the value-safe fix receipt.
|
||||||
|
|
|
||||||
66
workplans/RAILIANCE-WP-0027-openbao-operator-only-access.md
Normal file
66
workplans/RAILIANCE-WP-0027-openbao-operator-only-access.md
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
---
|
||||||
|
id: RAILIANCE-WP-0027
|
||||||
|
type: workplan
|
||||||
|
title: "Retract public OpenBao listener behind operator-only access"
|
||||||
|
domain: financials
|
||||||
|
repo: railiance-platform
|
||||||
|
status: blocked
|
||||||
|
owner: codex
|
||||||
|
topic_slug: railiance
|
||||||
|
created: "2026-08-23"
|
||||||
|
updated: "2026-08-23"
|
||||||
|
related:
|
||||||
|
- RMASTER-WP-0020-T09
|
||||||
|
- RAPP-OPENBAO-WP-0002
|
||||||
|
---
|
||||||
|
|
||||||
|
# RAILIANCE-WP-0027 — 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: RAILIANCE-WP-0027-T01
|
||||||
|
status: done
|
||||||
|
priority: high
|
||||||
|
```
|
||||||
|
|
||||||
|
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: RAILIANCE-WP-0027-T02
|
||||||
|
status: done
|
||||||
|
priority: high
|
||||||
|
```
|
||||||
|
|
||||||
|
`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: RAILIANCE-WP-0027-T03
|
||||||
|
status: wait
|
||||||
|
priority: high
|
||||||
|
```
|
||||||
|
|
||||||
|
Blocked on two facts: KeyCape and the OpenBao role must accept the exact
|
||||||
|
loopback 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.
|
||||||
|
|
||||||
|
This workplan authorizes no OpenBao seal/unseal, policy broadening, PVC or
|
||||||
|
Secret mutation, reboot, restore, or RMASTER-WP-0020-T08 cleanup.
|
||||||
Loading…
Add table
Add a link
Reference in a new issue