302 lines
12 KiB
Markdown
302 lines
12 KiB
Markdown
|
|
# Product Requirements Document: secrets-engine
|
||
|
|
|
||
|
|
## Summary
|
||
|
|
|
||
|
|
secrets-engine provides the operational interface for approved secret lifecycle
|
||
|
|
work across build, test, and production. It wraps OpenBao with a catalog,
|
||
|
|
decision checks, stage-aware privilege boundaries, safe delivery modes, and
|
||
|
|
non-secret audit evidence.
|
||
|
|
|
||
|
|
The first implementation should focus on getting one real pilot lane working end
|
||
|
|
to end: the whynot-design npm publish token. The design must also be general
|
||
|
|
enough to support API keys, provider tokens, database passwords, CI credentials,
|
||
|
|
and other workload secrets later.
|
||
|
|
|
||
|
|
## Related Documents
|
||
|
|
|
||
|
|
- [NetKingdom security infrastructure boundary pointer](docs/netkingdom-security-infrastructure.md)
|
||
|
|
points to the canonical document in `net-kingdom/docs/` and defines the
|
||
|
|
responsibilities and interactions with OpenBao, flex-auth, user-engine,
|
||
|
|
ops-warden, ops-bridge, info-tech-canon, State Hub, and agents.
|
||
|
|
|
||
|
|
## Background
|
||
|
|
|
||
|
|
The current platform can define OpenBao paths, policies, and credential-change
|
||
|
|
requests, but the live path still requires too much manual OpenBao UI/CLI work.
|
||
|
|
This creates a trap: the secure process exists on paper, but daily work still
|
||
|
|
falls back to handovers, broad platform-root access, and interface-specific
|
||
|
|
mistakes.
|
||
|
|
|
||
|
|
secrets-engine is the missing workflow layer. It should let an approved decision
|
||
|
|
become an applied and verified secret lane without asking each operator or agent
|
||
|
|
to understand every OpenBao endpoint, CLI quoting rule, auth role shape, or
|
||
|
|
workload-specific delivery convention.
|
||
|
|
|
||
|
|
## Goals
|
||
|
|
|
||
|
|
- Provide one interaction surface for approved secret establishment, access,
|
||
|
|
rotation, deactivation, and verification.
|
||
|
|
- Separate build, test, and production privileges from the beginning.
|
||
|
|
- Let agents and operators apply approved OpenBao metadata without broad admin
|
||
|
|
access.
|
||
|
|
- Deliver secrets to commands and workloads without printing values.
|
||
|
|
- Produce non-secret evidence suitable for State Hub progress, audits, and
|
||
|
|
troubleshooting.
|
||
|
|
- Give ops-warden a credential routing target that is not responsible for secret
|
||
|
|
custody itself.
|
||
|
|
|
||
|
|
## Non-goals
|
||
|
|
|
||
|
|
- Replacing OpenBao as the canonical vault and audit backend.
|
||
|
|
- Replacing key-cape, user-engine, flex-auth, or State Hub.
|
||
|
|
- Building a full UI before the CLI/API model is clear.
|
||
|
|
- Automating high-risk production secret value provisioning before the approval,
|
||
|
|
wrapped-delivery, and verification model is proven.
|
||
|
|
- Storing raw secret values in Git, workplans, State Hub, chat, prompts, normal
|
||
|
|
logs, or long-lived local files.
|
||
|
|
|
||
|
|
## Primary Users
|
||
|
|
|
||
|
|
| User | Need |
|
||
|
|
| --- | --- |
|
||
|
|
| Platform operator | Apply approved secret changes without hand-typing OpenBao internals. |
|
||
|
|
| Agent such as Codex or ops-warden | Request or use approved credentials through a safe front door. |
|
||
|
|
| Workload maintainer | Get a clear request, review, approval, and consumption path. |
|
||
|
|
| Security reviewer | See decisions, policy boundaries, verification evidence, and revocation state. |
|
||
|
|
| Future service maintainer | Add new secret types and delivery modes without weakening production custody. |
|
||
|
|
|
||
|
|
## Operating Model
|
||
|
|
|
||
|
|
### Stage roles
|
||
|
|
|
||
|
|
secrets-engine should bootstrap at least three OpenBao-facing roles:
|
||
|
|
|
||
|
|
| Role | Intended use | Initial privilege shape |
|
||
|
|
| --- | --- | --- |
|
||
|
|
| secrets-engine-build | Build/dev lanes, generated test values, low-risk experimentation | Can manage approved build-stage metadata and values under build prefixes. |
|
||
|
|
| secrets-engine-test | Test/staging lanes and integration verification | Can manage approved test-stage metadata and values; can perform positive/negative checks. |
|
||
|
|
| secrets-engine-prod | Production metadata apply and tightly controlled delivery | Can apply approved prod metadata and auth roles; raw prod value read/provisioning remains gated and logged. |
|
||
|
|
|
||
|
|
The exact OpenBao policy names can change, but the stage distinction is a
|
||
|
|
product requirement, not an implementation detail.
|
||
|
|
|
||
|
|
### Bootstrap credential files
|
||
|
|
|
||
|
|
Until proper OIDC/service authentication exists, a platform-root operator may
|
||
|
|
create temporary OpenBao credentials for the three roles and place them outside
|
||
|
|
repositories, for example under a local mode-0700 directory. The files must be:
|
||
|
|
|
||
|
|
- mode 0600;
|
||
|
|
- outside Git worktrees;
|
||
|
|
- named by role and environment only, never by secret value;
|
||
|
|
- revocable;
|
||
|
|
- recorded in non-secret bootstrap notes by path and accessor only when safe;
|
||
|
|
- treated as temporary infrastructure setup material.
|
||
|
|
|
||
|
|
Agents may be told the file path, not the token value. The engine should read
|
||
|
|
such files only when explicitly invoked in bootstrap mode.
|
||
|
|
|
||
|
|
## Functional Requirements
|
||
|
|
|
||
|
|
### FR1 - Secret catalog
|
||
|
|
|
||
|
|
The engine must maintain a non-secret catalog of secret lanes and grants.
|
||
|
|
|
||
|
|
Each catalog entry should include:
|
||
|
|
|
||
|
|
- catalog id;
|
||
|
|
- owning domain/repo/workload;
|
||
|
|
- stage: build, test, production, or another explicit stage;
|
||
|
|
- OpenBao mount and path;
|
||
|
|
- fields exposed;
|
||
|
|
- allowed consumers and auth claims;
|
||
|
|
- delivery modes;
|
||
|
|
- approval requirement;
|
||
|
|
- TTL and rotation expectations;
|
||
|
|
- verification requirements;
|
||
|
|
- revocation/deactivation behavior;
|
||
|
|
- audit evidence expectations.
|
||
|
|
|
||
|
|
### FR2 - Decision integration
|
||
|
|
|
||
|
|
Privileged actions must require an approved decision or approved credential
|
||
|
|
change request unless explicitly running in a local bootstrap or dry-run mode.
|
||
|
|
|
||
|
|
The engine must be able to:
|
||
|
|
|
||
|
|
- inspect a request;
|
||
|
|
- render a human-reviewable plan;
|
||
|
|
- link to the decision record when available;
|
||
|
|
- refuse denied, superseded, stale, or unapproved requests;
|
||
|
|
- record non-secret apply and verification evidence.
|
||
|
|
|
||
|
|
### FR3 - OpenBao metadata apply
|
||
|
|
|
||
|
|
The engine must generate and apply OpenBao metadata safely:
|
||
|
|
|
||
|
|
- ACL policies;
|
||
|
|
- auth roles;
|
||
|
|
- token roles where needed;
|
||
|
|
- KV metadata where safe;
|
||
|
|
- path and name restrictions based on catalog and stage;
|
||
|
|
- dry-run output before live mutation.
|
||
|
|
|
||
|
|
Production apply must fail closed if the request is not approved or if the plan
|
||
|
|
contains an out-of-bound policy, role, mount, path, wildcard, or broad admin
|
||
|
|
capability.
|
||
|
|
|
||
|
|
### FR4 - Secret provisioning
|
||
|
|
|
||
|
|
The engine must support secret value provisioning without exposing raw values in
|
||
|
|
coordination channels.
|
||
|
|
|
||
|
|
Initial supported modes:
|
||
|
|
|
||
|
|
- operator-attended OpenBao provisioning;
|
||
|
|
- bootstrap local file import with strict permissions;
|
||
|
|
- response-wrapped handoff where OpenBao supports it;
|
||
|
|
- generated test secrets for non-production only.
|
||
|
|
|
||
|
|
Production raw value automation should remain deliberately constrained until the
|
||
|
|
wrapped or dual-control flow is proven.
|
||
|
|
|
||
|
|
### FR5 - Secret delivery
|
||
|
|
|
||
|
|
The engine must provide delivery modes that avoid printing secret values:
|
||
|
|
|
||
|
|
- exec-time environment injection;
|
||
|
|
- exec-time temp file injection with cleanup;
|
||
|
|
- workload-specific config file generation such as temporary npm config;
|
||
|
|
- response wrapping for handoff flows;
|
||
|
|
- read checks that return boolean/evidence, not the value.
|
||
|
|
|
||
|
|
A representative target command shape:
|
||
|
|
|
||
|
|
```bash
|
||
|
|
secrets-engine exec --catalog whynot-design-npm-publish -- npm publish
|
||
|
|
```
|
||
|
|
|
||
|
|
For npm, the engine should prefer creating a temporary npm config and setting the
|
||
|
|
child process environment to use it, then deleting it after the child exits.
|
||
|
|
|
||
|
|
### FR6 - Verification
|
||
|
|
|
||
|
|
The engine must support positive and negative verification without printing
|
||
|
|
secrets.
|
||
|
|
|
||
|
|
Positive checks prove an approved consumer can access or use the secret. Negative
|
||
|
|
checks prove an unrelated consumer cannot. Evidence should include non-secret
|
||
|
|
metadata such as catalog id, actor, decision id, path, timestamp, and result.
|
||
|
|
|
||
|
|
### FR7 - CLI/API interface
|
||
|
|
|
||
|
|
The MVP must provide a CLI. The command names may evolve, but the first surface
|
||
|
|
should cover:
|
||
|
|
|
||
|
|
```text
|
||
|
|
secrets-engine catalog list
|
||
|
|
secrets-engine catalog show <catalog-id>
|
||
|
|
secrets-engine decision inspect <decision-or-ccr-id>
|
||
|
|
secrets-engine plan <decision-or-ccr-id>
|
||
|
|
secrets-engine apply <decision-or-ccr-id> --stage <build|test|prod>
|
||
|
|
secrets-engine provision <catalog-id> --stage <stage> --from-file <path>
|
||
|
|
secrets-engine verify <catalog-id> --positive
|
||
|
|
secrets-engine verify <catalog-id> --negative
|
||
|
|
secrets-engine exec --catalog <catalog-id> -- <command...>
|
||
|
|
secrets-engine revoke <catalog-id-or-lease>
|
||
|
|
```
|
||
|
|
|
||
|
|
The API should be designed after the CLI semantics are clear.
|
||
|
|
|
||
|
|
### FR8 - Audit and evidence
|
||
|
|
|
||
|
|
The engine must never log raw secret values. It must write non-secret evidence
|
||
|
|
for:
|
||
|
|
|
||
|
|
- decision inspected;
|
||
|
|
- plan rendered;
|
||
|
|
- apply attempted/succeeded/failed;
|
||
|
|
- secret provisioned without value disclosure;
|
||
|
|
- exec delivery attempted/succeeded/failed;
|
||
|
|
- verification positive/negative result;
|
||
|
|
- revoke/deactivate/rotate actions.
|
||
|
|
|
||
|
|
State Hub integration should use non-secret progress entries and decision links.
|
||
|
|
OpenBao audit logs remain the backend source of truth for vault operations.
|
||
|
|
|
||
|
|
### FR9 - ops-warden routing
|
||
|
|
|
||
|
|
ops-warden should route non-SSH credential requests to secrets-engine. It should
|
||
|
|
not own or vend provider tokens, API keys, database passwords, or OpenBao values.
|
||
|
|
|
||
|
|
A route result should tell the caller:
|
||
|
|
|
||
|
|
- the catalog id;
|
||
|
|
- the decision/request status;
|
||
|
|
- whether the secret is ready/resolvable;
|
||
|
|
- the safe command to request or execute with the credential;
|
||
|
|
- what human decision or provisioning step is still missing.
|
||
|
|
|
||
|
|
## Security Requirements
|
||
|
|
|
||
|
|
- Raw secret values must never appear in prompts, chat, Git, workplans, State
|
||
|
|
Hub messages, issue comments, or normal logs.
|
||
|
|
- Production operations must require an approved decision except break-glass
|
||
|
|
flows, which must be explicit and heavily audited.
|
||
|
|
- Stage roles must be unable to mutate paths outside their stage and allowed
|
||
|
|
prefixes.
|
||
|
|
- Production metadata appliers must not gain broad sys, auth, identity, root, or
|
||
|
|
platform-admin semantics.
|
||
|
|
- Bootstrap token files must be temporary, revocable, mode 0600, and outside
|
||
|
|
repositories.
|
||
|
|
- The engine must redact token-like values from child process output where it
|
||
|
|
controls the execution path.
|
||
|
|
- Every role and delivery mode must have a documented revocation path.
|
||
|
|
|
||
|
|
## MVP Scope
|
||
|
|
|
||
|
|
The MVP is complete when it can support the whynot-design npm publish token
|
||
|
|
pilot with this chain:
|
||
|
|
|
||
|
|
1. Catalog entry exists for whynot-design npm publish.
|
||
|
|
2. Approved decision/CCR is inspected.
|
||
|
|
3. OpenBao ACL policy and auth role are applied through a stage-appropriate
|
||
|
|
secrets-engine role or bootstrap credential.
|
||
|
|
4. The token value is provisioned without being printed or logged.
|
||
|
|
5. Positive and negative verification pass.
|
||
|
|
6. A safe command can execute npm publish with the token injected only into the
|
||
|
|
child process.
|
||
|
|
7. ops-warden can report the catalog entry as ready/resolvable.
|
||
|
|
|
||
|
|
## Success Metrics
|
||
|
|
|
||
|
|
- Approved secret lanes can be applied without platform-root hand typing.
|
||
|
|
- A typical approved non-production credential can be established in minutes.
|
||
|
|
- Production metadata apply succeeds without granting raw secret read authority.
|
||
|
|
- No secret values are found in repo history, State Hub payloads, logs, or chat.
|
||
|
|
- Operators can understand a generated plan without knowing OpenBao endpoint
|
||
|
|
quirks.
|
||
|
|
- At least one real workload consumes a credential through secrets-engine exec.
|
||
|
|
|
||
|
|
## Risks
|
||
|
|
|
||
|
|
| Risk | Mitigation |
|
||
|
|
| --- | --- |
|
||
|
|
| Wrapper accidentally becomes broad platform-admin by another name | Stage roles, path allowlists, decision checks, negative tests. |
|
||
|
|
| Temporary bootstrap files become permanent | Track bootstrap mode, add revocation tasks, replace with OIDC/service auth. |
|
||
|
|
| Agents exfiltrate secrets through logs or prompts | Prefer exec-time delivery, redaction, no raw read default. |
|
||
|
|
| Product scope grows into identity/authorization | Keep key-cape/user-engine and flex-auth boundaries explicit. |
|
||
|
|
| OpenBao-specific assumptions leak everywhere | Keep a catalog and interface model; isolate backend adapter code. |
|
||
|
|
|
||
|
|
## Open Questions
|
||
|
|
|
||
|
|
- Should the first repo expose only a CLI, or also a tiny local service API?
|
||
|
|
- What is the canonical State Hub decision object for secret establishment,
|
||
|
|
rotation, and deactivation?
|
||
|
|
- Which stage names are final: build, test, prod, or build, staging,
|
||
|
|
production?
|
||
|
|
- Should production value provisioning require two-person review immediately or
|
||
|
|
only after the pilot?
|
||
|
|
- Which identity claim should bind the whynot-design consumer long term: group,
|
||
|
|
workload service account, repository identity, or a combination?
|