--- id: SECRETS-WP-0002 type: workplan title: "Bootstrap secrets-engine MVP" domain: platform-security repo: secrets-engine status: finished owner: codex created: "2026-06-28" updated: "2026-06-28" state_hub_workstream_id: "6c9a8c0d-18b5-41ac-8cd5-a8e84fb286b4" --- # SECRETS-WP-0002 - Bootstrap secrets-engine MVP ## Goal Create the first usable secrets-engine implementation: a decision-aware wrapper around OpenBao that can apply approved secret metadata, provision and verify a pilot secret lane, and deliver a credential to a workload command without printing the secret. The whynot-design npm publish token is the pilot case. ## Context The platform currently has OpenBao, credential-change requests, State Hub decisions, ops-warden routing, and initial workload KV lane definitions. The missing piece is a dedicated workflow engine that owns the interaction model and hides OpenBao UI/CLI complexity from daily work. During bootstrap, a platform-root operator may create temporary OpenBao credentials for secrets-engine roles and provide their local file paths to the agent. This is a setup accelerator, not the desired steady state. ## Design Constraints - OpenBao remains the canonical custody and audit backend. - secrets-engine must not store raw secrets in Git, State Hub, chat, prompts, or normal logs. - Build, test, and production must have separate OpenBao privilege roles. - Production automation starts with approved metadata apply and safe delivery; raw value provisioning remains constrained and auditable. - ops-warden routes credential needs to secrets-engine but does not vend secrets. ## Tasks ## T01 - Seed repository structure and ownership docs ```task id: SECRETS-WP-0002-T01 status: done priority: high state_hub_task_id: "e974743b-29bb-42e0-b0c2-56d3fa9f6311" ``` Create the initial repository with: - `INTENT.md`; - `ProductRequirementsDocument.md`; - `docs/netkingdom-security-infrastructure.md`; - this workplan under `workplans/`; - `AGENTS.md` with no-secret-handling rules; - a minimal README pointing to the CLI and catalog direction. Acceptance: - The repo states that secrets-engine owns workflow and interaction, not OpenBao custody itself. - Boundaries with OpenBao, ops-warden, State Hub, key-cape/user-engine, and flex-auth are explicit. - No raw secret value appears in any seed file. ## T02 - Define catalog schema and path conventions ```task id: SECRETS-WP-0002-T02 status: done priority: high state_hub_task_id: "0a21de63-7d79-45f9-aac8-e42adbadae28" ``` Create a non-secret catalog schema for secret lanes and grants. The schema must include catalog id, owner, stage, OpenBao mount/path, fields, consumer binding, delivery modes, approval requirement, verification checks, rotation and deactivation expectations, and audit evidence requirements. Acceptance: - A validator rejects missing stage, mount, path, fields, approval model, and delivery modes. - The whynot-design npm publish lane can be represented without a secret value. - Build, test, and production entries can express different restrictions. ## T03 - Specify OpenBao stage roles and bootstrap policy ```task id: SECRETS-WP-0002-T03 status: done priority: high state_hub_task_id: "64ced137-6ff7-483b-80db-3b51afee7f0a" ``` Define the initial OpenBao roles and policies: - `secrets-engine-build`; - `secrets-engine-test`; - `secrets-engine-prod`. Also define the bootstrap token-file process for initial setup. Acceptance: - Policy docs list exact allowed and denied OpenBao paths for each role. - Production role cannot act as root, platform-admin, or broad auth/sys admin. - Bootstrap token files are documented as local-only, mode 0600, outside repos, revocable, and temporary. - Negative checks prove each role is denied outside its stage/prefix boundary. ## T04 - Implement CLI skeleton and dry-run planning ```task id: SECRETS-WP-0002-T04 status: done priority: high state_hub_task_id: "8cccc01e-4399-4bb3-9242-c3685d0916b4" ``` Implement an initial CLI with dry-run first: ```text secrets-engine catalog list secrets-engine catalog show secrets-engine decision inspect secrets-engine plan secrets-engine apply --stage --dry-run ``` Acceptance: - Dry-run renders policy, auth role, path, field, and verification actions. - Dry-run refuses unapproved, denied, superseded, or malformed requests. - Dry-run refuses broad policy names, wildcards, root/platform-admin semantics, and out-of-stage paths. ## T05 - Integrate State Hub decisions and evidence ```task id: SECRETS-WP-0002-T05 status: done priority: high state_hub_task_id: "64898c75-e113-4c39-916e-1a640475ddf7" ``` Connect the CLI to State Hub decision and progress APIs for non-secret metadata. Acceptance: - A decision can be inspected from the CLI. - The CLI prints or records a review URL when available. - Apply and verification write non-secret progress notes. - Secret values are never sent to State Hub. ## T06 - Implement OpenBao apply for approved metadata ```task id: SECRETS-WP-0002-T06 status: done priority: high state_hub_task_id: "b4b098d0-c6e0-4e50-a21e-b33d8ceea3e8" ``` Apply approved OpenBao ACL policies and auth roles through the selected stage role or temporary bootstrap credential. Acceptance: - Apply succeeds for the whynot-design metadata lane in the intended stage. - Apply is idempotent. - Apply refuses unapproved decisions and out-of-policy mutations. - Apply evidence contains no secret values. ## T07 - Implement safe provisioning and verification ```task id: SECRETS-WP-0002-T07 status: done priority: high state_hub_task_id: "1b458c09-a4e7-490c-acec-d55eff4bae6c" ``` Support initial provisioning modes: - attended operator provisioning; - local bootstrap file import with mode checks; - generated non-production test secrets. Add positive and negative verification commands that do not print raw values. Acceptance: - The whynot-design token can be confirmed present without printing it. - Positive verification proves the approved consumer can access/use it. - Negative verification proves an unrelated consumer is denied. - Verification evidence is non-secret and reviewable. ## T08 - Implement exec-time delivery for npm pilot ```task id: SECRETS-WP-0002-T08 status: done priority: high state_hub_task_id: "871cc4d4-4cbf-43be-98b7-3bad0d371f87" ``` Implement: ```bash secrets-engine exec --catalog whynot-design-npm-publish -- npm publish ``` For npm, prefer temporary config-file injection over printing/exporting the token. Clean up temporary files after the child process exits. Acceptance: - npm publish can run with the token available only to the child process. - The token is not printed, persisted in the repo, or written to normal logs. - The temp config file is deleted on success, failure, and interruption where possible. - The command refuses to run when the catalog entry is not approved and ready. ## T09 - Update ops-warden routing contract ```task id: SECRETS-WP-0002-T09 status: done priority: medium state_hub_task_id: "b6c14f2a-49b1-4f39-a909-ba02a78fbef5" ``` Define the contract ops-warden should use when routing non-SSH credential needs to secrets-engine. Acceptance: - Route output includes catalog id, readiness, decision status, and safe next command. - ops-warden does not request or store raw secret values. - whynot-design can retry the npm credential request and receive actionable guidance from the front door. ## T10 - Hardening backlog and exit from bootstrap mode ```task id: SECRETS-WP-0002-T10 status: done priority: medium state_hub_task_id: "52c070ec-33ac-4736-96e3-6bbacaa7fc83" ``` Create the hardening backlog needed after the pilot. Minimum items: - replace bootstrap token files with OIDC/service auth; - add response-wrapped handoff where suitable; - add production dual-control option; - add rotation and compromised/deactivated secret states; - add audit report command; - add API service mode after CLI semantics stabilize. Acceptance: - Bootstrap tokens have revocation tasks. - Production hardening steps are explicit and prioritized. - The MVP can close without pretending bootstrap mode is the final security state. ## Exit Criteria - The repo can represent and validate the whynot-design npm publish catalog entry. - An approved decision can become an OpenBao policy/auth-role apply without platform-root hand typing. - The secret value can be provisioned and verified without disclosure. - `secrets-engine exec --catalog whynot-design-npm-publish -- npm publish` is either working or blocked only on an explicit external condition. - ops-warden can route the request to secrets-engine and report readiness. - Bootstrap credentials are documented, bounded, and scheduled for removal.