Review construction plan for audit-core OpenBao runtime custody
Awaiting founder approve. Receiver already runs on the interim ESO token; phase 4 replaces it with an AppRole and an empty senders KV path.
This commit is contained in:
parent
dcc933abd5
commit
93b9c1a027
1 changed files with 120 additions and 0 deletions
120
plans/audit-core-openbao-runtime-custody.md
Normal file
120
plans/audit-core-openbao-runtime-custody.md
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
---
|
||||
id: audit-core-openbao-runtime-custody
|
||||
demand_source: audit-core/workplans/AUDIT-WP-0005-T02
|
||||
consumer_repo: audit-core
|
||||
credential_type: openbao-approle-kv
|
||||
status: reviewed
|
||||
approved_by: null
|
||||
approved_at: null
|
||||
created: "2026-08-13"
|
||||
updated: "2026-08-13"
|
||||
---
|
||||
|
||||
# Construction plan: audit-core OpenBao runtime custody
|
||||
|
||||
## 1. Demand
|
||||
|
||||
audit-core on railiance01 needs durable PostgreSQL custody and a sender
|
||||
registry without the founder typing OpenBao tokens or running `bao kv put`.
|
||||
The founder’s remaining acts are: approve this plan, and unseal OpenBao if
|
||||
it is sealed. Mechanics belong to ops-mason (structure) and ops-warden
|
||||
(routing / founder desk), not to an ad-hoc terminal session.
|
||||
|
||||
## 2. Existing-structure survey
|
||||
|
||||
Checked 2026-08-13 against live railiance01 and the routing catalog:
|
||||
|
||||
- **Database leases already exist.** `rapp-postgres` provisioned `audit_core`
|
||||
with `audit_core_app` / `audit_core_migrate`, and OpenBao already vends
|
||||
`database/creds/audit-core-runtime` and `database/creds/audit-core-migration`
|
||||
through railiance-platform grants `rapp-postgres/audit-core-runtime` and
|
||||
`rapp-postgres/audit-core-migration`. `warden route show
|
||||
database-dynamic-credentials` points at that playbook. Do not create a
|
||||
second database engine or a KV copy of a rotating lease.
|
||||
- **ESO token already exists.** `external-secrets/openbao-audit-core-eso-token`
|
||||
was minted 2026-08-13 with policy `external-secrets-audit-core` (read on
|
||||
the two database cred paths and on `platform/data/workloads/audit-core/senders`).
|
||||
ClusterSecretStore YAML is drafted; it is not yet applied.
|
||||
- **KV senders path does not exist.** A founder `bao kv put` against
|
||||
`platform/workloads/audit-core/senders` 403’d because the workstation
|
||||
`~/.vault-token` is not an operator identity. That is the failure this
|
||||
plan exists to retire.
|
||||
- **Catalog.** `database-dynamic-credentials` already covers the lease.
|
||||
There is no `audit-core-senders` entry. `openbao-api-key` is the generic
|
||||
template and must not become the concrete lane.
|
||||
- **Auth topology.** Same as user-engine / rapp-qonto: railiance01 ESO
|
||||
cannot use CoulombCore Kubernetes auth. AppRole is the transitional
|
||||
bridge; same-cluster Kubernetes auth remains the target.
|
||||
- **Does an existing lane already satisfy this?** The database half, yes —
|
||||
bind to the existing OpenBao database roles. The sender-registry half,
|
||||
no — there is no path, no AppRole, and no catalog entry. Reuse the
|
||||
email-connect / user-engine *shape* (namespace-limited store, 15m
|
||||
tokens, eight uses), do not widen those identities.
|
||||
|
||||
## 3. Proposed changes
|
||||
|
||||
| # | Action | Object | Reuse-vs-new rationale |
|
||||
|---|---|---|---|
|
||||
| 1 | reuse | OpenBao roles `audit-core-runtime` / `audit-core-migration` | Already vended; a KV copy of a lease recreates the delivery gap |
|
||||
| 2 | reuse | policy `external-secrets-audit-core` | Already written; covers database creds + senders read |
|
||||
| 3 | create | AppRole `external-secrets-audit-core` | Replace the long-lived ESO token with the same 15m/30m/8-use bridge as user-engine and rapp-qonto |
|
||||
| 4 | deliver | Secret `external-secrets/openbao-audit-core-approle` | Mason write-only delivery of role_id/secret_id; never logged |
|
||||
| 5 | create | ClusterSecretStore `openbao-audit-core` | Namespace-limited to `audit-core`; AppRole auth (token store is the interim until this builds) |
|
||||
| 6 | reuse | ClusterSecretStore `openbao-audit-core-database` + ExternalSecret | Namespaced VaultDynamicSecret cannot read the ESO token in `external-secrets`; CSS can. One `dataFrom` extract per lease. Applied 2026-08-13, SecretSynced |
|
||||
| 7 | create | empty KV path `platform/workloads/audit-core/senders` | Structure only. Values are **not** founder-pasted: first deploy mints sender tokens in-cluster into Secret `audit-core-senders`. A later wrap-migrate (user-engine pattern) can move them into this path without printing |
|
||||
| 8 | propose | ops-warden catalog `audit-core-senders` | Pointer, `warden_executes: false`, starts `draft` |
|
||||
| 9 | retire | founder `bao kv put` / token-prompt as the T02 delivery path | That is the error-prone interaction this demand forbids |
|
||||
|
||||
No sibling workload path is readable. Mason does not print, log, or return
|
||||
sender tokens or database passwords.
|
||||
|
||||
## 4. Review notes
|
||||
|
||||
- **Naming:** `external-secrets-audit-core` / `openbao-audit-core` matches
|
||||
email-connect and user-engine. Database grant names stay with rapp-postgres.
|
||||
- **TTL/scoping:** 15-minute tokens, 30-minute max, eight uses. Store
|
||||
condition is `audit-core` only.
|
||||
- **Redundancy:** does not create a second database role or a KV cache of
|
||||
the lease. Does not widen `openbao-email-connect` or
|
||||
`openbao-user-engine-runtime`.
|
||||
- **Compaction:** retires the attended `bao kv put` path as the way T02
|
||||
completes. The already-minted static ESO token is interim and is revoked
|
||||
after the AppRole store is Ready.
|
||||
- **Secret values:** sender tokens are generated by us, not imported from a
|
||||
vendor. Founder paste-once is the wrong desk for them. Generate in-cluster;
|
||||
optional later wrap-migrate into the empty KV path.
|
||||
- **Founder remaining acts:** approve this plan; unseal OpenBao if sealed.
|
||||
No token paste, no `bao` command review.
|
||||
|
||||
## 5. Executive summary
|
||||
|
||||
**One-line ask:** approve letting ops-mason finish audit-core’s OpenBao
|
||||
lane (AppRole + namespace-limited store + empty senders path + catalog
|
||||
pointer) so the receiver can run without you typing OpenBao tokens.
|
||||
|
||||
**Who gets access:** only External Secrets, through AppRole
|
||||
`external-secrets-audit-core`. Application pods keep seeing mounted
|
||||
files and `AUDIT_CORE_SENDERS`. Nothing else gains a new identity.
|
||||
|
||||
**To what:** read `database/creds/audit-core-runtime`,
|
||||
`database/creds/audit-core-migration`, and (later)
|
||||
`platform/workloads/audit-core/senders`. No sibling workload or tenant
|
||||
path.
|
||||
|
||||
**For how long:** each AppRole login is 15 minutes, 30 minutes maximum,
|
||||
eight uses. The AppRole secret ID lasts until rotated or replaced by
|
||||
same-cluster Kubernetes auth.
|
||||
|
||||
**Blast radius if the credential leaks:** append to the audit trail and
|
||||
read the sender registry; cannot rewrite or delete stored events (append-only
|
||||
trigger). Revoke the AppRole secret ID, rotate sender tokens overlap-first,
|
||||
and roll the receiver. Database leases expire on their own.
|
||||
|
||||
**Cost to reverse:** delete the AppRole, its bootstrap Secret, the
|
||||
ClusterSecretStore, and the empty KV path. Database roles and the
|
||||
`audit_core` database stay (owned by rapp-postgres). No other consumer
|
||||
is on this identity.
|
||||
|
||||
**Decision:** approve, reject, or send back to phase 1.
|
||||
Approval authorizes Mason build of structure and in-cluster sender
|
||||
minting. It does not authorize printing any secret value.
|
||||
Loading…
Add table
Add a link
Reference in a new issue