Document scope alignment and warden-sign readiness

This commit is contained in:
tegwick 2026-06-30 00:52:05 +02:00
parent d8aadaffe3
commit ae685f3a0a
10 changed files with 736 additions and 41 deletions

View 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.

View file

@ -7,8 +7,9 @@
## One-liner ## One-liner
**secrets-engine is the secure interaction and automation layer for approved **secrets-engine is the secure interaction and automation layer for approved
secret custody, delivery, and lifecycle work across build, test, and production, secret custody, scoped OpenBao capability handoff, delivery, and lifecycle work
with OpenBao as the initial enforcement backend.** across build, test, and production, with OpenBao as the initial enforcement
backend.**
## Why This Exists ## Why This Exists
@ -26,8 +27,8 @@ already produced avoidable friction:
- build, test, and production need different levels of privilege and ceremony; - build, test, and production need different levels of privilege and ceremony;
- secret values must never move through chat, Git, prompts, State Hub messages, - secret values must never move through chat, Git, prompts, State Hub messages,
or workplans; or workplans;
- ops-warden needs a reliable front door for credential use, not direct secret - ops-warden needs a reliable front door for credential and scoped capability
custody responsibility. use, not direct secret custody responsibility.
This repository exists to capture that complexity once, behind a stable and This repository exists to capture that complexity once, behind a stable and
auditable interface. auditable interface.
@ -36,10 +37,11 @@ auditable interface.
To provide a decision-aware secrets workflow that can: 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; - operate with distinct build, test, and production privilege layers;
- deliver secrets to commands and workloads without printing or storing raw - deliver secrets and scoped capabilities to commands and workloads without
values in coordination systems; printing or storing raw values in coordination systems;
- record enough non-secret evidence for review, audit, and troubleshooting; - record enough non-secret evidence for review, audit, and troubleshooting;
- make routine secure work fast enough that operators and agents actually use - make routine secure work fast enough that operators and agents actually use
the secure path. the secure path.
@ -55,7 +57,8 @@ not silently create new secret authority.
### 2. OpenBao Enforces, secrets-engine Orchestrates ### 2. OpenBao Enforces, secrets-engine Orchestrates
OpenBao remains the vault, policy, lease, and audit backend. secrets-engine owns 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 ### 3. Stage-aware Privilege
@ -97,11 +100,13 @@ has non-secret evidence that can be reviewed later.
secrets-engine is: 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 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 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; - an audit evidence writer for State Hub and local logs;
- the credential interaction surface that ops-warden can route to. - 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. | | 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. | | 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. | | 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. | | 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 contracts and catalog entries. | | 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. | | Request history and progress | State Hub | Write non-secret evidence and decision links only. |
## Direction of Evolution ## Direction of Evolution

View file

