From 0617923ff135e6df83fb80a31b3239145a31e339 Mon Sep 17 00:00:00 2001 From: tegwick Date: Sun, 23 Aug 2026 11:27:10 +0200 Subject: [PATCH] docs: plan production lifecycle hardening Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a0217e-8c4c-7383-be6b-f50a6e485306 --- .../SECRETS-WP-0006-catalog-lane-adoption.md | 7 + ...-WP-0007-production-lifecycle-hardening.md | 332 ++++++++++++++++++ 2 files changed, 339 insertions(+) create mode 100644 workplans/SECRETS-WP-0007-production-lifecycle-hardening.md diff --git a/workplans/SECRETS-WP-0006-catalog-lane-adoption.md b/workplans/SECRETS-WP-0006-catalog-lane-adoption.md index 62be5f4..bf111d4 100644 --- a/workplans/SECRETS-WP-0006-catalog-lane-adoption.md +++ b/workplans/SECRETS-WP-0006-catalog-lane-adoption.md @@ -203,6 +203,13 @@ Requested per-lane approval references and scoped attended/apply authority from railiance-platform in message `3db3da86-2f3f-4301-8be6-74b507ea66a0`. No value was read and no OpenBao mutation was attempted. +Hardening dependency 2026-08-23: `SECRETS-WP-0007` now owns the engine-level +provisioning, lifecycle, approval-binding, delivery-session, verification, and +evidence gaps found during scope assessment. T05 must not provision or revoke +the existing shared paths through the current commands. Native live adoption +resumes through `SECRETS-WP-0007-T07` after its T01-T06 safety gates; this task +continues to own the per-lane production evidence and acceptance outcome. + For each lane, obtain the required decision/operator approval before any live OpenBao policy, auth-role, provisioning, rotation, or delivery change. Start with metadata/capability-safe checks and preserve the current ops-warden proxy diff --git a/workplans/SECRETS-WP-0007-production-lifecycle-hardening.md b/workplans/SECRETS-WP-0007-production-lifecycle-hardening.md new file mode 100644 index 0000000..52a293b --- /dev/null +++ b/workplans/SECRETS-WP-0007-production-lifecycle-hardening.md @@ -0,0 +1,332 @@ +--- +id: SECRETS-WP-0007 +type: workplan +title: "Production-safe provisioning, authorization, and lifecycle hardening" +domain: infotech +repo: secrets-engine +status: ready +owner: codex +topic_slug: custodian +created: "2026-08-23" +updated: "2026-08-23" +--- + +# SECRETS-WP-0007 - Production-safe provisioning, authorization, and lifecycle hardening + +## Goal + +Close the highest-risk gaps between the proven CLI MVP and the production +workflow described by `INTENT.md`, before expanding secrets-engine into a +service or moving additional high-risk lanes from interim routing to native +operation. + +The source assessment is +`history/2026-08-23-scope-intent-capability-gap-assessment.md`. The most relevant +gaps are: + +1. single-field `bao kv put` can replace siblings on a multi-field path and puts + the value in the local subprocess argument vector; +2. KV `revoke` destroys metadata while leaving policy/AppRole access behind, + and its dry-run does not match live behavior; +3. production approval checks are coarse status checks, accept local fixtures, + and do not bind actor, action, lane, fields, expiry, or dual control; +4. AppRole delivery tokens are not explicitly revoked after exec/verification; +5. route and verification can attest only the first field and use a garbage + token rather than a real unrelated identity for KV denial; +6. evidence is best-effort and incomplete on failure paths. + +## Scope and sequencing + +This workplan hardens the existing CLI contract first. It covers KV write +transport and merge semantics, lifecycle command semantics, decision binding, +short-lived delivery sessions, verification/readiness, and evidence. It then +provides the safe implementation gate for resuming `SECRETS-WP-0006-T05/T06`. + +The first task is containment. No task may exercise live production values to +develop or test a primitive. Use fake values and a throwaway OpenBao instance +until the relevant behavior has passed unit and integration tests. Existing ESO, +Kubernetes/OIDC delivery, provider rotation, and application health remain with +their current owners. + +## Non-goals + +- A service API, daemon, UI, scheduler, or remote multi-user protocol. +- Runtime tenant authentication, quotas, or a tenant control plane. +- A second custody backend or backend-portability project. +- Provider-specific rotation automation. +- Replacing flex-auth, State Hub decisions, key-cape/user-engine identity, + ops-warden routing, ops-bridge transport, or OpenBao enforcement. +- Unparking the standalone `warden-sign` AppRole as a break-glass path. + +Service mode remains deferred until the exit criteria here are satisfied; it +must not expose the current bootstrap and lifecycle shortcuts as an API. + +## Safety invariants + +- No raw value in Git, State Hub, chat, prompts, workplans, evidence, normal + logs, environment diagnostics, or a subprocess argument vector. +- No write to a shared multi-field path unless sibling preservation is proven. +- No destructive metadata deletion through a command presented as ordinary + revoke/deactivate. +- Production actions require canonical, exact-action approval. Offline fixtures + cannot authorize steady-state production mutations or delivery. +- Existing workload delivery stays in place until separately approved owner + coordination says otherwise. +- Tests use fake values and throwaway OpenBao only; live checks are + metadata/capability-safe and approval-gated. + +## Contain unsafe lifecycle surfaces + +```task +id: SECRETS-WP-0007-T01 +status: todo +priority: high +``` + +Add immediate fail-closed guards before implementing replacement primitives: + +- reject `provision` on an existing multi-field lane; +- reject or rename the current destructive KV `revoke` path so it cannot be + mistaken for soft deactivation; +- make KV revoke dry-run render exactly the operations the live path would run; +- document that `SECRETS-WP-0006` may apply/verify metadata but must not provision + or revoke shared values through the current commands. + +Acceptance: + +- A regression test proves no backend call occurs for multi-field existing-lane + provisioning. +- A regression test proves dry-run and live operation plans contain the same KV, + AppRole, and policy targets. +- The destructive action requires an explicit name/flag and a separately + approved action; ordinary revoke cannot destroy KV metadata. +- CLI/help/runbook language no longer describes metadata deletion as reversible + deactivation. + +## Implement merge-safe, non-argv provisioning + +```task +id: SECRETS-WP-0007-T02 +status: todo +priority: high +``` + +Replace the raw `field=value` subprocess call with a backend write primitive +that never places the value in argv and safely updates one or more declared +fields without removing unmentioned siblings. The design may use OpenBao CAS, +a merge/patch operation, an input file reference with strict cleanup, or direct +request input, but it must remain isolated behind `OpenBaoClient` and preserve +the catalog field allowlist. + +Acceptance: + +- Unit tests inspect the complete subprocess request and prove the fake value is + absent from argv, environment, output, exceptions, and evidence. +- Throwaway OpenBao integration proves updating one field preserves every + sibling field and fails closed on a CAS conflict. +- Multi-field input is atomic from the caller's perspective; a partial failure + cannot silently leave an unreported mixed version. +- Source and generated inputs retain mode/path guards and guaranteed temporary + cleanup. +- Production generation remains forbidden, and high-risk production + provisioning is still decision- and dual-control-gated. + +## Split suspend, deactivate, and destroy semantics + +```task +id: SECRETS-WP-0007-T03 +status: todo +priority: high +``` + +Replace the overloaded `revoke` behavior with explicit lifecycle operations and +plans. Define at least: + +- **suspend delivery**: stop minting new native delivery sessions while + preserving custody and a documented rollback; +- **deactivate native access**: remove/disable the lane AppRole and consumer + policy without deleting the KV value; +- **revoke issued sessions**: revoke known tokens/leases by non-secret accessor + where the backend supports it; +- **destroy custody metadata**: irreversibly delete KV metadata/versions only + through an unmistakable, separately approved action. + +Preserve compatibility only where it cannot mislead. A legacy `revoke` alias +may map to a safe non-destructive action; it must never silently retain the +current destructive meaning. + +Acceptance: + +- Each operation has a guarded dry-run plan, exact targets, distinct approval + action, non-secret evidence, and documented rollback/irreversibility. +- Dry-run and live use the same plan object rather than separate handwritten + descriptions. +- Integration tests prove suspend/deactivate preserve KV data and destroy does + not run without its explicit approval and confirmation contract. +- Auth-capability and KV lanes have coherent but kind-appropriate behavior. +- Existing workload delivery is reported as an external dependency and is not + deleted by native lifecycle commands. + +## Bind approvals to exact production actions + +```task +id: SECRETS-WP-0007-T04 +status: todo +priority: high +``` + +Define and enforce the decision contract needed by production commands. A +resolved approval must bind at least: + +- canonical decision UUID and non-superseded status; +- catalog id and stage; +- action (`apply`, `provision`, `verify`, `exec`, `handoff`, `suspend`, + `deactivate`, `destroy`, or later `rotate`); +- exact field set or policy/auth targets where applicable; +- requesting actor/purpose and expiry or bounded execution window; +- required approval count and distinct approvers for `dual-control`. + +Coordinate the external object shape with State Hub/flex-auth rather than +inventing authorization ownership in this repo. Keep local fixtures for +throwaway demos and non-production tests only; require an explicit unsafe-demo +switch if they remain reachable at all. + +Acceptance: + +- Every privileged production handler passes an action-specific request into + one shared authorization function. +- Tests reject wrong lane, stage, action, field set, actor/purpose, expiry, + superseded status, insufficient approvals, duplicate approvers, and local + production fixtures before any OpenBao call. +- `approval.model: dual-control` has enforced semantics rather than being a + label. +- Catalogs use resolvable canonical decision UUIDs for live actions; legacy CCR + references remain provenance, not executable authorization. +- State Hub outage fails production actions closed while dry-run/catalog + inspection remains usable. + +## Make delivery sessions short-lived and explicitly closed + +```task +id: SECRETS-WP-0007-T05 +status: todo +priority: high +``` + +Refactor AppRole login into a scoped session object that retains only the +minimum non-secret lifecycle handle needed to revoke the issued token in a +`finally` path. Apply it consistently to exec, KV verification, auth-capability +verification, and any future file/wrapped delivery. + +Define the steady-state OpenBao authentication interface separately from the +delivery AppRole. Bootstrap token files remain an explicit break-glass/setup +provider; add a bounded OIDC/service-auth provider only with railiance-platform +and identity-owner review. + +Acceptance: + +- Success, child non-zero exit, setup failure, verification failure, SIGINT, and + SIGTERM tests all attempt token revocation and clean temporary material. +- Secret IDs remain single-use where configured; tokens retain TTL/use limits + as backstops rather than their only cleanup. +- Evidence records session establishment/revocation outcome using non-secret + handles or request ids only. +- A failed revocation is visible and actionable without printing token or + accessor material. +- Bootstrap-file authentication is clearly separated from the reviewed + steady-state provider and cannot become an implicit fallback. + +## Strengthen verification, readiness, and evidence + +```task +id: SECRETS-WP-0007-T06 +status: todo +priority: high +``` + +Make verification and routing truthful for multi-field and high-risk lanes: + +- verify every declared field unless the exact approved subset is explicit; +- make route readiness require every required field, not only the first; +- replace the garbage-token negative check with a reviewed real unrelated + identity/token or a capabilities-based denial proof that can detect policy + overlap; +- record attempt, success/failure, cleanup, and authorization outcome for every + privileged command; +- correlate engine evidence with OpenBao audit request ids where available; +- provide a non-secret lane audit summary over local/State Hub evidence. + +Acceptance: + +- Removing any required sibling field makes readiness false and identifies only + the missing field name, never values. +- Negative verification fails when a deliberately overlapping unrelated policy + is introduced in throwaway OpenBao. +- Evidence tests cover backend exceptions, child failures, State Hub delivery + failures, and cleanup failures without leaking fake secret patterns. +- An audit/report command summarizes decisions, attempts, outcomes, and cleanup + for a lane without becoming an authority or replacing OpenBao audit logs. +- The full test suite and throwaway OpenBao integration suite pass. + +## Resume native production lane adoption + +```task +id: SECRETS-WP-0007-T07 +status: wait +priority: high +``` + +Dependency: T01-T06 complete, then explicit per-lane approvals and scoped +production authority from railiance-platform. + +Resume `SECRETS-WP-0006-T05` lane by lane. Apply only the exact native policy and +bounded AppRole, verify every field plus unrelated-consumer denial, confirm the +existing workload delivery remains healthy, exercise only an approved +value-safe child command, and record rollback/session-cleanup evidence. + +After a lane passes, complete `SECRETS-WP-0006-T06` with ops-warden. Retire its +interim proxy only after both parties agree that native readiness evidence is +complete. Do not batch-retire all five lanes. + +Acceptance per lane: + +- Canonical action-bound approval is resolved and linked. +- Policy/AppRole server readback matches the reviewed exact-path plan. +- All declared fields pass presence/access checks; a real unrelated identity is + denied; no value enters evidence. +- Issued delivery sessions are explicitly revoked and cleanup is evidenced. +- Existing ESO/OIDC delivery and application health remain good according to + their owners. +- Rollback is rehearsed or capabilities-safe verified before proxy retirement. +- ops-warden routing reports native readiness and removes only that lane's + interim proxy. + +## Dependencies and coordination + +- `SECRETS-WP-0006` owns the five-lane catalog admission and live cutover. +- railiance-platform owns production OpenBao authority, custody, and backend + audit. +- State Hub/flex-auth own the canonical decision/authorization contract. +- key-cape/user-engine own human/service identity and claims. +- Workload owners own ESO/Kubernetes delivery and provider/application health. +- ops-warden owns credential routing and interim proxy disposition. + +Any external contract change must be recorded as non-secret evidence and must +not transfer custody or authorization ownership into this repository. + +## Exit criteria + +- Current unsafe multi-field provisioning and misleading revoke behavior are + contained and replaced. +- Raw values cannot enter subprocess argv or evidence through provisioning. +- Production approvals are canonical, exact-action, expiring, and genuinely + dual-control-capable. +- Delivery tokens are explicitly revoked on every exit path. +- Readiness and verification cover all declared fields and meaningful unrelated + identities. +- Lifecycle operations distinguish reversible access suspension from irreversible + custody destruction. +- At least one of the five admitted production lanes completes the hardened + native verification/cutover path; remaining lanes have explicit external + blockers rather than engine-safety blockers. +- Service-mode design remains deferred until these guarantees are demonstrated.