docs: align scope with implemented capabilities
Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a0217e-8c4c-7383-be6b-f50a6e485306
This commit is contained in:
parent
3ca0e63bed
commit
7799716c73
4 changed files with 454 additions and 159 deletions
355
SCOPE.md
355
SCOPE.md
|
|
@ -1,207 +1,244 @@
|
||||||
# SCOPE
|
# SCOPE
|
||||||
|
|
||||||
> Lightweight boundary for agents and contributors.
|
> Implemented capability boundary for agents and contributors. Aspirational
|
||||||
|
> direction belongs in `INTENT.md`; current work and operational gates belong in
|
||||||
|
> `workplans/`.
|
||||||
|
|
||||||
## One-liner
|
## One-liner
|
||||||
|
|
||||||
secrets-engine is the workflow and automation interface for approved secret
|
secrets-engine is a decision-gated Python CLI that validates non-secret secret
|
||||||
custody, auth-capability handoff, delivery, and lifecycle work across build,
|
lane metadata and orchestrates narrowly scoped OpenBao policy, AppRole,
|
||||||
test, and production, with OpenBao as the enforcement backend.
|
provisioning, verification, delivery, routing, handoff, and revocation actions.
|
||||||
|
|
||||||
## Core Idea
|
It is an OpenBao workflow client, not a vault, authorization service, identity
|
||||||
|
provider, credential broker, or general secrets API.
|
||||||
|
|
||||||
OpenBao is the vault. secrets-engine is the day-to-day interaction layer that
|
## Implemented Capabilities
|
||||||
connects cataloged secret lanes, scoped auth-capability lanes, approval
|
|
||||||
decisions, stage-specific OpenBao roles, safe delivery modes, and non-secret
|
|
||||||
evidence.
|
|
||||||
|
|
||||||
## In Scope
|
### Catalog and validation
|
||||||
|
|
||||||
- Non-secret catalog of secret lanes, grants, consumers, stages, and delivery
|
- Loads YAML catalog entries for `kv` and `auth-capability` lanes.
|
||||||
modes.
|
- Models `build`, `test`, and `prod` stages, exact mounts/paths/fields,
|
||||||
- Non-secret catalog of scoped OpenBao auth capabilities where the protected
|
consumers, approvals, delivery modes, verification, lifecycle ownership,
|
||||||
material is a narrow policy/AppRole grant rather than a KV value.
|
workload-delivery metadata, and `standard`/`high` risk.
|
||||||
- Decision-aware planning and apply flows for OpenBao policies, auth roles, and
|
- Distinguishes engine-managed and existing KV mounts, and engine-managed,
|
||||||
metadata.
|
existing, or absent native delivery auth.
|
||||||
- Build, test, and production privilege separation.
|
- Rejects malformed entries, inline secret-looking values, wildcard paths,
|
||||||
- Safe provisioning, verification, rotation, revocation, and deactivation
|
unsupported modes, bootstrap-only approval for high-risk lanes, and high-risk
|
||||||
workflows.
|
entries without rotation/deactivation owners.
|
||||||
- Exec-time delivery to operators, agents, CI jobs, workloads, and ops-bridge
|
- Records existing ESO/Kubernetes/OIDC workload delivery as metadata only; it
|
||||||
tasks without printing raw values.
|
does not operate those delivery systems.
|
||||||
- Future service/API mode that exposes the same approved planning, delivery,
|
|
||||||
handoff, lifecycle, and evidence semantics to ops-warden, agents, CI,
|
|
||||||
workloads, and UI surfaces without exposing OpenBao internals.
|
|
||||||
- ops-warden routing contract for non-SSH credentials and scoped OpenBao
|
|
||||||
capabilities.
|
|
||||||
- State Hub non-secret evidence and progress integration.
|
|
||||||
- Canonicalization of terms with info-tech-canon.
|
|
||||||
|
|
||||||
## Out of Scope
|
### Decision-gated planning and OpenBao metadata apply
|
||||||
|
|
||||||
- Replacing OpenBao as custody, policy, lease, or audit backend.
|
- Resolves a catalog lane by catalog id or `approval.decision_ref`.
|
||||||
- Replacing flex-auth authorization decisions.
|
- Resolves an approval from State Hub by id, with tracked local YAML mirrors as
|
||||||
- Replacing user-engine/key-cape identity and claim lifecycle.
|
a pilot/offline fallback.
|
||||||
- Issuing SSH certificates, which remains ops-warden responsibility.
|
- Fails privileged live commands closed when a required decision is missing,
|
||||||
- Owning tunnels or remote transport, which remains ops-bridge responsibility.
|
unapproved, or superseded. Plans and `apply --dry-run` remain non-mutating.
|
||||||
- Storing raw secret values in this repo, State Hub, chat, prompts, or logs.
|
- Renders guarded OpenBao plans for exact consumer ACL policies and AppRoles.
|
||||||
- Broad platform-root or platform-admin automation as a steady-state model.
|
- Applies policy and AppRole metadata idempotently. Existing mounts render a
|
||||||
- Handing broad OpenBao tokens to another subsystem when a narrower
|
non-mutating check and are never created by apply.
|
||||||
cataloged capability can satisfy the request.
|
- Rejects stage mismatches, wildcard paths, broad-admin names, forbidden
|
||||||
|
`sys/`, token, identity, root, or sudo semantics, and auth-capability paths
|
||||||
|
outside an exact allowlist.
|
||||||
|
|
||||||
## Relevant When
|
### KV provisioning
|
||||||
|
|
||||||
- An approved decision needs to become a narrow OpenBao policy/auth-role apply
|
- Imports one declared field from a mode-0600 file outside Git worktrees.
|
||||||
without platform-root hand-typing.
|
- Generates random values only for non-production lanes.
|
||||||
- A workload or operator command needs a secret delivered **into the command**
|
- Keeps values out of CLI output and evidence records.
|
||||||
without printing or exporting it (e.g. `npm publish`).
|
|
||||||
- A non-SSH credential need (API key, provider token, npm token, DB password,
|
|
||||||
scoped OpenBao token) is routed here by ops-warden.
|
|
||||||
- ops-warden needs an approved, narrow OpenBao capability such as
|
|
||||||
`ssh/sign/<role>` access for its own SSH certificate flow, without receiving a
|
|
||||||
broad platform-root token.
|
|
||||||
- Build/test/production need different privilege, ceremony, and delivery rules
|
|
||||||
for the same kind of secret.
|
|
||||||
- A reviewer needs non-secret evidence of who applied/provisioned/verified what.
|
|
||||||
|
|
||||||
## Not Relevant When
|
This is a bootstrap/pilot primitive, not a safe general updater for existing
|
||||||
|
multi-field production paths. The current adapter invokes `bao kv put` with one
|
||||||
|
field and can replace sibling fields at that KV path; it also places the value
|
||||||
|
in the local `bao` subprocess argument vector. Do not use it for the admitted
|
||||||
|
shared multi-field lanes until merge-safe, non-argv provisioning is implemented.
|
||||||
|
|
||||||
- You need an **SSH certificate** (→ ops-warden `warden sign`).
|
### Verification
|
||||||
- You need an **authorization decision** (→ flex-auth).
|
|
||||||
- You need **identity / OIDC / MFA / claim lifecycle** (→ user-engine / key-cape).
|
|
||||||
- You need a **tunnel** or remote transport (→ ops-bridge).
|
|
||||||
- You want OpenBao itself replaced as the custody/lease/audit backend (it is not).
|
|
||||||
- You want a raw secret value moved through Git, State Hub, chat, prompts, or logs
|
|
||||||
(never — delivery is exec-time or out-of-band only).
|
|
||||||
|
|
||||||
## Current State
|
- KV positive verification logs in through the lane AppRole and reports whether
|
||||||
|
one declared field is present, without printing the field value.
|
||||||
|
- KV negative verification checks that a fixed invalid token cannot read the
|
||||||
|
path.
|
||||||
|
- Auth-capability verification checks the AppRole token's capabilities on exact
|
||||||
|
allowlisted and denial-probe paths.
|
||||||
|
|
||||||
MVP delivered. The Python CLI (`src/secrets_engine/`) supports the core lane
|
These are bounded policy/presence probes. They do not yet prove denial for a
|
||||||
flow: catalog → decision check → guarded OpenBao policy/AppRole apply →
|
real unrelated workload identity, validate every field by default, exercise a
|
||||||
provision or handoff → positive/negative verification → safe delivery →
|
provider operation, or produce OpenBao audit-request correlation.
|
||||||
non-secret route pointers → revoke.
|
|
||||||
|
|
||||||
The repo supports both stored-value KV lanes and non-KV auth-capability lanes.
|
### Exec-time delivery
|
||||||
KV lanes cover secrets such as npm publish tokens; auth-capability lanes cover
|
|
||||||
narrow OpenBao policy/AppRole grants such as `ssh/sign/<role>` access for
|
|
||||||
ops-warden. The maturity-gated publication-scope policy is in place and
|
|
||||||
fail-safe: until the broader domain reaches the required maturity, publish lanes
|
|
||||||
clamp to the safest repo-scoped token shape.
|
|
||||||
|
|
||||||
Current operational status lives in workplans, `.custodian-brief.md`, and
|
- `exec-env` fetches one declared field through the lane AppRole and injects it
|
||||||
`history/`; this file should stay stable enough for agents and contributors to
|
into a child process environment.
|
||||||
use as the boundary reference.
|
- `npm-config` creates a temporary mode-0600 npm config containing an environment
|
||||||
|
reference rather than the token, injects the value only into the child, and
|
||||||
|
deletes the config afterward.
|
||||||
|
- Child stdout and stderr are combined and streamed through token-pattern and
|
||||||
|
exact-value redaction.
|
||||||
|
- Undeclared fields and undeclared/unsupported exec modes are rejected before
|
||||||
|
value fetch.
|
||||||
|
|
||||||
## Hardening Trajectory
|
The OpenBao KV response is parsed in the parent process, so every field stored
|
||||||
|
at the path crosses that process boundary even though only the selected field is
|
||||||
|
injected. Scoped AppRole tokens rely on configured TTL/use limits; exec and
|
||||||
|
verification do not explicitly revoke them after use.
|
||||||
|
|
||||||
The steady-state target is to keep routine secure work low-friction while
|
### Auth-capability handoff
|
||||||
removing bootstrap shortcuts. The hardening path is tracked in
|
|
||||||
`docs/hardening-backlog.md` and includes:
|
|
||||||
|
|
||||||
- replacing bootstrap token files with OIDC, service auth, or another scoped
|
- Models narrow non-KV AppRole grants such as exact `ssh/sign/<role>` update
|
||||||
OpenBao auth path for steady-state stage roles;
|
capability.
|
||||||
- using response wrapping, short leases, and single-use handoff paths when
|
- Mints `role_id`/`secret_id` material only after approval and writes it to
|
||||||
exec-time delivery does not fit;
|
distinct mode-0600 files outside Git worktrees without printing the
|
||||||
- requiring dual control for production value provisioning beyond approved
|
`secret_id`.
|
||||||
pilots;
|
|
||||||
- making rotation, revocation, and deactivation routine evidenced operations;
|
|
||||||
- exposing stabilized CLI semantics through service/API mode only after the
|
|
||||||
underlying decision, delivery, lifecycle, and evidence contracts are proven.
|
|
||||||
|
|
||||||
## How It Fits
|
The cataloged standalone `warden-sign` AppRole is currently parked by governance
|
||||||
|
and must not be applied as a break-glass or recovery path. OpenBao being sealed
|
||||||
|
cannot be recovered through that AppRole.
|
||||||
|
|
||||||
secrets-engine is the **interaction layer** in the NetKingdom security stack. It
|
### Routing and evidence
|
||||||
sits between approval/identity systems and the OpenBao backend:
|
|
||||||
|
|
||||||
- **OpenBao / railiance-platform** — enforces custody, policy, lease, audit.
|
- `route` returns a non-secret pointer containing lane ownership, decision
|
||||||
secrets-engine drives it through least-privilege stage roles and validated
|
status, metadata/value-presence booleans, readiness, and a safe next command.
|
||||||
paths, never as root.
|
- Records scrubbed local JSONL evidence and posts a minimal State Hub progress
|
||||||
- **flex-auth / State Hub decisions** — authorize. secrets-engine requires and
|
event on a best-effort basis.
|
||||||
verifies a decision before privileged action and writes non-secret evidence
|
- Keeps OpenBao audit logs as the backend source of truth.
|
||||||
back.
|
|
||||||
- **user-engine / key-cape** — own identity and claims that bind consumers.
|
|
||||||
- **ops-warden** — routes non-SSH credential needs here (conduit-not-broker) and
|
|
||||||
issues SSH certs itself; secrets-engine orchestrates OpenBao-backed issuance,
|
|
||||||
delivery, handoff, verification, and revocation while OpenBao remains the
|
|
||||||
custody backend.
|
|
||||||
- **ops-bridge** — may consume scoped delivery for remote execution but stores no
|
|
||||||
secret material.
|
|
||||||
- **info-tech-canon** — source of canonical terminology and stage/policy concepts.
|
|
||||||
|
|
||||||
Canonical cross-system boundary: `net-kingdom/docs/secrets-engine-security-infrastructure-boundary.md`.
|
Route readiness checks only the first declared KV field, and State Hub evidence
|
||||||
|
delivery is not durable or transactional. Treat route output as operational
|
||||||
|
guidance, not complete attestation for multi-field or high-risk lanes.
|
||||||
|
|
||||||
## Terminology
|
### Revocation currently available
|
||||||
|
|
||||||
| Term | Meaning |
|
- For `auth-capability` lanes, live `revoke` deletes the AppRole and policy.
|
||||||
| --- | --- |
|
- For KV lanes, live `revoke` deletes all KV metadata/versions at the path.
|
||||||
| **lane / catalog id** | a non-secret entry describing a KV secret or auth capability, its OpenBao location, consumers, delivery, and approval |
|
|
||||||
| **auth-capability lane** | a catalog lane whose protected material is a narrow OpenBao policy/AppRole capability, not a stored KV value |
|
|
||||||
| **stage** | `build` / `test` / `prod` — separate OpenBao privilege contexts |
|
|
||||||
| **stage role** | `secrets-engine-{build,test,prod}` OpenBao role, confined to its prefix |
|
|
||||||
| **delivery mode** | how material leaves OpenBao: `exec-env`, `npm-config`, `read-check`, `wrapped`, `approle-login` |
|
|
||||||
| **org / repo** | Gitea organisation (`coulomb`) / repository (`whynot-design`) — explicit, not the overloaded "project" |
|
|
||||||
| **npm scope** | the `@`-prefixed npm name (`@whynot`) — distinct from org and repo |
|
|
||||||
| **maturity** | `maturity-build/test/prod` package tag; feeds the publication-scope policy |
|
|
||||||
| **bootstrap token** | temporary mode-0600 OpenBao token used during setup, revocable, outside repos |
|
|
||||||
| **service/API mode** | future stable API surface over proven CLI semantics for approved plans, deliveries, handoffs, lifecycle actions, and evidence |
|
|
||||||
|
|
||||||
## Related / Overlapping
|
KV revoke is destructive decommissioning, not soft deactivation: it currently
|
||||||
|
leaves the KV lane's consumer AppRole and policy in place. There is no general
|
||||||
|
lease/accessor revoke, rotation command, compromised state, or reversible lane
|
||||||
|
state machine.
|
||||||
|
|
||||||
- **ops-warden** — front door / SSH cert issuer; routes non-SSH needs here.
|
## CLI Surface
|
||||||
- **OpenBao (railiance-platform)** — the custody/policy/lease/audit backend.
|
|
||||||
- **flex-auth** — authorization decisions secrets-engine depends on.
|
```text
|
||||||
- **user-engine / key-cape** — identity and claim lifecycle for consumers.
|
secrets-engine catalog list|show
|
||||||
- **ops-bridge** — remote transport; may consume scoped delivery.
|
secrets-engine decision inspect
|
||||||
- **net-kingdom** — owns the cross-system security-infrastructure boundary doc.
|
secrets-engine plan
|
||||||
- **info-tech-canon** — canonical terminology source.
|
secrets-engine apply [--dry-run]
|
||||||
|
secrets-engine provision
|
||||||
|
secrets-engine verify
|
||||||
|
secrets-engine handoff
|
||||||
|
secrets-engine exec
|
||||||
|
secrets-engine policy publication
|
||||||
|
secrets-engine route
|
||||||
|
secrets-engine revoke [--dry-run]
|
||||||
|
```
|
||||||
|
|
||||||
|
The implemented exec adapters are `exec-env` and `npm-config`. `read-check` is
|
||||||
|
verification, `approle-login` is auth-capability handoff metadata, and
|
||||||
|
`exec-file`/`wrapped` are reserved schema names without executable adapters.
|
||||||
|
|
||||||
|
## Proven Operationally
|
||||||
|
|
||||||
|
- The whynot-design npm pilot completed a real publish through native
|
||||||
|
`secrets-engine exec` without placing the token in the parent shell.
|
||||||
|
- Throwaway OpenBao integration tests exercise plan, apply, provisioning,
|
||||||
|
positive/negative verification, exec delivery, routing, revocation, and
|
||||||
|
idempotent metadata apply.
|
||||||
|
- Five existing high-risk `platform` mount lanes have reviewed catalog metadata
|
||||||
|
and guarded dry-run plans. Their native AppRoles are not live: workplan
|
||||||
|
`SECRETS-WP-0006` waits on per-lane approval, production authority, live
|
||||||
|
positive/negative verification, and routing cutover.
|
||||||
|
|
||||||
|
## Not Implemented
|
||||||
|
|
||||||
|
- A service API, daemon, UI, queue, scheduler, or remote multi-user service.
|
||||||
|
- OpenBao OIDC/service-auth login for steady-state secrets-engine operation.
|
||||||
|
- Native `exec-file` or response-wrapped delivery.
|
||||||
|
- Merge-safe multi-field KV updates or provider-side rotation.
|
||||||
|
- First-class rotate, compromise, suspend, reactivate, lease-status, or audit
|
||||||
|
report commands.
|
||||||
|
- Dual-control enforcement beyond accepting the catalog label.
|
||||||
|
- Direct flex-auth evaluation, claim validation, or identity authentication.
|
||||||
|
- Runtime tenancy isolation; `org`, `repo`, consumers, and stages are catalog
|
||||||
|
metadata plus local path/policy guards, not a tenant control plane.
|
||||||
|
- Management or health verification of ESO, Kubernetes Secrets, deployments,
|
||||||
|
provider accounts, SSH issuance, tunnels, or remote transport.
|
||||||
|
- Any backend other than the local `bao`/`vault` CLI speaking to OpenBao.
|
||||||
|
|
||||||
|
## System Boundary
|
||||||
|
|
||||||
|
- **OpenBao / railiance-platform** owns custody, policy enforcement, leases, and
|
||||||
|
audit. secrets-engine invokes it through supplied credentials.
|
||||||
|
- **flex-auth / State Hub decisions** own authorization. secrets-engine only
|
||||||
|
resolves and enforces recorded decision status.
|
||||||
|
- **user-engine / key-cape** own identity, OIDC, MFA, and claims.
|
||||||
|
- **ops-warden** issues SSH certificates and routes non-SSH credential needs; it
|
||||||
|
does not vend their values.
|
||||||
|
- **ops-bridge** owns tunnels and remote execution transport and may consume a
|
||||||
|
scoped delivery path.
|
||||||
|
- **workload/platform repositories** own ESO/Kubernetes delivery, provider
|
||||||
|
rotation, and application health.
|
||||||
|
- **info-tech-canon / net-kingdom** own canonical terminology and the
|
||||||
|
cross-system security boundary.
|
||||||
|
|
||||||
|
Canonical boundary:
|
||||||
|
`net-kingdom/docs/secrets-engine-security-infrastructure-boundary.md`.
|
||||||
|
|
||||||
|
## Security Rules
|
||||||
|
|
||||||
|
- Never place raw secret values in Git, State Hub, chat, prompts, workplans,
|
||||||
|
normal logs, or evidence.
|
||||||
|
- Never treat catalog admission, a dry-run, or an old workload CCR as approval
|
||||||
|
for a new production auth surface.
|
||||||
|
- Never mutate an existing shared mount or replace workload delivery by
|
||||||
|
implication.
|
||||||
|
- Never use current single-field provisioning on a shared multi-field path.
|
||||||
|
- Never call KV `revoke` unless destructive deletion of all path versions is the
|
||||||
|
explicitly approved intent.
|
||||||
|
- Keep bootstrap and handoff material outside repositories with mode 0600 and
|
||||||
|
explicit expiry/revocation handling.
|
||||||
|
|
||||||
|
## Where Current Work Lives
|
||||||
|
|
||||||
|
- `workplans/` is the source of truth for open work and operational gates.
|
||||||
|
- `docs/hardening-backlog.md` tracks exit from bootstrap mode.
|
||||||
|
- `history/` contains dated capability and intent assessments.
|
||||||
|
- `INTENT.md` remains the stable aspirational direction.
|
||||||
|
|
||||||
## Provided Capabilities
|
## Provided Capabilities
|
||||||
|
|
||||||
```capability
|
```capability
|
||||||
type: security
|
type: security
|
||||||
title: Decision-aware OpenBao policy/role apply
|
title: Guarded OpenBao lane planning and metadata apply
|
||||||
description: Turns an approved State Hub decision into a narrow, guarded OpenBao apply —
|
description: Validates cataloged KV and auth-capability lanes, renders exact policy/AppRole plans,
|
||||||
catalog lane to dry-run plan to idempotent ACL policy + AppRole write — through
|
and applies approved metadata while rejecting missing decisions, stage mismatches, wildcards,
|
||||||
least-privilege build/test/prod stage roles. Refuses unapproved, superseded, wildcard,
|
broad-admin names, and forbidden capability paths. Existing mounts are check-only.
|
||||||
out-of-stage, or broad-admin plans before any backend call. Writes non-secret evidence.
|
keywords: [secrets, openbao, policy, approle, catalog, decision, stage, least-privilege]
|
||||||
keywords: [secrets, openbao, vault, policy, approle, catalog, decision, stage, least-privilege, netkingdom]
|
|
||||||
```
|
```
|
||||||
|
|
||||||
```capability
|
```capability
|
||||||
type: security
|
type: security
|
||||||
title: Exec-time secret delivery
|
title: AppRole-scoped exec delivery
|
||||||
description: Delivers a secret into a child process only — never printing, exporting, or
|
description: Fetches one declared KV field through a lane AppRole and injects it into a child
|
||||||
persisting the value. npm-config injects a temporary mode-0600 .npmrc pointing at the
|
process using exec-env or a temporary npm config, with output redaction and cleanup. This is
|
||||||
configured registry; exec-env injects a scoped env var. Temp config is cleaned up on
|
CLI-local delivery; exec-file, wrapping, service delivery, and explicit token revocation are absent.
|
||||||
success, failure, and interruption; child output is redacted as a backstop.
|
keywords: [secrets, delivery, exec, npm, injection, redaction, openbao]
|
||||||
keywords: [secrets, delivery, exec, npm, publish, token, injection, redaction, npmrc, openbao]
|
|
||||||
```
|
|
||||||
|
|
||||||
```capability
|
|
||||||
type: governance
|
|
||||||
title: Maturity-gated publication-scope policy
|
|
||||||
description: Binds npm publication scope to package maturity (build to gitea-wide, test to
|
|
||||||
org-wide, prod to repo-scoped) and gates the graduated table behind the netkingdom domain
|
|
||||||
reaching production grade. While dormant, every lane clamps to the safest repo-scope —
|
|
||||||
fail-safe, never fail-open. The injected token env-var name signals the effective blast radius.
|
|
||||||
keywords: [policy, maturity, publication-scope, governance, least-privilege, npm, gitea, netkingdom]
|
|
||||||
```
|
```
|
||||||
|
|
||||||
```capability
|
```capability
|
||||||
type: security
|
type: security
|
||||||
title: Scoped OpenBao auth-capability handoff
|
title: Scoped OpenBao auth-capability handoff
|
||||||
description: Models non-KV grants such as warden-sign as guarded policy/AppRole lanes.
|
description: Generates an exact-path policy/AppRole plan and writes role-id/secret-id material to
|
||||||
Plans refuse wildcards, sys/auth/token/identity paths, root-like capabilities, and
|
strict out-of-repo files after approval. Operational use remains subject to lane-specific governance.
|
||||||
non-update SSH signing paths; handoff emits only file paths and non-secret metadata
|
keywords: [openbao, approle, auth-capability, handoff, least-privilege]
|
||||||
while keeping role-id and secret-id material outside Git and normal logs.
|
|
||||||
keywords: [secrets, openbao, approle, auth-capability, warden-sign, ssh-signing, handoff, least-privilege]
|
|
||||||
```
|
```
|
||||||
|
|
||||||
```capability
|
```capability
|
||||||
type: security
|
type: governance
|
||||||
title: Lifecycle and non-secret evidence
|
title: Non-secret routing and evidence pointers
|
||||||
description: Tracks secret and capability lifecycle actions as explicit, reversible
|
description: Reports decision/readiness metadata and records scrubbed local and best-effort State Hub
|
||||||
workflow steps: provision, verify, deliver, rotate, revoke, deactivate, and audit.
|
evidence without returning secret values. It is not a durable audit store or complete multi-field attestation.
|
||||||
OpenBao keeps custody and audit; secrets-engine records only non-secret decisions,
|
keywords: [routing, evidence, state-hub, audit, secrets]
|
||||||
paths, policy names, actors, timestamps, and verification outcomes.
|
|
||||||
keywords: [secrets, lifecycle, rotation, revocation, deactivation, audit, evidence, openbao, state-hub]
|
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -9,12 +9,14 @@
|
||||||
| Kind | ID | Status | Lane | Source |
|
| Kind | ID | Status | Lane | Source |
|
||||||
| --- | --- | --- | --- | --- |
|
| --- | --- | --- | --- | --- |
|
||||||
| workplan | ADHOC-2026-08-21 | finished | — | workplans/ADHOC-2026-08-21.md |
|
| workplan | ADHOC-2026-08-21 | finished | — | workplans/ADHOC-2026-08-21.md |
|
||||||
|
| workplan | ADHOC-2026-08-23 | finished | — | workplans/ADHOC-2026-08-23.md |
|
||||||
| workplan | SECRETS-WP-0001 | finished | — | workplans/SECRETS-WP-0001-statehub-bootstrap.md |
|
| workplan | SECRETS-WP-0001 | finished | — | workplans/SECRETS-WP-0001-statehub-bootstrap.md |
|
||||||
| workplan | SECRETS-WP-0002 | finished | — | workplans/SECRETS-WP-0002-bootstrap.md |
|
| workplan | SECRETS-WP-0002 | finished | — | workplans/SECRETS-WP-0002-bootstrap.md |
|
||||||
| workplan | SECRETS-WP-0004 | finished | — | workplans/SECRETS-WP-0004-warden-sign-token-lane.md |
|
| workplan | SECRETS-WP-0004 | finished | — | workplans/SECRETS-WP-0004-warden-sign-token-lane.md |
|
||||||
| workplan | SECRETS-WP-0005 | finished | — | workplans/SECRETS-WP-0005-scope-intent-value-gaps.md |
|
| workplan | SECRETS-WP-0005 | finished | — | workplans/SECRETS-WP-0005-scope-intent-value-gaps.md |
|
||||||
| workplan | SECRETS-WP-0006 | active | — | workplans/SECRETS-WP-0006-catalog-lane-adoption.md |
|
| workplan | SECRETS-WP-0006 | active | — | workplans/SECRETS-WP-0006-catalog-lane-adoption.md |
|
||||||
| task | ADHOC-2026-08-21-T01 | done | — | workplans/ADHOC-2026-08-21.md |
|
| task | ADHOC-2026-08-21-T01 | done | — | workplans/ADHOC-2026-08-21.md |
|
||||||
|
| task | ADHOC-2026-08-23-T01 | done | — | workplans/ADHOC-2026-08-23.md |
|
||||||
| task | SECRETS-WP-0001-T01 | done | — | workplans/SECRETS-WP-0001-statehub-bootstrap.md |
|
| task | SECRETS-WP-0001-T01 | done | — | workplans/SECRETS-WP-0001-statehub-bootstrap.md |
|
||||||
| task | SECRETS-WP-0001-T02 | done | — | workplans/SECRETS-WP-0001-statehub-bootstrap.md |
|
| task | SECRETS-WP-0001-T02 | done | — | workplans/SECRETS-WP-0001-statehub-bootstrap.md |
|
||||||
| task | SECRETS-WP-0001-T03 | done | — | workplans/SECRETS-WP-0001-statehub-bootstrap.md |
|
| task | SECRETS-WP-0001-T03 | done | — | workplans/SECRETS-WP-0001-statehub-bootstrap.md |
|
||||||
|
|
|
||||||
217
history/2026-08-23-scope-intent-capability-gap-assessment.md
Normal file
217
history/2026-08-23-scope-intent-capability-gap-assessment.md
Normal file
|
|
@ -0,0 +1,217 @@
|
||||||
|
# Scope and Intent Capability Gap Assessment
|
||||||
|
|
||||||
|
Date: 2026-08-23
|
||||||
|
Author: codex
|
||||||
|
Compared: `SCOPE.md` against `INTENT.md` and the current implementation
|
||||||
|
|
||||||
|
## Executive assessment
|
||||||
|
|
||||||
|
The repository has a credible, tested CLI MVP, but it is not yet the complete
|
||||||
|
secure interaction and automation layer described by `INTENT.md`.
|
||||||
|
|
||||||
|
The strongest implemented slice is:
|
||||||
|
|
||||||
|
```text
|
||||||
|
catalog -> approval-status check -> guarded plan -> policy/AppRole apply
|
||||||
|
-> bounded presence/capability verification -> CLI-local exec/handoff
|
||||||
|
-> non-secret route/evidence pointer
|
||||||
|
```
|
||||||
|
|
||||||
|
The weakest slice is lifecycle safety beyond that pilot chain. Rotation is
|
||||||
|
metadata only, KV provisioning is not merge-safe for multi-field paths, KV
|
||||||
|
revoke is destructive and incomplete, approval integration is still a pilot
|
||||||
|
resolver rather than a production authorization contract, and service mode does
|
||||||
|
not exist.
|
||||||
|
|
||||||
|
The intent remains directionally sound. The gap is maturity, not a need to move
|
||||||
|
the system boundary: OpenBao should remain the backend; flex-auth/State Hub
|
||||||
|
should authorize; key-cape/user-engine should own identity; ops-warden should
|
||||||
|
route; and secrets-engine should remain the guarded workflow layer.
|
||||||
|
|
||||||
|
## Open-work assessment
|
||||||
|
|
||||||
|
The only active repository workplan is `SECRETS-WP-0006`:
|
||||||
|
|
||||||
|
- T05 waits on explicit per-lane approval and scoped production OpenBao apply
|
||||||
|
authority for five reviewed existing production lanes.
|
||||||
|
- T06 waits on successful native verification before ops-warden proxy retirement.
|
||||||
|
|
||||||
|
No approval or production authority was available during this assessment. The
|
||||||
|
latest ops-warden message also parks the standalone `warden-sign` AppRole for
|
||||||
|
break-glass use and explicitly requests no credential action. There was no safe,
|
||||||
|
actionable live task, so documentation reconciliation was the appropriate work.
|
||||||
|
|
||||||
|
## Intent scorecard
|
||||||
|
|
||||||
|
| Intent area | Assessment | Current evidence | Material gap |
|
||||||
|
| --- | --- | --- | --- |
|
||||||
|
| Decision first | Partial | Privileged CLI handlers require a resolved status and reject missing, unapproved, or superseded decisions. | Resolution accepts tracked local fixtures, checks only coarse status, has no freshness/purpose/actor semantics, and does not enforce actual dual control. The five new CCR strings do not resolve through the State Hub UUID endpoint. |
|
||||||
|
| OpenBao enforces; engine orchestrates | Substantially aligned | Backend operations are isolated in `openbao.py`; catalog, plan, guards, delivery, routing, and evidence are separate modules. | Only the local `bao`/`vault` subprocess adapter exists. Some safety depends on local validation rather than backend-bound per-request authorization. |
|
||||||
|
| Stage-aware privilege | Partial | Stage names, stage mismatch rejection, build/test prefixes, static stage policies, and consumer policy/AppRole naming exist. | Production has no local owner-prefix invariant (`STAGE_PREFIX["prod"]` is empty). Static bootstrap stage policies and supplied credentials remain wider and longer-lived than per-action identity. |
|
||||||
|
| No values in coordination surfaces | Partial, with a concrete implementation risk | Catalog validation rejects secret-looking inline values; evidence is scrubbed; CLI output avoids values; exec output is redacted. | `kv_put` passes the raw value in the local `bao` subprocess argument vector. Exec/verification parse the complete KV path response in process memory. These do not put values in Git/State Hub, but they fall short of the strongest custody boundary in the intent. |
|
||||||
|
| Least friction without broad power | Partial | Human-readable dry-runs, one-command exec, route pointers, and exact consumer policies reduce hand-written OpenBao work. | Routine production still needs manual decision and credential bridging. There is no OIDC/service login, service API, or durable request orchestration. |
|
||||||
|
| Bootstrap honestly, then harden | Partial | Bootstrap files are mode checked, rejected inside Git worktrees, documented, and tracked in the hardening backlog. | Bootstrap mode is still part of the live CLI; one historical cleanup/revocation record remains incomplete; tracked local approval mirrors remain usable for production commands. |
|
||||||
|
| Prefer exec-time delivery | Partial | `exec-env` and `npm-config` are implemented, including temporary npm config cleanup and child-output redaction. | `exec-file` and `wrapped` are schema-only. Scoped login tokens are not explicitly revoked after exec/verify, and child delivery is local CLI execution only. |
|
||||||
|
| Auditable and reversible | Weak/partial | Scrubbed JSONL evidence and best-effort State Hub progress events exist; OpenBao remains the audit source. | Many failure paths produce no evidence, State Hub posting silently drops failures, actors are not cryptographically bound, no audit-report command exists, and KV revoke is destructive rather than reversible. |
|
||||||
|
| Typed multi-application catalog | Substantially aligned as metadata | Multiple KV lanes, an auth-capability lane, explicit org/repo/stage/consumer/field data, existing-mount semantics, and high-risk ownership checks are implemented. | This is not runtime multi-tenancy. Consumer claims are descriptive and are not authenticated or authorized by this process. |
|
||||||
|
| CLI and service API | CLI achieved; API absent | The documented CLI surface exists and the pilot flow has integration coverage. | No daemon, API, queue, scheduler, UI, remote protocol, or concurrency model exists. |
|
||||||
|
| Lifecycle: establish/access/rotate/deactivate | Establish/access partial; lifecycle incomplete | Apply, provision, verify, exec, handoff, and two forms of revoke exist. | No rotate command, compromise/suspend state, provider rotation, lease/accessor lifecycle, rollback orchestration, or safe soft deactivation exists. |
|
||||||
|
|
||||||
|
## Highest-priority gaps
|
||||||
|
|
||||||
|
### P0 — Provisioning is unsafe for shared multi-field paths
|
||||||
|
|
||||||
|
`provision_from_file` reads one declared field and calls `OpenBaoClient.kv_put`.
|
||||||
|
That adapter invokes:
|
||||||
|
|
||||||
|
```text
|
||||||
|
bao kv put <mount>/<path> <field>=<value>
|
||||||
|
```
|
||||||
|
|
||||||
|
Two consequences matter:
|
||||||
|
|
||||||
|
1. `kv put` replaces the data at a KV v2 path rather than merging sibling
|
||||||
|
fields. Updating one field can remove the others.
|
||||||
|
2. The raw value is present in the local subprocess argument vector while the
|
||||||
|
command runs.
|
||||||
|
|
||||||
|
This is acceptable only as a constrained pilot/bootstrap primitive on a
|
||||||
|
single-field or disposable path. It must not be used on the newly admitted
|
||||||
|
issue-core, reuse-surface, Forgejo, or email paths. A production design needs a
|
||||||
|
merge-safe update mechanism that does not expose values through argv, plus
|
||||||
|
tests proving sibling preservation and failure cleanup.
|
||||||
|
|
||||||
|
### P0 — KV revoke is destructive, incomplete, and inconsistent with dry-run
|
||||||
|
|
||||||
|
For a KV lane, live `revoke` deletes all KV metadata/versions but leaves the
|
||||||
|
consumer AppRole and ACL policy. The dry-run text says it would delete both KV
|
||||||
|
metadata and the AppRole, which the live path does not do.
|
||||||
|
|
||||||
|
This does not meet the intent's reversible lifecycle principle. The command
|
||||||
|
needs explicit operations with different approvals, for example:
|
||||||
|
|
||||||
|
- suspend delivery by deleting/disabling AppRole credentials;
|
||||||
|
- deactivate consumer policy/auth;
|
||||||
|
- revoke leases/tokens by accessor;
|
||||||
|
- delete current value versions;
|
||||||
|
- irreversibly destroy KV metadata only under an explicit destruction action.
|
||||||
|
|
||||||
|
Until then, KV revoke should be treated as destructive path deletion, not a
|
||||||
|
general revocation or deactivation workflow.
|
||||||
|
|
||||||
|
### P0 — Production approval is not yet a complete authorization contract
|
||||||
|
|
||||||
|
The resolver accepts `resolved`, `approved`, or `accepted` status and absence of
|
||||||
|
`superseded_by`. It does not validate action type, lane/stage binding, actor,
|
||||||
|
expiry, allowed fields, operation, approval count, or flex-auth result.
|
||||||
|
`dual-control` is a catalog label but is not enforced as two approvals.
|
||||||
|
|
||||||
|
Tracked local decision mirrors are useful for demos and historical pilots but
|
||||||
|
are too permissive as a steady-state production authority source. Production
|
||||||
|
should require a canonical decision object bound to the exact action and should
|
||||||
|
fail closed when State Hub/flex-auth cannot prove that binding.
|
||||||
|
|
||||||
|
## Important hardening gaps
|
||||||
|
|
||||||
|
### P1 — Steady-state authentication is absent
|
||||||
|
|
||||||
|
The CLI accepts a token from an environment variable or a mode-0600 bootstrap
|
||||||
|
file. It does not perform OpenBao OIDC, workload/service auth, short-lived
|
||||||
|
issuer exchange, or per-action identity binding. This keeps routine production
|
||||||
|
work dependent on attended external credential bridging.
|
||||||
|
|
||||||
|
### P1 — Verification is narrower than the intent
|
||||||
|
|
||||||
|
KV positive verification checks one field, defaulting to the first. Route
|
||||||
|
readiness also checks only the first field, so a multi-field lane can appear
|
||||||
|
ready while sibling fields are missing. KV negative verification uses a fixed
|
||||||
|
garbage token, not a real unrelated workload identity. Provider behavior and
|
||||||
|
application health are outside the check.
|
||||||
|
|
||||||
|
High-risk lane acceptance should verify every declared field, use a real
|
||||||
|
unrelated identity or capabilities proof, capture OpenBao audit request ids,
|
||||||
|
and, where appropriate, call a value-safe provider/application smoke.
|
||||||
|
|
||||||
|
### P1 — Delivery token lifecycle is implicit
|
||||||
|
|
||||||
|
Exec and verification create AppRole Secret IDs and login tokens. Secret ID
|
||||||
|
use counts and token TTL/use bounds limit them, but the code does not revoke the
|
||||||
|
issued token explicitly on success, child failure, interruption, or verification
|
||||||
|
failure. Evidence does not include a safe lease/accessor lifecycle.
|
||||||
|
|
||||||
|
### P1 — Evidence is informative, not a durable audit workflow
|
||||||
|
|
||||||
|
Local JSONL is append-only by convention, not tamper-evident. State Hub posting
|
||||||
|
is best-effort and silently ignored on error. Apply/provision/handoff failures
|
||||||
|
are generally recorded only if a caller adds separate evidence; there is no
|
||||||
|
transaction id joining State Hub evidence to OpenBao audit entries, and no
|
||||||
|
`audit` command summarizes a lane.
|
||||||
|
|
||||||
|
### P1 — Lifecycle metadata is not lifecycle automation
|
||||||
|
|
||||||
|
Catalog entries require rotation/deactivation descriptions and owners, which is
|
||||||
|
valuable governance metadata. The engine does not execute those plans, manage
|
||||||
|
provider credential overlap, coordinate consumers, maintain compromised or
|
||||||
|
deactivated state, or verify rollback.
|
||||||
|
|
||||||
|
## Longer-term product gaps
|
||||||
|
|
||||||
|
### P2 — Service mode
|
||||||
|
|
||||||
|
The intent describes a CLI and service API. Only the CLI exists. A service
|
||||||
|
should wait until approval binding, auth, delivery token lifecycle, evidence,
|
||||||
|
and destructive-operation semantics are hardened; exposing today's CLI directly
|
||||||
|
would amplify its pilot shortcuts.
|
||||||
|
|
||||||
|
### P2 — Runtime tenancy and consumer identity
|
||||||
|
|
||||||
|
The catalog can describe many applications and logical owners, but the engine
|
||||||
|
does not authenticate a tenant, resolve claims, isolate concurrent callers, or
|
||||||
|
enforce per-tenant quotas/policies. The current product is multi-application
|
||||||
|
metadata and path orchestration, not a multi-tenant service.
|
||||||
|
|
||||||
|
### P2 — Backend abstraction
|
||||||
|
|
||||||
|
OpenBao-specific behavior is isolated reasonably well, but there is only one
|
||||||
|
subprocess backend. “OpenBao as the initial enforcement backend” remains an
|
||||||
|
architectural option, not a demonstrated portable backend contract.
|
||||||
|
|
||||||
|
## Current evolution phase
|
||||||
|
|
||||||
|
Against the phases in `INTENT.md`:
|
||||||
|
|
||||||
|
1. **Bootstrap:** implemented and still active.
|
||||||
|
2. **MVP:** achieved for the whynot-design npm pilot.
|
||||||
|
3. **Stage separation:** implemented in catalog/plan/static policy form, but
|
||||||
|
steady-state stage authentication and stronger production owner binding are
|
||||||
|
incomplete.
|
||||||
|
4. **Hardening:** started; existing-mount admission, risk classification,
|
||||||
|
exact-field guards, bounded AppRoles, and fail-closed decisions exist. The P0
|
||||||
|
and P1 gaps above remain.
|
||||||
|
5. **Service mode:** not started.
|
||||||
|
|
||||||
|
## Recommended next sequence
|
||||||
|
|
||||||
|
1. Keep `SECRETS-WP-0006-T05` limited to approved metadata apply and explicit
|
||||||
|
per-field, positive/negative verification. Do not provision or revoke the
|
||||||
|
existing shared paths through the current KV lifecycle commands.
|
||||||
|
2. Fix provisioning transport and merge semantics, with sibling-preservation
|
||||||
|
and process-argument tests.
|
||||||
|
3. Split KV suspend/deactivate/destroy semantics and make dry-run match live
|
||||||
|
behavior.
|
||||||
|
4. Replace coarse/local production decision resolution with an action-bound,
|
||||||
|
expiring, dual-control-capable authorization contract.
|
||||||
|
5. Add steady-state OIDC/service auth and explicit child-token revocation.
|
||||||
|
6. Strengthen multi-field/readiness and unrelated-identity verification, then
|
||||||
|
correlate evidence with OpenBao audit request ids.
|
||||||
|
7. Implement rotation state and wrapped/file delivery before designing service
|
||||||
|
mode.
|
||||||
|
|
||||||
|
## Conclusion
|
||||||
|
|
||||||
|
`INTENT.md` still describes the right destination, but the accurate present
|
||||||
|
tense is a guarded OpenBao CLI MVP with one proven native workload pilot and
|
||||||
|
several reviewed-but-not-live production lane plans. The repository should not
|
||||||
|
yet advertise itself as a service API, complete lifecycle engine, runtime
|
||||||
|
multi-tenant system, wrapped-delivery broker, or production-safe general KV
|
||||||
|
updater.
|
||||||
39
workplans/ADHOC-2026-08-23.md
Normal file
39
workplans/ADHOC-2026-08-23.md
Normal file
|
|
@ -0,0 +1,39 @@
|
||||||
|
---
|
||||||
|
id: ADHOC-2026-08-23
|
||||||
|
type: workplan
|
||||||
|
title: "Implemented scope and intent-gap reconciliation"
|
||||||
|
domain: infotech
|
||||||
|
repo: secrets-engine
|
||||||
|
status: finished
|
||||||
|
owner: codex
|
||||||
|
topic_slug: custodian
|
||||||
|
created: "2026-08-23"
|
||||||
|
updated: "2026-08-23"
|
||||||
|
---
|
||||||
|
|
||||||
|
# ADHOC-2026-08-23 - Implemented scope and intent-gap reconciliation
|
||||||
|
|
||||||
|
## Reconcile implemented capability scope
|
||||||
|
|
||||||
|
```task
|
||||||
|
id: ADHOC-2026-08-23-T01
|
||||||
|
status: done
|
||||||
|
priority: medium
|
||||||
|
```
|
||||||
|
|
||||||
|
Checked the repository workplans and coordination inbox. The only active work,
|
||||||
|
`SECRETS-WP-0006-T05/T06`, remains waiting on external production approval and
|
||||||
|
authority; the current ops-warden message requested no credential action.
|
||||||
|
|
||||||
|
Rewrote `SCOPE.md` as an implemented capability boundary rather than an
|
||||||
|
aspirational/current-work ledger, and recorded a dated assessment against
|
||||||
|
`INTENT.md` in
|
||||||
|
`history/2026-08-23-scope-intent-capability-gap-assessment.md`. The assessment
|
||||||
|
documents the achieved CLI MVP and the concrete approval, provisioning,
|
||||||
|
revocation, verification, auth, evidence, lifecycle, tenancy, and service-mode
|
||||||
|
gaps without exposing secret material.
|
||||||
|
|
||||||
|
`statehub fix-consistency` was attempted twice and interrupted after repeated
|
||||||
|
60-second stalls in State Hub HTTP calls (`GET /topics/<id>` and
|
||||||
|
`PATCH /repos/secrets-engine`). The progress event was recorded successfully,
|
||||||
|
but registrar/index consistency remains pending on State Hub availability.
|
||||||
Loading…
Add table
Add a link
Reference in a new issue