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
|
||||
|
||||
> 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
|
||||
|
||||
secrets-engine is the workflow and automation interface for approved secret
|
||||
custody, auth-capability handoff, delivery, and lifecycle work across build,
|
||||
test, and production, with OpenBao as the enforcement backend.
|
||||
secrets-engine is a decision-gated Python CLI that validates non-secret secret
|
||||
lane metadata and orchestrates narrowly scoped OpenBao policy, AppRole,
|
||||
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
|
||||
connects cataloged secret lanes, scoped auth-capability lanes, approval
|
||||
decisions, stage-specific OpenBao roles, safe delivery modes, and non-secret
|
||||
evidence.
|
||||
## Implemented Capabilities
|
||||
|
||||
## In Scope
|
||||
### Catalog and validation
|
||||
|
||||
- Non-secret catalog of secret lanes, grants, consumers, stages, and delivery
|
||||
modes.
|
||||
- Non-secret catalog of scoped OpenBao auth capabilities where the protected
|
||||
material is a narrow policy/AppRole grant rather than a KV value.
|
||||
- Decision-aware planning and apply flows for OpenBao policies, auth roles, and
|
||||
metadata.
|
||||
- Build, test, and production privilege separation.
|
||||
- Safe provisioning, verification, rotation, revocation, and deactivation
|
||||
workflows.
|
||||
- Exec-time delivery to operators, agents, CI jobs, workloads, and ops-bridge
|
||||
tasks without printing raw values.
|
||||
- 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.
|
||||
- Loads YAML catalog entries for `kv` and `auth-capability` lanes.
|
||||
- Models `build`, `test`, and `prod` stages, exact mounts/paths/fields,
|
||||
consumers, approvals, delivery modes, verification, lifecycle ownership,
|
||||
workload-delivery metadata, and `standard`/`high` risk.
|
||||
- Distinguishes engine-managed and existing KV mounts, and engine-managed,
|
||||
existing, or absent native delivery auth.
|
||||
- Rejects malformed entries, inline secret-looking values, wildcard paths,
|
||||
unsupported modes, bootstrap-only approval for high-risk lanes, and high-risk
|
||||
entries without rotation/deactivation owners.
|
||||
- Records existing ESO/Kubernetes/OIDC workload delivery as metadata only; it
|
||||
does not operate those delivery systems.
|
||||
|
||||
## Out of Scope
|
||||
### Decision-gated planning and OpenBao metadata apply
|
||||
|
||||
- Replacing OpenBao as custody, policy, lease, or audit backend.
|
||||
- Replacing flex-auth authorization decisions.
|
||||
- Replacing user-engine/key-cape identity and claim lifecycle.
|
||||
- Issuing SSH certificates, which remains ops-warden responsibility.
|
||||
- Owning tunnels or remote transport, which remains ops-bridge responsibility.
|
||||
- Storing raw secret values in this repo, State Hub, chat, prompts, or logs.
|
||||
- Broad platform-root or platform-admin automation as a steady-state model.
|
||||
- Handing broad OpenBao tokens to another subsystem when a narrower
|
||||
cataloged capability can satisfy the request.
|
||||
- Resolves a catalog lane by catalog id or `approval.decision_ref`.
|
||||
- Resolves an approval from State Hub by id, with tracked local YAML mirrors as
|
||||
a pilot/offline fallback.
|
||||
- Fails privileged live commands closed when a required decision is missing,
|
||||
unapproved, or superseded. Plans and `apply --dry-run` remain non-mutating.
|
||||
- Renders guarded OpenBao plans for exact consumer ACL policies and AppRoles.
|
||||
- Applies policy and AppRole metadata idempotently. Existing mounts render a
|
||||
non-mutating check and are never created by apply.
|
||||
- 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
|
||||
without platform-root hand-typing.
|
||||
- A workload or operator command needs a secret delivered **into the command**
|
||||
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.
|
||||
- Imports one declared field from a mode-0600 file outside Git worktrees.
|
||||
- Generates random values only for non-production lanes.
|
||||
- Keeps values out of CLI output and evidence records.
|
||||
|
||||
## 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`).
|
||||
- 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).
|
||||
### Verification
|
||||
|
||||
## 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
|
||||
flow: catalog → decision check → guarded OpenBao policy/AppRole apply →
|
||||
provision or handoff → positive/negative verification → safe delivery →
|
||||
non-secret route pointers → revoke.
|
||||
These are bounded policy/presence probes. They do not yet prove denial for a
|
||||
real unrelated workload identity, validate every field by default, exercise a
|
||||
provider operation, or produce OpenBao audit-request correlation.
|
||||
|
||||
The repo supports both stored-value KV lanes and non-KV auth-capability lanes.
|
||||
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.
|
||||
### Exec-time delivery
|
||||
|
||||
Current operational status lives in workplans, `.custodian-brief.md`, and
|
||||
`history/`; this file should stay stable enough for agents and contributors to
|
||||
use as the boundary reference.
|
||||
- `exec-env` fetches one declared field through the lane AppRole and injects it
|
||||
into a child process environment.
|
||||
- `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
|
||||
removing bootstrap shortcuts. The hardening path is tracked in
|
||||
`docs/hardening-backlog.md` and includes:
|
||||
### Auth-capability handoff
|
||||
|
||||
- replacing bootstrap token files with OIDC, service auth, or another scoped
|
||||
OpenBao auth path for steady-state stage roles;
|
||||
- using response wrapping, short leases, and single-use handoff paths when
|
||||
exec-time delivery does not fit;
|
||||
- requiring dual control for production value provisioning beyond approved
|
||||
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.
|
||||
- Models narrow non-KV AppRole grants such as exact `ssh/sign/<role>` update
|
||||
capability.
|
||||
- Mints `role_id`/`secret_id` material only after approval and writes it to
|
||||
distinct mode-0600 files outside Git worktrees without printing the
|
||||
`secret_id`.
|
||||
|
||||
## 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
|
||||
sits between approval/identity systems and the OpenBao backend:
|
||||
### Routing and evidence
|
||||
|
||||
- **OpenBao / railiance-platform** — enforces custody, policy, lease, audit.
|
||||
secrets-engine drives it through least-privilege stage roles and validated
|
||||
paths, never as root.
|
||||
- **flex-auth / State Hub decisions** — authorize. secrets-engine requires and
|
||||
verifies a decision before privileged action and writes non-secret evidence
|
||||
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.
|
||||
- `route` returns a non-secret pointer containing lane ownership, decision
|
||||
status, metadata/value-presence booleans, readiness, and a safe next command.
|
||||
- Records scrubbed local JSONL evidence and posts a minimal State Hub progress
|
||||
event on a best-effort basis.
|
||||
- Keeps OpenBao audit logs as the backend source of truth.
|
||||
|
||||
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 |
|
||||
| --- | --- |
|
||||
| **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 |
|
||||
- For `auth-capability` lanes, live `revoke` deletes the AppRole and policy.
|
||||
- For KV lanes, live `revoke` deletes all KV metadata/versions at the path.
|
||||
|
||||
## 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.
|
||||
- **OpenBao (railiance-platform)** — the custody/policy/lease/audit backend.
|
||||
- **flex-auth** — authorization decisions secrets-engine depends on.
|
||||
- **user-engine / key-cape** — identity and claim lifecycle for consumers.
|
||||
- **ops-bridge** — remote transport; may consume scoped delivery.
|
||||
- **net-kingdom** — owns the cross-system security-infrastructure boundary doc.
|
||||
- **info-tech-canon** — canonical terminology source.
|
||||
## CLI Surface
|
||||
|
||||
```text
|
||||
secrets-engine catalog list|show
|
||||
secrets-engine decision inspect
|
||||
secrets-engine plan
|
||||
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
|
||||
|
||||
```capability
|
||||
type: security
|
||||
title: Decision-aware OpenBao policy/role apply
|
||||
description: Turns an approved State Hub decision into a narrow, guarded OpenBao apply —
|
||||
catalog lane to dry-run plan to idempotent ACL policy + AppRole write — through
|
||||
least-privilege build/test/prod stage roles. Refuses unapproved, superseded, wildcard,
|
||||
out-of-stage, or broad-admin plans before any backend call. Writes non-secret evidence.
|
||||
keywords: [secrets, openbao, vault, policy, approle, catalog, decision, stage, least-privilege, netkingdom]
|
||||
title: Guarded OpenBao lane planning and metadata apply
|
||||
description: Validates cataloged KV and auth-capability lanes, renders exact policy/AppRole plans,
|
||||
and applies approved metadata while rejecting missing decisions, stage mismatches, wildcards,
|
||||
broad-admin names, and forbidden capability paths. Existing mounts are check-only.
|
||||
keywords: [secrets, openbao, policy, approle, catalog, decision, stage, least-privilege]
|
||||
```
|
||||
|
||||
```capability
|
||||
type: security
|
||||
title: Exec-time secret delivery
|
||||
description: Delivers a secret into a child process only — never printing, exporting, or
|
||||
persisting the value. npm-config injects a temporary mode-0600 .npmrc pointing at the
|
||||
configured registry; exec-env injects a scoped env var. Temp config is cleaned up on
|
||||
success, failure, and interruption; child output is redacted as a backstop.
|
||||
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]
|
||||
title: AppRole-scoped exec delivery
|
||||
description: Fetches one declared KV field through a lane AppRole and injects it into a child
|
||||
process using exec-env or a temporary npm config, with output redaction and cleanup. This is
|
||||
CLI-local delivery; exec-file, wrapping, service delivery, and explicit token revocation are absent.
|
||||
keywords: [secrets, delivery, exec, npm, injection, redaction, openbao]
|
||||
```
|
||||
|
||||
```capability
|
||||
type: security
|
||||
title: Scoped OpenBao auth-capability handoff
|
||||
description: Models non-KV grants such as warden-sign as guarded policy/AppRole lanes.
|
||||
Plans refuse wildcards, sys/auth/token/identity paths, root-like capabilities, and
|
||||
non-update SSH signing paths; handoff emits only file paths and non-secret metadata
|
||||
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]
|
||||
description: Generates an exact-path policy/AppRole plan and writes role-id/secret-id material to
|
||||
strict out-of-repo files after approval. Operational use remains subject to lane-specific governance.
|
||||
keywords: [openbao, approle, auth-capability, handoff, least-privilege]
|
||||
```
|
||||
|
||||
```capability
|
||||
type: security
|
||||
title: Lifecycle and non-secret evidence
|
||||
description: Tracks secret and capability lifecycle actions as explicit, reversible
|
||||
workflow steps: provision, verify, deliver, rotate, revoke, deactivate, and audit.
|
||||
OpenBao keeps custody and audit; secrets-engine records only non-secret decisions,
|
||||
paths, policy names, actors, timestamps, and verification outcomes.
|
||||
keywords: [secrets, lifecycle, rotation, revocation, deactivation, audit, evidence, openbao, state-hub]
|
||||
type: governance
|
||||
title: Non-secret routing and evidence pointers
|
||||
description: Reports decision/readiness metadata and records scrubbed local and best-effort State Hub
|
||||
evidence without returning secret values. It is not a durable audit store or complete multi-field attestation.
|
||||
keywords: [routing, evidence, state-hub, audit, secrets]
|
||||
```
|
||||
|
|
|
|||
|
|
@ -9,12 +9,14 @@
|
|||
| Kind | ID | Status | Lane | Source |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| 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-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-0005 | finished | — | workplans/SECRETS-WP-0005-scope-intent-value-gaps.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-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-T02 | 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