Document scope alignment and warden-sign readiness
This commit is contained in:
parent
d8aadaffe3
commit
ae685f3a0a
10 changed files with 736 additions and 41 deletions
19
.decisions/SECRETS-WP-0004.yaml
Normal file
19
.decisions/SECRETS-WP-0004.yaml
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
# Offline approval mirror for the canonical State Hub decision
|
||||
# 4589dcb7-c0df-4073-9a0b-4f80a0fcdb93 (SECRETS-WP-0004).
|
||||
#
|
||||
# Build-mode short-circuit: the operator (Bernd) authorized the warden-sign prod
|
||||
# apply and the canonical hub decision is recorded; this mirror lets
|
||||
# `secrets-engine apply warden-sign --stage prod` resolve the lane's decision_ref
|
||||
# (SECRETS-WP-0004) without waiting. The hub decision is the audit record; resolve
|
||||
# it formally with "Approved:". NON-SECRET: contains no token value.
|
||||
id: SECRETS-WP-0004
|
||||
title: "warden-sign auth-capability lane — prod apply (FLEX-WP-0007 T4)"
|
||||
status: resolved
|
||||
superseded_by: null
|
||||
decided_by: "human"
|
||||
review_url: "http://127.0.0.1:8000/decisions/4589dcb7-c0df-4073-9a0b-4f80a0fcdb93"
|
||||
rationale: >-
|
||||
APPROVE: establish the warden-sign OpenBao policy + AppRole granting update on
|
||||
ssh/sign/{agt,adm,atm}-role only, for the FLEX-WP-0007 T4 production policy-gate
|
||||
smoke. Tightly scoped (denial probes confirm no token-create/sudo/root/admin).
|
||||
No secret value exposed or stored. Operator-authorized in build mode.
|
||||
31
INTENT.md
31
INTENT.md
|
|
@ -7,8 +7,9 @@
|
|||
## One-liner
|
||||
|
||||
**secrets-engine is the secure interaction and automation layer for approved
|
||||
secret custody, delivery, and lifecycle work across build, test, and production,
|
||||
with OpenBao as the initial enforcement backend.**
|
||||
secret custody, scoped OpenBao capability handoff, delivery, and lifecycle work
|
||||
across build, test, and production, with OpenBao as the initial enforcement
|
||||
backend.**
|
||||
|
||||
## Why This Exists
|
||||
|
||||
|
|
@ -26,8 +27,8 @@ already produced avoidable friction:
|
|||
- build, test, and production need different levels of privilege and ceremony;
|
||||
- secret values must never move through chat, Git, prompts, State Hub messages,
|
||||
or workplans;
|
||||
- ops-warden needs a reliable front door for credential use, not direct secret
|
||||
custody responsibility.
|
||||
- ops-warden needs a reliable front door for credential and scoped capability
|
||||
use, not direct secret custody responsibility.
|
||||
|
||||
This repository exists to capture that complexity once, behind a stable and
|
||||
auditable interface.
|
||||
|
|
@ -36,10 +37,11 @@ auditable interface.
|
|||
|
||||
To provide a decision-aware secrets workflow that can:
|
||||
|
||||
- translate approved requests into narrowly scoped OpenBao changes;
|
||||
- translate approved requests into narrowly scoped OpenBao changes or capability
|
||||
grants;
|
||||
- operate with distinct build, test, and production privilege layers;
|
||||
- deliver secrets to commands and workloads without printing or storing raw
|
||||
values in coordination systems;
|
||||
- deliver secrets and scoped capabilities to commands and workloads without
|
||||
printing or storing raw values in coordination systems;
|
||||
- record enough non-secret evidence for review, audit, and troubleshooting;
|
||||
- make routine secure work fast enough that operators and agents actually use
|
||||
the secure path.
|
||||
|
|
@ -55,7 +57,8 @@ not silently create new secret authority.
|
|||
### 2. OpenBao Enforces, secrets-engine Orchestrates
|
||||
|
||||
OpenBao remains the vault, policy, lease, and audit backend. secrets-engine owns
|
||||
the workflow, catalog, validation, delivery, and operator/agent interface.
|
||||
the workflow, catalog, validation, delivery, scoped capability handoff, and
|
||||
operator/agent interface.
|
||||
|
||||
### 3. Stage-aware Privilege
|
||||
|
||||
|
|
@ -97,11 +100,13 @@ has non-secret evidence that can be reviewed later.
|
|||
|
||||
secrets-engine is:
|
||||
|
||||
- a workflow layer for approved secret changes and access;
|
||||
- a workflow layer for approved secret changes, scoped capability grants, and
|
||||
access;
|
||||
- a CLI and service API for operators, agents, and automation;
|
||||
- a typed catalog of secret lanes, grants, delivery modes, and stage policies;
|
||||
- a typed catalog of KV secret lanes, auth-capability lanes, grants, delivery
|
||||
modes, and stage policies;
|
||||
- an OpenBao policy/auth-role applier with strict local validation;
|
||||
- an exec-time secret delivery helper;
|
||||
- an exec-time secret delivery and scoped capability handoff helper;
|
||||
- an audit evidence writer for State Hub and local logs;
|
||||
- the credential interaction surface that ops-warden can route to.
|
||||
|
||||
|
|
@ -124,8 +129,8 @@ secrets-engine is not:
|
|||
| Secret custody, leases, audit backend | OpenBao / railiance-platform | Use through least-privilege roles and validated paths. |
|
||||
| Human and service identity | key-cape / user-engine | Consume identity claims; do not replace identity lifecycle. |
|
||||
| Authorization decisions | flex-auth / State Hub decision model | Require and verify decisions before privileged actions. |
|
||||
| SSH certificate issuance | ops-warden | Provide routed credential access; do not make ops-warden vend secrets. |
|
||||
| Workload secret consumption | Workload repos / CI / runtime | Provide safe delivery contracts and catalog entries. |
|
||||
| SSH certificate issuance | ops-warden | Provide routed credential/capability access; do not make ops-warden vend secrets. |
|
||||
| Workload secret consumption | Workload repos / CI / runtime | Provide safe delivery and handoff contracts plus catalog entries. |
|
||||
| Request history and progress | State Hub | Write non-secret evidence and decision links only. |
|
||||
|
||||
## Direction of Evolution
|
||||
|
|
|
|||
68
SCOPE.md
68
SCOPE.md
|
|
@ -28,6 +28,9 @@ evidence.
|
|||
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.
|
||||
|
|
@ -72,31 +75,37 @@ evidence.
|
|||
|
||||
## Current State
|
||||
|
||||
MVP delivered. The Python CLI (`src/secrets_engine/`) proves the
|
||||
`whynot-design-npm-publish` KV lane end to end — catalog → decision check →
|
||||
policy/AppRole apply → provision → positive/negative verify → exec-time npm
|
||||
delivery → ops-warden routing pointer → revoke — verified live against OpenBao
|
||||
(`scripts/demo-e2e.sh`, `scripts/npm-publish-demo.sh`). The netkingdom
|
||||
maturity-gated publication-scope policy is in place but dormant (netkingdom at
|
||||
`maturity-build`), so lanes clamp to repo-scope / `NPM_AUTH_TOKEN`.
|
||||
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.
|
||||
|
||||
The current source also supports non-KV auth-capability lanes. `SECRETS-WP-0004`
|
||||
adds the `warden-sign` catalog lane, exact-path policy guards for
|
||||
`ssh/sign/{agt-role,adm-role,atm-role}`, AppRole TTL/use constraints, positive
|
||||
and negative capability probes, and a handoff command that writes `role_id` and
|
||||
`secret_id` only to mode-0600 files outside Git worktrees. Live apply and
|
||||
cross-repo smoke remain pending OpenBao/operator gates.
|
||||
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.
|
||||
|
||||
`SECRETS-WP-0003` has been optimized for the real whynot-design pilot closeout:
|
||||
the catalog points at the canonical approved State Hub decision, the old
|
||||
slug-named offline decision mirror has been retired, and a non-secret preflight
|
||||
plus closeout runbook document the remaining real publish steps. The suite is
|
||||
currently green at 59 passed, 2 skipped.
|
||||
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.
|
||||
|
||||
Bootstrap workplans `SECRETS-WP-0001` (State Hub integration) and
|
||||
`SECRETS-WP-0002` (MVP) are finished. Active: `SECRETS-WP-0003` (real pilot
|
||||
close-out) and `SECRETS-WP-0004` (scoped `warden-sign` auth-capability lane for
|
||||
ops-warden / FLEX-WP-0007 T4).
|
||||
## Hardening Trajectory
|
||||
|
||||
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:
|
||||
|
||||
- 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.
|
||||
|
||||
## How It Fits
|
||||
|
||||
|
|
@ -111,7 +120,9 @@ sits between approval/identity systems and the OpenBao backend:
|
|||
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 mints and custodies the tokens.
|
||||
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.
|
||||
|
|
@ -131,6 +142,7 @@ Canonical cross-system boundary: `net-kingdom/docs/secrets-engine-security-infra
|
|||
| **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
|
||||
|
||||
|
|
@ -183,3 +195,13 @@ description: Models non-KV grants such as warden-sign as guarded policy/AppRole
|
|||
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
|
||||
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]
|
||||
```
|
||||
|
|
|
|||
|
|
@ -53,6 +53,22 @@ auth_capability:
|
|||
token_num_uses: 0
|
||||
secret_id_ttl: 30m
|
||||
secret_id_num_uses: 1
|
||||
oidc:
|
||||
auth_mount: netkingdom
|
||||
role_name: warden-sign
|
||||
role_path: auth/netkingdom/role/warden-sign
|
||||
login_command: bao login -method=oidc -path=netkingdom role=warden-sign
|
||||
policies: [warden-sign]
|
||||
ttl: 15m
|
||||
user_claim: sub
|
||||
groups_claim: groups
|
||||
bound_claims:
|
||||
groups: [net-kingdom-admins]
|
||||
oidc_scopes: [openid, profile, email, groups]
|
||||
allowed_redirect_uris:
|
||||
- https://bao.coulomb.social/ui/vault/auth/netkingdom/oidc/callback
|
||||
- http://localhost:8250/oidc/callback
|
||||
- http://127.0.0.1:8250/oidc/callback
|
||||
allowed_paths:
|
||||
- path: ssh/sign/agt-role
|
||||
capabilities: [update]
|
||||
|
|
|
|||
|
|
@ -1,10 +1,11 @@
|
|||
# ops-warden → secrets-engine Routing Contract
|
||||
|
||||
ops-warden issues **SSH certificates only**. Every other credential need (API
|
||||
keys, provider tokens, DB passwords, npm publish tokens, and OpenBao API token
|
||||
lanes) routes to **secrets-engine**, which is OpenBao-backed. ops-warden must
|
||||
never request, hold, cache, or vend a raw secret value. A route result is a
|
||||
**pointer**, not a key.
|
||||
ops-warden issues **SSH certificates only**. Every other credential or scoped
|
||||
capability need (API keys, provider tokens, DB passwords, npm publish tokens,
|
||||
and OpenBao capability lanes) routes to **secrets-engine**. secrets-engine
|
||||
returns non-secret pointers and safe next commands while OpenBao remains the
|
||||
custody, policy, lease, and audit backend. ops-warden must never request, hold,
|
||||
cache, or vend a raw secret value. A route result is a **pointer**, not a key.
|
||||
|
||||
## What ops-warden calls
|
||||
|
||||
|
|
@ -49,6 +50,9 @@ secrets-engine route <catalog-id> --json
|
|||
- **Actionable when not ready.** If a lane is unapproved, unapplied, or
|
||||
unprovisioned, `next_command` + `missing` tell the caller exactly what to do.
|
||||
- **Idempotent / read-only.** `route` performs no mutation.
|
||||
- **Custody stays in OpenBao.** secrets-engine orchestrates approved issuance,
|
||||
delivery, handoff, verification, and revocation paths; it does not make
|
||||
ops-warden a secret store or token broker.
|
||||
|
||||
## whynot-design retry flow
|
||||
|
||||
|
|
|
|||
|
|
@ -16,6 +16,10 @@ only; the operator receives `role_id` and `secret_id` out-of-band.
|
|||
| SSH mount | `ssh` |
|
||||
| Policy | `warden-sign` |
|
||||
| AppRole | `warden-sign` |
|
||||
| OIDC auth mount | `netkingdom` |
|
||||
| OIDC role | `warden-sign` |
|
||||
| OIDC role path | `auth/netkingdom/role/warden-sign` |
|
||||
| OIDC bound group | `net-kingdom-admins` |
|
||||
| Token TTL | `15m` |
|
||||
| Secret ID TTL | `30m` |
|
||||
| Secret ID uses | `1` |
|
||||
|
|
@ -42,6 +46,60 @@ BAO_ADDR=https://bao.coulomb.social \
|
|||
The bootstrap token file must be mode `0600`, revocable, and tracked in
|
||||
[hardening-backlog.md](hardening-backlog.md) H0 until revoked and shredded.
|
||||
|
||||
## OIDC operator login pointer
|
||||
|
||||
For an attended human operator who has `bao` on the workstation, the intended
|
||||
narrow login is:
|
||||
|
||||
```bash
|
||||
bao login -method=oidc -path=netkingdom role=warden-sign
|
||||
```
|
||||
|
||||
That role lives at `auth/netkingdom/role/warden-sign`, is bound through the
|
||||
`groups` claim to `net-kingdom-admins`, and attaches only the `warden-sign`
|
||||
policy. It is not the `platform-admin` role and not the whynot-design KV-read
|
||||
role.
|
||||
|
||||
If the role has not been applied yet, create/update it from an approved OpenBao
|
||||
operator context with this non-secret payload:
|
||||
|
||||
```json
|
||||
{
|
||||
"role_type": "oidc",
|
||||
"allowed_redirect_uris": [
|
||||
"https://bao.coulomb.social/ui/vault/auth/netkingdom/oidc/callback",
|
||||
"http://localhost:8250/oidc/callback",
|
||||
"http://127.0.0.1:8250/oidc/callback"
|
||||
],
|
||||
"oidc_scopes": ["openid", "profile", "email", "groups"],
|
||||
"user_claim": "sub",
|
||||
"groups_claim": "groups",
|
||||
"bound_claims": {
|
||||
"groups": ["net-kingdom-admins"]
|
||||
},
|
||||
"policies": "warden-sign",
|
||||
"ttl": "15m"
|
||||
}
|
||||
```
|
||||
|
||||
Equivalent CLI path:
|
||||
|
||||
```bash
|
||||
bao write auth/netkingdom/role/warden-sign @warden-sign-oidc-role.json
|
||||
```
|
||||
|
||||
After login, verify the token shape without printing the token value:
|
||||
|
||||
```bash
|
||||
bao token capabilities ssh/sign/agt-role
|
||||
bao token capabilities ssh/sign/adm-role
|
||||
bao token capabilities ssh/sign/atm-role
|
||||
bao token capabilities auth/token/create
|
||||
```
|
||||
|
||||
The first three should include `update`; the last one should not grant token
|
||||
creation/admin capability.
|
||||
|
||||
## Handoff
|
||||
|
||||
Mint a fresh single-use AppRole `secret_id` and write both handoff values to
|
||||
|
|
|
|||
152
history/2026-06-29-scope-intent-gap-analysis.md
Normal file
152
history/2026-06-29-scope-intent-gap-analysis.md
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
# SCOPE.md vs INTENT.md Gap Analysis
|
||||
|
||||
Date: 2026-06-29
|
||||
Author: codex
|
||||
|
||||
## Executive Summary
|
||||
|
||||
`SCOPE.md` is now broadly aligned with `INTENT.md`. The core boundary is
|
||||
consistent: OpenBao enforces custody/policy/lease/audit; secrets-engine owns the
|
||||
workflow, catalog, validation, delivery surface, and non-secret evidence; flex-auth
|
||||
and State Hub decisions authorize; key-cape/user-engine own identity;
|
||||
ops-warden routes credential needs and keeps SSH certificate issuance.
|
||||
|
||||
The most important recent alignment improvement is that `SCOPE.md` now covers
|
||||
auth-capability lanes, which fit the intent principle of low-friction secure work
|
||||
without broad OpenBao power. The remaining gaps are mostly about document role,
|
||||
not contradiction: `INTENT.md` is stable and aspirational, while `SCOPE.md` mixes
|
||||
boundary, current implementation state, workplan status, and capability registry
|
||||
metadata.
|
||||
|
||||
## Alignment
|
||||
|
||||
- Both documents describe secrets-engine as the secure interaction and automation
|
||||
layer for approved secret custody, delivery, and lifecycle work.
|
||||
- Both keep OpenBao as the enforcement backend rather than something this repo
|
||||
replaces.
|
||||
- Both reject raw secret values in Git, State Hub, chat, prompts, workplans, and
|
||||
normal logs.
|
||||
- Both place authorization outside this repo, with secrets-engine requiring and
|
||||
verifying decisions before privileged actions.
|
||||
- Both preserve stage-aware privilege separation across build, test, and
|
||||
production.
|
||||
- Both treat ops-warden as a routing/front-door integration, not a secret-vending
|
||||
subsystem.
|
||||
- Both emphasize low-friction operator/agent workflows bounded by narrow grants,
|
||||
TTLs, delivery rules, and audit evidence.
|
||||
|
||||
## Notable Drift
|
||||
|
||||
### 1. SCOPE.md Is More Current-State Ledger Than Boundary
|
||||
|
||||
`INTENT.md` explicitly says it is aspirational and stable. `SCOPE.md` is intended
|
||||
as a lightweight boundary for agents and contributors, but its `Current State`
|
||||
section now includes detailed workplan status, specific test counts, lane names,
|
||||
and pending operational gates.
|
||||
|
||||
This is useful for agents, but it will age quickly. Test counts, active workplan
|
||||
states, and named pending gates belong more naturally in workplans, history notes,
|
||||
or the generated custodian brief. SCOPE can still summarize current maturity, but
|
||||
it should avoid facts that need frequent operational churn.
|
||||
|
||||
### 2. Service API Direction Is Missing From SCOPE.md
|
||||
|
||||
`INTENT.md` says the repo should evolve into a CLI and service API that
|
||||
ops-warden, agents, CI, and future UI surfaces can use without knowing OpenBao
|
||||
internals. `SCOPE.md` currently emphasizes the CLI, catalog, policies, delivery
|
||||
modes, and capability blocks, but it does not explicitly name service-mode/API
|
||||
as an in-scope future surface.
|
||||
|
||||
This is a real scope gap if future work is expected to add an API. SCOPE should
|
||||
either list the service API as in scope or explicitly defer it to a later
|
||||
workplan while keeping it inside the strategic boundary.
|
||||
|
||||
### 3. Hardening Phase Is Present But Not Mapped
|
||||
|
||||
`INTENT.md` names a hardening path: replace bootstrap token files with OIDC or
|
||||
service auth, wrapped delivery, short leases, dual control for production
|
||||
provisioning, and routine rotation/deactivation workflows.
|
||||
|
||||
`SCOPE.md` includes many of these pieces indirectly, but it does not present the
|
||||
hardening posture as a clear phase or checklist. The result is that an agent can
|
||||
see what is allowed, but not always which remaining hardening moves are expected
|
||||
next.
|
||||
|
||||
### 4. Auth-Capability Lanes Are In Scope But Not In INTENT.md Vocabulary
|
||||
|
||||
`SCOPE.md` now correctly includes auth-capability lanes. `INTENT.md` does not use
|
||||
that term, but the concept is compatible with its principles: least friction
|
||||
without broad power, OpenBao-enforced policy, short-lived credential surfaces,
|
||||
and no raw secret movement through coordination systems.
|
||||
|
||||
This is not a conflict. It is a vocabulary gap. INTENT can remain stable, but a
|
||||
future small amendment could mention that secrets-engine also brokers scoped
|
||||
OpenBao capabilities, not only stored secret values.
|
||||
|
||||
### 5. Ops-Warden Wording Needs Care
|
||||
|
||||
`SCOPE.md` says secrets-engine "mints and custodies the tokens" in the ops-warden
|
||||
relationship note. That is directionally true for OpenBao-backed credential
|
||||
material, but it can be read too broadly. The intent boundary is that ops-warden
|
||||
routes credential use and issues SSH certs, while OpenBao remains the custody
|
||||
backend.
|
||||
|
||||
Safer wording would emphasize that secrets-engine orchestrates OpenBao-backed
|
||||
issuance, delivery, and handoff without owning SSH certificate issuance or storing
|
||||
secret values itself.
|
||||
|
||||
### 6. Lifecycle Surface Is Listed But Underdescribed
|
||||
|
||||
Both documents mention rotation, revocation, deactivation, reversibility, and
|
||||
audit evidence. `SCOPE.md` lists these as in scope and includes revoke in the MVP
|
||||
path, but it does not provide a dedicated capability block or boundary language
|
||||
for routine rotation/deactivation.
|
||||
|
||||
That gap matters because lifecycle work is central to the intent. A future scope
|
||||
update could add a capability block for rotation/revocation/deactivation evidence
|
||||
once the implementation is mature enough.
|
||||
|
||||
## Missing Or Underweighted In SCOPE.md
|
||||
|
||||
- Service API / service mode as a future but in-bound surface.
|
||||
- Dual-control production provisioning expectations.
|
||||
- OIDC/service-auth replacement of bootstrap token files as an explicit hardening
|
||||
target.
|
||||
- Response wrapping and short leases as first-class hardening/delivery concepts,
|
||||
not only implied by delivery-mode terminology.
|
||||
- Routine rotation/deactivation as a durable capability, separate from one-off
|
||||
revoke support.
|
||||
- Clearer distinction between OpenBao custody and secrets-engine orchestration
|
||||
when describing minted tokens or AppRole material.
|
||||
- Stable boundary language separated from volatile implementation status.
|
||||
|
||||
## Missing Or Underweighted In INTENT.md
|
||||
|
||||
- Auth-capability lanes as first-class non-KV grants.
|
||||
- The ops-warden `warden-sign` use case as an example of routing a scoped
|
||||
OpenBao capability without making ops-warden vend secrets.
|
||||
- The maturity-gated publication-scope policy concept.
|
||||
- The catalog distinction between KV secret lanes and capability lanes.
|
||||
|
||||
These are small vocabulary/extensions gaps rather than strategic mismatches.
|
||||
|
||||
## Recommended Follow-Up
|
||||
|
||||
1. Keep `SCOPE.md` as the operational boundary, but trim volatile status details
|
||||
into `history/` or workplans after each milestone.
|
||||
2. Add service API/service mode to `SCOPE.md` as an in-scope future surface if
|
||||
that remains the intended direction.
|
||||
3. Add a short `Hardening Trajectory` section to `SCOPE.md` that mirrors
|
||||
`INTENT.md`: OIDC/service auth, wrapped delivery, short leases, dual control,
|
||||
routine rotation/deactivation.
|
||||
4. Tighten ops-warden wording so it says secrets-engine orchestrates scoped
|
||||
OpenBao issuance/handoff while OpenBao keeps custody and ops-warden keeps SSH
|
||||
cert issuance.
|
||||
5. Consider a small `INTENT.md` update later to name auth-capability lanes as a
|
||||
valid class of approved secret-adjacent work.
|
||||
|
||||
## Assessment
|
||||
|
||||
No major contradiction was found. `SCOPE.md` is implementation-rich and current;
|
||||
`INTENT.md` remains stable and mission-oriented. The gap to manage is keeping
|
||||
SCOPE useful to agents without turning it into a second workplan ledger.
|
||||
137
uv.lock
generated
Normal file
137
uv.lock
generated
Normal file
|
|
@ -0,0 +1,137 @@
|
|||
version = 1
|
||||
requires-python = ">=3.11"
|
||||
|
||||
[[package]]
|
||||
name = "colorama"
|
||||
version = "0.4.6"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "iniconfig"
|
||||
version = "2.3.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "packaging"
|
||||
version = "26.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/d7/f1/e7a6dd94a8d4a5626c03e4e99c87f241ba9e350cd9e6d75123f992427270/packaging-26.2.tar.gz", hash = "sha256:ff452ff5a3e828ce110190feff1178bb1f2ea2281fa2075aadb987c2fb221661", size = 228134 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/df/b2/87e62e8c3e2f4b32e5fe99e0b86d576da1312593b39f47d8ceef365e95ed/packaging-26.2-py3-none-any.whl", hash = "sha256:5fc45236b9446107ff2415ce77c807cee2862cb6fac22b8a73826d0693b0980e", size = 100195 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pluggy"
|
||||
version = "1.6.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pygments"
|
||||
version = "2.20.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pytest"
|
||||
version = "9.1.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
||||
{ name = "iniconfig" },
|
||||
{ name = "packaging" },
|
||||
{ name = "pluggy" },
|
||||
{ name = "pygments" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313", size = 1636369 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c", size = 386536 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pyyaml"
|
||||
version = "6.0.3"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/6d/16/a95b6757765b7b031c9374925bb718d55e0a9ba8a1b6a12d25962ea44347/pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e", size = 185826 },
|
||||
{ url = "https://files.pythonhosted.org/packages/16/19/13de8e4377ed53079ee996e1ab0a9c33ec2faf808a4647b7b4c0d46dd239/pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824", size = 175577 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0c/62/d2eb46264d4b157dae1275b573017abec435397aa59cbcdab6fc978a8af4/pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c", size = 775556 },
|
||||
{ url = "https://files.pythonhosted.org/packages/10/cb/16c3f2cf3266edd25aaa00d6c4350381c8b012ed6f5276675b9eba8d9ff4/pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00", size = 882114 },
|
||||
{ url = "https://files.pythonhosted.org/packages/71/60/917329f640924b18ff085ab889a11c763e0b573da888e8404ff486657602/pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d", size = 806638 },
|
||||
{ url = "https://files.pythonhosted.org/packages/dd/6f/529b0f316a9fd167281a6c3826b5583e6192dba792dd55e3203d3f8e655a/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a", size = 767463 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f2/6a/b627b4e0c1dd03718543519ffb2f1deea4a1e6d42fbab8021936a4d22589/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4", size = 794986 },
|
||||
{ url = "https://files.pythonhosted.org/packages/45/91/47a6e1c42d9ee337c4839208f30d9f09caa9f720ec7582917b264defc875/pyyaml-6.0.3-cp311-cp311-win32.whl", hash = "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b", size = 142543 },
|
||||
{ url = "https://files.pythonhosted.org/packages/da/e3/ea007450a105ae919a72393cb06f122f288ef60bba2dc64b26e2646fa315/pyyaml-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf", size = 158763 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d1/33/422b98d2195232ca1826284a76852ad5a86fe23e31b009c9886b2d0fb8b2/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196", size = 182063 },
|
||||
{ url = "https://files.pythonhosted.org/packages/89/a0/6cf41a19a1f2f3feab0e9c0b74134aa2ce6849093d5517a0c550fe37a648/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0", size = 173973 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ed/23/7a778b6bd0b9a8039df8b1b1d80e2e2ad78aa04171592c8a5c43a56a6af4/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28", size = 775116 },
|
||||
{ url = "https://files.pythonhosted.org/packages/65/30/d7353c338e12baef4ecc1b09e877c1970bd3382789c159b4f89d6a70dc09/pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c", size = 844011 },
|
||||
{ url = "https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc", size = 807870 },
|
||||
{ url = "https://files.pythonhosted.org/packages/05/c0/b3be26a015601b822b97d9149ff8cb5ead58c66f981e04fedf4e762f4bd4/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e", size = 761089 },
|
||||
{ url = "https://files.pythonhosted.org/packages/be/8e/98435a21d1d4b46590d5459a22d88128103f8da4c2d4cb8f14f2a96504e1/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea", size = 790181 },
|
||||
{ url = "https://files.pythonhosted.org/packages/74/93/7baea19427dcfbe1e5a372d81473250b379f04b1bd3c4c5ff825e2327202/pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5", size = 137658 },
|
||||
{ url = "https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b", size = 154003 },
|
||||
{ url = "https://files.pythonhosted.org/packages/1a/08/67bd04656199bbb51dbed1439b7f27601dfb576fb864099c7ef0c3e55531/pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd", size = 140344 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252 },
|
||||
{ url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081 },
|
||||
{ url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159 },
|
||||
{ url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613 },
|
||||
{ url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115 },
|
||||
{ url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427 },
|
||||
{ url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090 },
|
||||
{ url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246 },
|
||||
{ url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814 },
|
||||
{ url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809 },
|
||||
{ url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454 },
|
||||
{ url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355 },
|
||||
{ url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175 },
|
||||
{ url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194 },
|
||||
{ url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108 },
|
||||
{ url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901 },
|
||||
{ url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272 },
|
||||
{ url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "secrets-engine"
|
||||
version = "0.1.0"
|
||||
source = { editable = "." }
|
||||
dependencies = [
|
||||
{ name = "pyyaml" },
|
||||
]
|
||||
|
||||
[package.optional-dependencies]
|
||||
dev = [
|
||||
{ name = "pytest" },
|
||||
]
|
||||
|
||||
[package.metadata]
|
||||
requires-dist = [
|
||||
{ name = "pytest", marker = "extra == 'dev'", specifier = ">=7.4" },
|
||||
{ name = "pyyaml", specifier = ">=6.0" },
|
||||
]
|
||||
|
|
@ -123,6 +123,23 @@ waiting on an approved SECRETS-WP-0004 decision/workplan gate plus a mode-0600
|
|||
production bootstrap token outside any repo. The pending token path/revocation
|
||||
row is recorded in `docs/hardening-backlog.md` H0.
|
||||
|
||||
2026-06-29: Attended ops-warden follow-up message
|
||||
`92de2614-061f-4241-aa13-a3ce72ad41d5`. Production OpenBao is unsealed and the
|
||||
dry-run apply plan is valid for exact `update` grants on `ssh/sign/agt-role`,
|
||||
`ssh/sign/adm-role`, and `ssh/sign/atm-role`. Live apply remains blocked because
|
||||
`secrets-engine route warden-sign --json` reports `decision_status: missing`
|
||||
for `SECRETS-WP-0004`, and the documented lane bootstrap token file
|
||||
`~/.secrets-engine/bootstrap/prod-warden-sign.token` is absent. A broader
|
||||
platform-admin token file exists with mode `600`; it was not used to bypass the
|
||||
missing lane decision or the documented bootstrap handoff.
|
||||
|
||||
2026-06-30: Approval mirror `.decisions/SECRETS-WP-0004.yaml` is now present
|
||||
and `secrets-engine route warden-sign --json` reports `decision_status:
|
||||
resolved` for canonical decision `4589dcb7-c0df-4073-9a0b-4f80a0fcdb93`.
|
||||
Readiness remains false because the OpenBao `warden-sign` policy/AppRole has
|
||||
not been applied (`metadata_applied: false`), and the documented lane bootstrap
|
||||
token file is still absent. Live apply and handoff were not executed.
|
||||
|
||||
Apply the policy + AppRole on `https://bao.coulomb.social` using a mode-0600
|
||||
bootstrap token stored outside any repo. Idempotent re-apply.
|
||||
|
||||
|
|
@ -157,6 +174,18 @@ and attaching only policy `warden-sign`. Replied to ops-warden in State Hub
|
|||
message `0bce1e08-58c2-4db4-b06c-f86cf8142273`; no token value, role_id,
|
||||
secret_id, or token accessor was included.
|
||||
|
||||
2026-06-29: ops-warden follow-up message
|
||||
`92de2614-061f-4241-aa13-a3ce72ad41d5` requested the AppRole handoff as the
|
||||
preferred end-state. Handoff was not executed because live apply is still gated
|
||||
by the missing approved decision and missing lane bootstrap token. Once those
|
||||
blockers clear, the intended handoff remains single-use AppRole material written
|
||||
to mode-0600 files outside any Git worktree and delivered to Bernd out-of-band.
|
||||
|
||||
2026-06-30: The decision gate is now resolved by the offline approval mirror,
|
||||
so handoff is waiting on live OpenBao apply plus an attended, out-of-band
|
||||
bootstrap path. No `role_id`, `secret_id`, token value, token accessor, or
|
||||
smoke output was written to Git or State Hub.
|
||||
|
||||
Define and execute the handoff: mint a fresh `secret_id`, deliver it (with the
|
||||
`role_id`) to the operator out-of-band; warden does `approle login` to obtain a
|
||||
`VAULT_TOKEN`. Post the non-secret pointers on the ops-warden thread (policy name,
|
||||
|
|
|
|||
253
workplans/SECRETS-WP-0005-scope-intent-value-gaps.md
Normal file
253
workplans/SECRETS-WP-0005-scope-intent-value-gaps.md
Normal file
|
|
@ -0,0 +1,253 @@
|
|||
---
|
||||
id: SECRETS-WP-0005
|
||||
type: workplan
|
||||
title: "Close high-value SCOPE and INTENT gaps"
|
||||
domain: infotech
|
||||
repo: secrets-engine
|
||||
status: finished
|
||||
owner: codex
|
||||
topic_slug: custodian
|
||||
created: "2026-06-29"
|
||||
updated: "2026-06-29"
|
||||
state_hub_workstream_id: "262e8539-bfd9-435c-81fc-8148c9c5f744"
|
||||
---
|
||||
|
||||
# SECRETS-WP-0005 - Close high-value SCOPE and INTENT gaps
|
||||
|
||||
## Goal
|
||||
|
||||
Convert the SCOPE/INTENT gap analysis into concrete documentation and planning
|
||||
changes that improve day-to-day value for agents, operators, and cross-repo
|
||||
integrators.
|
||||
|
||||
The main value target is clarity: keep `SCOPE.md` useful as a stable operating
|
||||
boundary, make the service/API direction visible, map the hardening trajectory,
|
||||
and tighten language around OpenBao custody, ops-warden routing, and lifecycle
|
||||
work.
|
||||
|
||||
## Source Analysis
|
||||
|
||||
This workplan is based on:
|
||||
|
||||
- `history/2026-06-29-scope-intent-gap-analysis.md`
|
||||
- `SCOPE.md`
|
||||
- `INTENT.md`
|
||||
- `docs/netkingdom-security-infrastructure.md`
|
||||
|
||||
The assessment found no major contradiction. The gap is that `SCOPE.md` is now
|
||||
implementation-rich and current, while `INTENT.md` is stable and aspirational.
|
||||
The best value comes from separating durable boundary language from volatile
|
||||
status, then making future high-value surfaces explicit enough that agents do
|
||||
not have to rediscover the direction.
|
||||
|
||||
## Value Strategy
|
||||
|
||||
Prioritize changes that:
|
||||
|
||||
- reduce stale operational text in long-lived boundary docs;
|
||||
- make future work easier to route without adding new authority;
|
||||
- clarify custody and routing boundaries before live OpenBao handoffs;
|
||||
- turn hardening goals into visible acceptance targets;
|
||||
- preserve current useful context by moving it to `history/` instead of deleting
|
||||
it.
|
||||
|
||||
## Tasks
|
||||
|
||||
## T01 - Separate durable scope from volatile status
|
||||
|
||||
```task
|
||||
id: SECRETS-WP-0005-T01
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "37c72cb5-d3fa-42a7-a9a4-28712582539e"
|
||||
```
|
||||
|
||||
2026-06-29: Refactored `SCOPE.md` current-state language to remove exact test counts, active workplan state, and pending live-gate detail. Durable status now points agents to workplans, `.custodian-brief.md`, and `history/`.
|
||||
|
||||
Refactor `SCOPE.md` so it remains a stable boundary document rather than a
|
||||
second workplan ledger.
|
||||
|
||||
Keep the current maturity summary, but remove or generalize details that will
|
||||
stale quickly: exact test counts, active workplan state, and pending live gates.
|
||||
Move any useful historical detail into `history/` if it is not already captured.
|
||||
|
||||
Acceptance:
|
||||
|
||||
- `SCOPE.md` still tells agents what this repo owns and does not own.
|
||||
- `SCOPE.md` no longer depends on exact test counts or active workplan status to
|
||||
remain true.
|
||||
- Current-state details needed for continuity are preserved in `history/` or the
|
||||
relevant workplan.
|
||||
- `git diff --check` is clean.
|
||||
|
||||
## T02 - Add service/API direction to the boundary
|
||||
|
||||
```task
|
||||
id: SECRETS-WP-0005-T02
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "8703854c-c722-45a9-ab93-1bd914ebd37f"
|
||||
```
|
||||
|
||||
2026-06-29: Added future service/API mode to `SCOPE.md` as an in-bound surface over proven CLI semantics for plans, deliveries, handoffs, lifecycle actions, and evidence.
|
||||
|
||||
Represent the `INTENT.md` service-mode direction in `SCOPE.md` without
|
||||
overcommitting implementation.
|
||||
|
||||
The service/API surface should be described as in scope for future work: a
|
||||
stable interface for ops-warden, agents, CI, workloads, and future UI surfaces
|
||||
to request approved plans, deliveries, handoffs, and non-secret evidence without
|
||||
knowing OpenBao internals.
|
||||
|
||||
Acceptance:
|
||||
|
||||
- `SCOPE.md` names service/API mode as an in-bound future surface.
|
||||
- The boundary says service mode does not replace OpenBao, flex-auth, key-cape,
|
||||
user-engine, or ops-warden.
|
||||
- No new API contract is promised beyond what this repo can plausibly own.
|
||||
|
||||
## T03 - Add a hardening trajectory section
|
||||
|
||||
```task
|
||||
id: SECRETS-WP-0005-T03
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "351eea5d-878b-4ddf-9d1f-6dd59929e3b0"
|
||||
```
|
||||
|
||||
2026-06-29: Added a durable `Hardening Trajectory` section to `SCOPE.md`, linked to `docs/hardening-backlog.md`, covering scoped auth, wrapping/leases, dual control, lifecycle, and service/API maturation.
|
||||
|
||||
Add a short durable hardening section to `SCOPE.md` that mirrors the direction
|
||||
in `INTENT.md`.
|
||||
|
||||
It should cover:
|
||||
|
||||
- replacing bootstrap token files with OIDC, service auth, or other scoped auth;
|
||||
- response wrapping and short leases;
|
||||
- dual control for production provisioning;
|
||||
- routine rotation, revocation, and deactivation;
|
||||
- evidence that proves delivery and lifecycle actions without exposing values.
|
||||
|
||||
Acceptance:
|
||||
|
||||
- `SCOPE.md` gives agents a clear next-hardening map.
|
||||
- The hardening section does not claim these items are already complete.
|
||||
- The section references existing backlog or workplan locations when useful.
|
||||
|
||||
## T04 - Tighten ops-warden and custody wording
|
||||
|
||||
```task
|
||||
id: SECRETS-WP-0005-T04
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "9444e6ba-2853-42d4-a074-e21b350d5d8a"
|
||||
```
|
||||
|
||||
2026-06-29: Tightened `SCOPE.md` and `docs/ops-warden-routing-contract.md` so OpenBao remains the custody backend, secrets-engine orchestrates approved OpenBao-backed flows, and ops-warden remains a conduit-not-broker SSH cert issuer.
|
||||
|
||||
Review `SCOPE.md`, `INTENT.md`, and routing docs for wording that could imply
|
||||
secrets-engine stores raw secret values itself or that ops-warden vends
|
||||
non-SSH secrets.
|
||||
|
||||
Preferred phrasing:
|
||||
|
||||
- OpenBao keeps custody, policy, lease, and audit.
|
||||
- secrets-engine orchestrates cataloged OpenBao-backed issuance, delivery,
|
||||
handoff, verification, and revocation.
|
||||
- ops-warden routes non-SSH credential needs here and issues SSH certificates
|
||||
itself.
|
||||
|
||||
Acceptance:
|
||||
|
||||
- `SCOPE.md` no longer says secrets-engine broadly "custodies tokens" without
|
||||
clarifying OpenBao custody.
|
||||
- Routing docs remain aligned with the conduit-not-broker model.
|
||||
- No text suggests raw values may move through Git, State Hub, chat, prompts,
|
||||
workplans, or normal logs.
|
||||
|
||||
## T05 - Make lifecycle capability first-class
|
||||
|
||||
```task
|
||||
id: SECRETS-WP-0005-T05
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "b259a499-a1aa-4b37-bf4d-bf19ed79eb99"
|
||||
```
|
||||
|
||||
2026-06-29: Added a first-class `Lifecycle and non-secret evidence` capability block to `SCOPE.md` for provision, verify, deliver, rotate, revoke, deactivate, and audit workflows.
|
||||
|
||||
Add durable boundary language for rotation, revocation, deactivation, and
|
||||
non-secret lifecycle evidence.
|
||||
|
||||
This should not require implementing new lifecycle code immediately. The goal is
|
||||
to make lifecycle ownership and value clear enough that future implementation
|
||||
work can be routed cleanly.
|
||||
|
||||
Acceptance:
|
||||
|
||||
- `SCOPE.md` includes lifecycle as a first-class capability or boundary concern,
|
||||
not only as a passing list item.
|
||||
- The text distinguishes one-off revoke support from routine lifecycle
|
||||
management.
|
||||
- Any follow-up implementation gaps are linked to `docs/hardening-backlog.md` or
|
||||
a future workplan.
|
||||
|
||||
## T06 - Bring INTENT vocabulary forward carefully
|
||||
|
||||
```task
|
||||
id: SECRETS-WP-0005-T06
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "cdd1c8a1-11ac-4d92-8d67-f239e62b0e62"
|
||||
```
|
||||
|
||||
2026-06-29: Updated `INTENT.md` carefully to acknowledge scoped OpenBao capability grants and auth-capability lanes while keeping the file mission-level and implementation-light.
|
||||
|
||||
Consider a small `INTENT.md` update for concepts that have become important
|
||||
without changing the mission: auth-capability lanes, scoped OpenBao
|
||||
capabilities, and the distinction between KV secret lanes and non-KV capability
|
||||
lanes.
|
||||
|
||||
This task is intentionally careful because `INTENT.md` should remain stable and
|
||||
aspirational, not become implementation status.
|
||||
|
||||
Acceptance:
|
||||
|
||||
- `INTENT.md` acknowledges scoped OpenBao capabilities if the wording improves
|
||||
clarity.
|
||||
- The file remains stable, concise, and mission-oriented.
|
||||
- Implementation-specific lane names stay in `SCOPE.md`, workplans, or history
|
||||
unless they serve as examples.
|
||||
|
||||
## T07 - Verify, sync, and record closeout
|
||||
|
||||
```task
|
||||
id: SECRETS-WP-0005-T07
|
||||
status: done
|
||||
priority: medium
|
||||
state_hub_task_id: "5168182e-9fce-4bf4-8e6d-7c6e93cc8f71"
|
||||
```
|
||||
|
||||
2026-06-29: Final documentation checks passed (`git diff --check` clean), docs were reviewed against `docs/netkingdom-security-infrastructure.md`, and State Hub consistency sync applied the SECRETS-WP-0005 task updates.
|
||||
|
||||
Run final documentation checks, preserve non-secret closeout evidence, and sync
|
||||
the workplan state.
|
||||
|
||||
Acceptance:
|
||||
|
||||
- `git diff --check` is clean.
|
||||
- The final changed docs are reviewed against
|
||||
`docs/netkingdom-security-infrastructure.md`.
|
||||
- State Hub progress records the closeout.
|
||||
- After workplan file changes, the custodian consistency sync is run or the
|
||||
operator is asked to run `make fix-consistency REPO=secrets-engine`.
|
||||
|
||||
## Exit Criteria
|
||||
|
||||
- `SCOPE.md` is stable enough for agents to use without frequent status churn.
|
||||
- `INTENT.md` and `SCOPE.md` agree on the expanded lane model without turning
|
||||
INTENT into an implementation ledger.
|
||||
- Service/API direction, hardening trajectory, custody boundaries, and lifecycle
|
||||
ownership are visible and actionable.
|
||||
- No raw secret values, token material, or sensitive operational details are
|
||||
added to Git, State Hub, chat, prompts, workplans, or normal logs.
|
||||
Loading…
Add table
Add a link
Reference in a new issue