diff --git a/INTENT.md b/INTENT.md index 8ba6387..3e416a2 100644 --- a/INTENT.md +++ b/INTENT.md @@ -74,10 +74,21 @@ build once approved. terms (approve, reject, or send back to phase 1 with feedback), not asked to review raw `bao` commands. 4. **Build.** Once approved, execute the plan — create/modify/tear down the - AppRole, policy, secret path, and catalog entry. Not before phase 3 - approval, ever, for anything that grants or widens access. (Tear-down of - something already flagged for removal, or a dry-run/plan-only mode, does - not require the same gate — see Design Principles.) + AppRole, policy, and secret path *structure*, then propose the matching + ops-warden catalog entry. Not before phase 3 approval, ever, for anything + that grants or widens access. (Tear-down of something already flagged for + removal, or a dry-run/plan-only mode, does not require the same gate — + see Design Principles.) + + **ops-mason never touches secret values, including its own builds.** It + creates the empty KV path, the policy, and the AppRole — structure only. + The actual secret value (an API key, a password) goes in through + ops-warden's existing **paste-once provision** desk + (`ops-warden/src/warden/desk.py`'s `paste_once_provision` act): a + localhost-only web form where the founder pastes the value once, written + directly via `bao kv put` and never shown in a terminal, chat, or audit + log. Phase 4 ends with "structure built, ready for paste-once + provisioning" — it does not end with a live credential. --- @@ -86,15 +97,36 @@ build once approved. ### ops-mason owns - Drafting and executing construction plans for new/changed/retired OpenBao - AppRoles, policies, and KV secret paths + AppRoles, policies, and KV secret paths (structure — never secret values, + see phase 4 above) - Consistency review against existing NetKingdom credential structure — reuse over duplication, compaction over sprawl - The executive-summary format that makes a plan decidable at a glance -- Registering what it builds into ops-warden's routing catalog - (`registry/routing/catalog.yaml`) so the lane is discoverable the moment - it exists +- Proposing the matching entry in ops-warden's routing catalog + (`ops-warden/registry/routing/catalog.yaml`) for what it builds - Its own audit trail of what it built, when, and under which approved plan +**Catalog entries are pointer-only, same rule ops-warden enforces on every +non-SSH entry (the catalog's own "no-double-source rule", +`ops-warden/workplans/WARDEN-WP-0010-access-routing-charter.md`):** +`id`/`title`/`need_keywords`/`owner_repo`/`subsystem`/`wiki_ref`/`canon_ref`/ +`reviewed`/`status`, always `warden_executes: false` (ops-mason built the +lane, it does not execute the runtime credential fetch — the consumer's own +code does, the way `rein-openweights/credentials.py` does today). **Never** +an authored `steps`/`cert_command` block — those are reserved for +`warden_executes: true` entries, i.e. ops-warden's own SSH lane. The actual +"how a consumer uses this credential" doc lives with the consumer (e.g. +`rein-openweights/INTENT.md`/`credentials.py`), referenced via `wiki_ref`, +not restated inside the catalog. + +Landing a catalog entry is a normal git contribution to the `ops-warden` +repo (a commit/PR touching `registry/routing/catalog.yaml`), subject to +its own CI (`tests/test_routing.py` — anchor resolution) and its stale-review +cadence (new entries typically start `status: draft` until the built lane +is verified end-to-end, then promoted to `active` — same as any other +owner-ship promotion in that catalog). ops-mason does not have, and does +not need, some separate live registration API into ops-warden. + ### ops-mason does not own | Need | Owner | ops-mason's relationship | @@ -106,6 +138,7 @@ build once approved. | SSH certificate issuance | ops-warden | Untouched — ops-mason works in OpenBao AppRole/policy/KV space, not the SSH CA lane | | OpenBao cluster init/unseal, platform deploy | railiance-platform | Out of scope — ops-mason operates within an already-running OpenBao | | Holding or logging secret values | Nobody, ever | Same invariant as ops-warden: values live in OpenBao and process env only | +| Delivering the actual secret value into a path ops-mason built | ops-warden (`paste_once_provision` desk) | ops-mason builds the empty structure; the founder pastes the value once through ops-warden's existing local web form, never through ops-mason | **ops-mason is not a second secrets manager and not a policy-decision engine.** It is the construction crew for a foundation ops-warden and every credential @@ -129,10 +162,11 @@ consumer stands on. Directly extends ops-warden's own principle 7. The executive summary is written so the founder never has to read a `bao` command to make the call. -5. **Nothing built is invisible.** Every successful build registers a - catalog entry in ops-warden's routing registry in the same action — - there is no such thing as infrastructure ops-mason built that ops-warden - doesn't know how to route to. +5. **Nothing built stays invisible.** Every successful build is followed by + a proposed catalog entry to `ops-warden` in the same phase-4 action + (pointer-only, `status: draft` until verified end-to-end) — there should + be no infrastructure ops-mason built that isn't at least a draft entry + away from `warden route find` surfacing it. 6. **Posture-aware, like ops-warden.** The organization is in build phase (one founder-operator, pre-revenue) — construction plans should reflect current posture (see `ops-warden/wiki/WorkloadSecurityPosture.md`) and @@ -172,7 +206,8 @@ ops-warden itself exists to prevent. architecture/founder call, ops-mason builds what's already decided - Applying anything that grants or widens access without a phase-3 approved plan -- Storing secret values anywhere but OpenBao / process env +- Touching secret values at all, even transiently — structure only; values + go in via ops-warden's `paste_once_provision` desk, not through ops-mason - Owning OpenBao cluster lifecycle, flex-auth runtime, or key-cape identity --- @@ -186,11 +221,12 @@ ops-mason is succeeding when: `bao` commands. 2. Every construction plan is checked against existing structure before it's proposed — duplicate/near-duplicate lanes are the exception, not routine. -3. The founder's only touchpoint is the phase-3 decision, made in plain - terms (who gets what, for how long, what it costs to undo) — never asked - to review raw provisioning mechanics. -4. Every ops-mason build has a matching ops-warden catalog entry the moment - it lands — no undocumented lanes. +3. The founder's only touchpoints are the phase-3 decision (plain terms: + who gets what, for how long, what it costs to undo) and, if the lane + needs a live value, one paste through ops-warden's existing desk — + never asked to review or run raw provisioning mechanics. +4. Every ops-mason build ships with a proposed ops-warden catalog entry — + no undocumented lanes, even in `draft` status. 5. Tearing down access is as routine and reviewed a process as creating it — sprawl doesn't accumulate because removal is just as supported as construction. diff --git a/SCOPE.md b/SCOPE.md index de4f817..c7dc4b7 100644 --- a/SCOPE.md +++ b/SCOPE.md @@ -16,10 +16,12 @@ decision gate, in plain terms; (4) build, only after approval. ## In Scope - Construction plans for new/changed/retired OpenBao AppRoles, policies, - KV secret paths + KV secret path *structure* (never values) - Consistency review — reuse over duplication, compaction over sprawl - The executive-summary format that makes a plan decidable at a glance -- Registering what it builds into ops-warden's routing catalog +- Proposing pointer-only entries (`warden_executes: false`, no authored + `steps`) in ops-warden's routing catalog for what it builds — a normal + git contribution to that repo, not a live API - Its own audit trail of what it built, under which approved plan ## Out of Scope @@ -31,7 +33,8 @@ decision gate, in plain terms; (4) build, only after approval. - Routing consumers to lanes once built — ops-warden - SSH certificate issuance — ops-warden - OpenBao cluster init/unseal, platform deploy — railiance-platform -- Holding or logging secret values, ever +- Touching secret values at all, even transiently — delivered via + ops-warden's existing `paste_once_provision` desk instead ## Current State diff --git a/workplans/MASON-WP-0001-foundation.md b/workplans/MASON-WP-0001-foundation.md index 9da8eb7..51a2f26 100644 --- a/workplans/MASON-WP-0001-foundation.md +++ b/workplans/MASON-WP-0001-foundation.md @@ -72,14 +72,18 @@ state_hub_task_id: "e37debfd-8a00-4780-b036-9376c6a10557" Phase 4: given an **approved** construction plan (explicit approval marker set after the executive summary was reviewed), execute it against -OpenBao — policy write, AppRole creation, KV secret path creation, -role_id/secret_id delivery to the consuming host, and a matching -ops-warden catalog entry in the same action (`INTENT.md` principle 5 — -nothing built stays invisible to ops-warden). Must refuse to run against -an unapproved or missing-approval-marker plan — this is the one place a -bug is a real security incident, not a bad UX. Start narrow: implement -only the operations the first real plan (T05) needs, not a general -OpenBao automation framework. +OpenBao — policy write, AppRole creation, KV secret path creation +(**empty path/structure only — never a secret value**, see `INTENT.md`), +role_id/secret_id delivery to the consuming host, and a proposed +pointer-only ops-warden catalog entry (`warden_executes: false`, no +authored `steps`, `status: draft` — a normal commit/PR to the +`ops-warden` repo, not a live API call). Ends by naming the exact +`paste_once_provision` step the founder still needs to do (which path, +which field) — it does not attempt to fill the value itself. Must refuse +to run against an unapproved or missing-approval-marker plan — this is +the one place a bug is a real security incident, not a bad UX. Start +narrow: implement only the operations the first real plan (T05) needs, +not a general OpenBao automation framework. ```task id: MASON-WP-0001-T04 @@ -92,11 +96,15 @@ state_hub_task_id: "e949f4b7-5ef4-4e42-8a07-61b6c8040298" Run the whole pipeline for real: construction plan for Option B from `glas-harness/workplans/GLAS-WP-0002-T02` (dedicated -`rein-openweights` AppRole + KV secret at `reins/rein-openweights/openrouter`, -mirroring `agent-harness-binky-mail`'s shape) → review/optimize → executive -summary → founder approval → build. Once built, notify -`glas-harness`/`rein-openweights` so `GLAS-WP-0002-T02`'s live OpenBao -verification can proceed. +`rein-openweights` AppRole + KV secret path at +`reins/rein-openweights/openrouter`, mirroring `agent-harness-binky-mail`'s +shape) → review/optimize → executive summary → founder approval → build +(structure only). Build ends with the founder pasting the real +OpenRouter key through ops-warden's `paste_once_provision` desk into the +newly created path/field — that one paste is the only place the live +value exists outside OpenBao. Once done, notify `glas-harness`/ +`rein-openweights` so `GLAS-WP-0002-T02`'s live OpenBao verification can +proceed. ```task id: MASON-WP-0001-T05