@ -28,6 +28,9 @@ evidence.
workflows. workflows.
- Exec-time delivery to operators, agents, CI jobs, workloads, and ops-bridge - Exec-time delivery to operators, agents, CI jobs, workloads, and ops-bridge
tasks without printing raw values. 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 - ops-warden routing contract for non-SSH credentials and scoped OpenBao
capabilities. capabilities.
- State Hub non-secret evidence and progress integration. - State Hub non-secret evidence and progress integration.
@ -72,31 +75,37 @@ evidence.
## Current State ## Current State
MVP delivered. The Python CLI (`src/secrets_engine/`) proves the MVP delivered. The Python CLI (`src/secrets_engine/`) supports the core lane
`whynot-design-npm-publish` KV lane end to end — catalog → decision check → flow: catalog → decision check → guarded OpenBao policy/AppRole apply →
policy/AppRole apply → provision → positive/negative verify → exec-time npm provision or handoff → positive/negative verification → safe delivery →
delivery → ops-warden routing pointer → revoke — verified live against OpenBao non-secret route pointers → revoke.
(`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`.
The current source also supports non-KV auth-capability lanes. `SECRETS-WP-0004` The repo supports both stored-value KV lanes and non-KV auth-capability lanes.
adds the `warden-sign` catalog lane, exact-path policy guards for KV lanes cover secrets such as npm publish tokens; auth-capability lanes cover
`ssh/sign/{agt-role,adm-role,atm-role}`, AppRole TTL/use constraints, positive narrow OpenBao policy/AppRole grants such as `ssh/sign/<role>` access for
and negative capability probes, and a handoff command that writes `role_id` and ops-warden. The maturity-gated publication-scope policy is in place and
`secret_id` only to mode-0600 files outside Git worktrees. Live apply and fail-safe: until the broader domain reaches the required maturity, publish lanes
cross-repo smoke remain pending OpenBao/operator gates. clamp to the safest repo-scoped token shape.
`SECRETS-WP-0003` has been optimized for the real whynot-design pilot closeout: Current operational status lives in workplans, `.custodian-brief.md`, and
the catalog points at the canonical approved State Hub decision, the old `history/`; this file should stay stable enough for agents and contributors to
slug-named offline decision mirror has been retired, and a non-secret preflight use as the boundary reference.
plus closeout runbook document the remaining real publish steps. The suite is
currently green at 59 passed, 2 skipped.
Bootstrap workplans `SECRETS-WP-0001` (State Hub integration) and ## Hardening Trajectory
`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 The steady-state target is to keep routine secure work low-friction while
ops-warden / FLEX-WP-0007 T4). 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 ## How It Fits
@ -111,7 +120,9 @@ sits between approval/identity systems and the OpenBao backend:
back. back.
- **user-engine / key-cape** — own identity and claims that bind consumers. - **user-engine / key-cape** — own identity and claims that bind consumers.
- **ops-warden** — routes non-SSH credential needs here (conduit-not-broker) and - **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 - **ops-bridge** — may consume scoped delivery for remote execution but stores no
secret material. secret material.
- **info-tech-canon** — source of canonical terminology and stage/policy concepts. - **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 | | **npm scope** | the `@`-prefixed npm name (`@whynot`) — distinct from org and repo |
| **maturity** | `maturity-build/test/prod` package tag; feeds the publication-scope policy | | **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 | | **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 ## 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. 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] 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]
```

View file

@ -53,6 +53,22 @@ auth_capability:
token_num_uses: 0 token_num_uses: 0
secret_id_ttl: 30m secret_id_ttl: 30m
secret_id_num_uses: 1 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: allowed_paths:
- path: ssh/sign/agt-role - path: ssh/sign/agt-role
capabilities: [update] capabilities: [update]

View file

@ -1,10 +1,11 @@
# ops-warden → secrets-engine Routing Contract # ops-warden → secrets-engine Routing Contract
ops-warden issues **SSH certificates only**. Every other credential need (API ops-warden issues **SSH certificates only**. Every other credential or scoped
keys, provider tokens, DB passwords, npm publish tokens, and OpenBao API token capability need (API keys, provider tokens, DB passwords, npm publish tokens,
lanes) routes to **secrets-engine**, which is OpenBao-backed. ops-warden must and OpenBao capability lanes) routes to **secrets-engine**. secrets-engine
never request, hold, cache, or vend a raw secret value. A route result is a returns non-secret pointers and safe next commands while OpenBao remains the
**pointer**, not a key. 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 ## 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 - **Actionable when not ready.** If a lane is unapproved, unapplied, or
unprovisioned, `next_command` + `missing` tell the caller exactly what to do. unprovisioned, `next_command` + `missing` tell the caller exactly what to do.
- **Idempotent / read-only.** `route` performs no mutation. - **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 ## whynot-design retry flow

View file

@ -16,6 +16,10 @@ only; the operator receives `role_id` and `secret_id` out-of-band.
| SSH mount | `ssh` | | SSH mount | `ssh` |
| Policy | `warden-sign` | | Policy | `warden-sign` |
| AppRole | `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` | | Token TTL | `15m` |
| Secret ID TTL | `30m` | | Secret ID TTL | `30m` |
| Secret ID uses | `1` | | 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 The bootstrap token file must be mode `0600`, revocable, and tracked in
[hardening-backlog.md](hardening-backlog.md) H0 until revoked and shredded. [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 ## Handoff
Mint a fresh single-use AppRole `secret_id` and write both handoff values to Mint a fresh single-use AppRole `secret_id` and write both handoff values to

View 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
View 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" },
]

View file

@ -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 production bootstrap token outside any repo. The pending token path/revocation
row is recorded in `docs/hardening-backlog.md` H0. 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 Apply the policy + AppRole on `https://bao.coulomb.social` using a mode-0600
bootstrap token stored outside any repo. Idempotent re-apply. 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, message `0bce1e08-58c2-4db4-b06c-f86cf8142273`; no token value, role_id,
secret_id, or token accessor was included. 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 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 `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, `VAULT_TOKEN`. Post the non-secret pointers on the ops-warden thread (policy name,

View 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.