reuse_policy leaves external-secrets-audit-core intact so database leases keep working. AppRole delivered to Kubernetes; interim static ESO token retired.
7.7 KiB
| id | demand_source | consumer_repo | credential_type | status | approved_by | approved_at | created | updated |
|---|---|---|---|---|---|---|---|---|
| audit-core-openbao-runtime-custody | audit-core/workplans/AUDIT-WP-0005-T02 | audit-core | openbao-approle-kv | built | Bernd Worsch | 2026-08-13 | 2026-08-13 | 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-postgresprovisionedaudit_corewithaudit_core_app/audit_core_migrate, and OpenBao already vendsdatabase/creds/audit-core-runtimeanddatabase/creds/audit-core-migrationthrough railiance-platform grantsrapp-postgres/audit-core-runtimeandrapp-postgres/audit-core-migration.warden route show database-dynamic-credentialspoints 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-tokenwas minted 2026-08-13 with policyexternal-secrets-audit-core(read on the two database cred paths and onplatform/data/workloads/audit-core/senders). ClusterSecretStore YAML is drafted; it is not yet applied. - KV senders path does not exist. A founder
bao kv putagainstplatform/workloads/audit-core/senders403’d because the workstation~/.vault-tokenis not an operator identity. That is the failure this plan exists to retire. - Catalog.
database-dynamic-credentialsalready covers the lease. There is noaudit-core-sendersentry.openbao-api-keyis 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-corematches 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-coreonly. - Redundancy: does not create a second database role or a KV cache of
the lease. Does not widen
openbao-email-connectoropenbao-user-engine-runtime. - Compaction: retires the attended
bao kv putpath 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
baocommand 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.
6. Build result
Built 2026-08-13 after founder approve, via
ops_mason.executor.build_approle_kv_lane with reuse_policy=True so
the existing external-secrets-audit-core policy (database creds +
senders read) was not rewritten.
- reused policy
external-secrets-audit-core; - created AppRole
external-secrets-audit-core(15m / 30m / 8 uses); - delivered role-id/secret-id into Secret
external-secrets/openbao-audit-core-approle; local delivery dir shredded; - switched ClusterSecretStores
openbao-audit-coreandopenbao-audit-core-databaseto AppRole auth; bothValid; - ExternalSecrets remain
SecretSynced; receiver/readyzstillcustody_class=archive; - deleted interim Secret
external-secrets/openbao-audit-core-eso-token; - catalog entry
audit-core-sendersalready drafted in ops-warden (warden route find "audit-core senders" --all).
Empty KV path platform/workloads/audit-core/senders was not written:
mason does not put values, and senders already live in-cluster. A later
wrap-migrate can create that path without a founder paste.
No secret value was printed, committed, or logged. The 15-minute platform-admin child used for the build was revoked.