diff --git a/workplans/RAILIANCE-WP-0011-reuse-surface-runtime-secrets-openbao-lane.md b/workplans/RAILIANCE-WP-0011-reuse-surface-runtime-secrets-openbao-lane.md new file mode 100644 index 0000000..3758962 --- /dev/null +++ b/workplans/RAILIANCE-WP-0011-reuse-surface-runtime-secrets-openbao-lane.md @@ -0,0 +1,125 @@ +--- +id: RAILIANCE-WP-0011 +type: workplan +title: "reuse-surface Runtime Secrets OpenBao Lane" +domain: financials +repo: railiance-platform +status: backlog +owner: codex +topic_slug: railiance +created: "2026-07-07" +updated: "2026-07-07" +depends_on_workplans: + - RAILIANCE-WP-0007 + - RAILIANCE-WP-0008 +related_repos: + - railiance-apps + - reuse-surface + - ops-warden +--- + +# RAILIANCE-WP-0011 — reuse-surface Runtime Secrets OpenBao Lane + +## Goal + +Promote reuse-surface hub runtime secrets from bootstrap Kubernetes Secret +custody to a reviewed OpenBao workload KV lane delivered by External Secrets +Operator, matching the platform pattern used by issue-core, OpenRouter, and +Forgejo mailer. + +Today both secrets live in `reuse/reuse-surface-env` on Railiance01: + +| Field | Consumer | +| --- | --- | +| `REUSE_SURFACE_TOKEN` | Hub write API; operators via `warden access` / kubectl | +| `REUSE_SURFACE_FORGEJO_WEBHOOK_SECRET` | Hub webhook receiver; Forgejo org webhook HMAC | + +Functional custody in K8s is sufficient for production today (live since +2026-07-07). This workplan is **hygiene and standardization**, not a blocker. + +No task may paste, commit, log, or send secret values through Git, State Hub, +chat, prompts, shell history, or workplan text. + +## Proposed contract + +| Item | Proposed value | +| --- | --- | +| Tenant/org | `reuse` | +| Workload | `reuse-surface` | +| KV mount | `platform` | +| OpenBao CLI path | `platform/workloads/reuse/reuse-surface/runtime-secrets` | +| Secret fields | `REUSE_SURFACE_TOKEN`, `REUSE_SURFACE_FORGEJO_WEBHOOK_SECRET` | +| Read policy | `workload-kv-read-reuse-surface-runtime` (name TBD at CCR) | +| K8s auth role | `external-secrets-reuse-surface` (name TBD at CCR) | +| ExternalSecret | `reuse/reuse-surface-runtime` → target Secret `reuse-surface-env` | +| ops-warden catalog | migrate `reuse-surface-hub-write-token` handoff to Bao path | + +Dual-consumer note: Forgejo org webhook must be updated whenever the webhook +HMAC rotates — document in `railiance-apps/docs/reuse-surface-on-railiance01.md` +and keep `make reuse-forgejo-webhook` idempotent. + +## Draft OpenBao + ESO Lane + +```task +id: RAILIANCE-WP-0011-T01 +status: todo +priority: medium +``` + +- Draft CCR for the lane (path, fields, policy, k8s role, ESO target) +- Align with `docs/openbao.md` path convention and + `docs/credential-lane-lifecycle-runbook.md` +- Negative review: no secret values in CCR or workplan text + +## Platform Apply And Verification + +```task +id: RAILIANCE-WP-0011-T02 +status: wait +priority: medium +``` + +Blocked on T01 approval. + +- Apply OpenBao policy + Kubernetes auth role (mirror forgejo-mailer / issue-core scripts) +- Seed path from existing cluster Secret (one-time operator step; value never logged) +- Add `manifests/reuse-surface-runtime-externalsecret.yaml` in `railiance-apps` +- Verify ExternalSecret `SecretSynced` and pod env injection after rollout +- Record non-secret audit evidence (positive + negative reads) + +## Consumer Handoff And Catalog Migration + +```task +id: RAILIANCE-WP-0011-T03 +status: wait +priority: low +``` + +Blocked on T02 verification. + +- Update `railiance-apps/docs/reuse-surface-on-railiance01.md` custody section +- Update ops-warden `reuse-surface-hub-write-token` playbook + routing catalog + (`fetch_command` → `bao kv get -field=...`) +- Add lane to `docs/workload-kv-access-lanes.md` +- Deprecate direct kubectl fetch as primary handoff (keep as break-glass note) + +## Forgejo Webhook Rotation Runbook + +```task +id: RAILIANCE-WP-0011-T04 +status: wait +priority: low +``` + +Blocked on T02. + +- Document rotation: update OpenBao field → ESO sync → rollout → + `make reuse-forgejo-webhook` (updates org hook secret) +- Add smoke: signed webhook POST returns 200/accepted or expected no-op + +## Acceptance + +- [ ] Both fields readable from `platform/workloads/reuse/reuse-surface/runtime-secrets` +- [ ] ESO owns `reuse-surface-env`; manual `kubectl create secret` no longer required for steady state +- [ ] `warden access reuse-surface-hub-write-token --fetch` uses OpenBao path +- [ ] Forgejo org webhook and hub HMAC stay aligned after a test rotation \ No newline at end of file