docs: plan production lifecycle hardening
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a0217e-8c4c-7383-be6b-f50a6e485306
This commit is contained in:
tegwick 2026-08-23 11:27:10 +02:00
parent 7799716c73
commit 0617923ff1
2 changed files with 339 additions and 0 deletions

View file

@ -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

View file

@ -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.