Console mapping: is v0.2 expressive enough (RBT-WP-0009-T05); RBT-WP-0005 decisions
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: sonnet Assistant-Process: 295952@bnt-lap001 Assistant-Session: e93f64ad-516c-46eb-9666-aad8d300c477
This commit is contained in:
parent
6d70f4d97d
commit
f52a3e14f4
3 changed files with 120 additions and 9 deletions
109
docs/console-mapping.md
Normal file
109
docs/console-mapping.md
Normal file
|
|
@ -0,0 +1,109 @@
|
|||
# Is v0.2 expressive enough? Mapping the security bootstrap console
|
||||
|
||||
Status: analysis, 2026-09-29 (RBT-WP-0009-T05; closes RBT-WP-0005-T03).
|
||||
|
||||
The plan for adopting `runbook-pack/v0.2` said: use the NetKingdom security bootstrap console
|
||||
(`net-kingdom/tools/security-bootstrap-console/`, 5,300 lines, invented in NET-WP-0016) as the first real test. If the model
|
||||
can express its stages, gates and runbooks without special cases, it is expressive enough. This is that test, done from the
|
||||
console's own definitions (read from its running `/api/status` and its source, against a throwaway metadata file).
|
||||
|
||||
## Verdict
|
||||
|
||||
**The structure maps; the behaviour does not fully.** v0.2 expresses the console's stages, gates, actors, dimensions, artefacts,
|
||||
evidence validators, typed approval and alternatives. It does not yet express five behaviours the console relies on: conditional
|
||||
applicability, re-evaluation of gates that can regress, outputs of one member feeding the next, local-only attributes, and
|
||||
gates satisfied by an automation path. So v0.2 is adequate for **procedures** (every runbook in the console, and the three
|
||||
NetKingdom packs) and **not yet proven adequate for a long-lived staged bootstrap** as a whole. Decision: the console stays a permanent
|
||||
legacy pack (RBT-WP-0005-T05); extracting its engine parts (T04) is moved to the backlog until the gaps below are closed.
|
||||
|
||||
## What the console contains
|
||||
|
||||
| Element | Count | Notes |
|
||||
| --- | --- | --- |
|
||||
| Stages | 6 | S1 Low-trust assembly, S2 King credential preparation, S3 OpenBao bootstrap, S4 Admin identity integration, S5 Cleanup and hardening, S6 Reopen under custody |
|
||||
| Top-level gates | 14 | statuses `done`, `blocked`, `human`, `automation` |
|
||||
| Sub-checklists | 11 + 4 + 4 | king-credential kit items, key-custody items, admin-identity integrations |
|
||||
| Section statuses | 9 | view-level completeness of the UI's own sections, not gates |
|
||||
| Roles | 6 | setup-operator, platform-root-custodian, identity-admin, openbao-ceremony-operator, recovery-custodian, future-quorum-custodian; each with a designated contact |
|
||||
| Subsystems, integrations | 6 + 6 | LLDAP, privacyIDEA, KeyCape, OpenBao, custodian age envelope, bootstrap bundle |
|
||||
| Runbooks | 7 | all `template` state; 23 copyable command blocks in total |
|
||||
| Artefacts | 12 | references only (a password-safe entry, an age key location, unseal shares held elsewhere); states nil, set, ok |
|
||||
| Approval | 1 | typed phrase `approve custody mode`, two approvable modes |
|
||||
|
||||
## How the console works, which decides the mapping
|
||||
|
||||
1. **A persistent fact document** (`.local/security-bootstrap.json`, flat keys such as `openbao_initialized`). It lives for weeks.
|
||||
2. **The stage is derived from the facts** (`derive_stage`: the most advanced fact wins), not from stepping through a list.
|
||||
3. **Gates are computed on every view**, from the facts and from live probes (files present, a Secret deployed in the cluster). A gate can go
|
||||
back from done to blocked when the system changes.
|
||||
4. **Gate status is a small vocabulary**: `done`; `blocked` (a precondition is missing); `human` (ready, waiting for a person);
|
||||
`automation` (satisfied by an unattended path, for example the SOPS-held init).
|
||||
5. **Applicability depends on choices**: the unseal custody model (sops-held, attended ceremony, auto-unseal) changes which init gate
|
||||
applies, and the production profile forbids one of them.
|
||||
|
||||
## The 14 gates
|
||||
|
||||
| # | Gate | Stage (proposed) | v0.2 form | Verdict |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| 1 | King credential kit | S2 | gate `datapoints_ok` over the 11 kit items (datapoints, confirmed by steps) | direct |
|
||||
| 2 | Custody strategy approval | S2 | irreversible step with `confirm_phrase: approve custody mode`; gate on the `custody_mode` datapoint | **caveat G4**: only some modes may approve live init; needs a value predicate, or an enum limited to the approvable modes |
|
||||
| 3 | OpenBao preflight | S3 | gate check `command`, exit 0 (`make ... openbao-status`) | direct |
|
||||
| 4 | OpenBao unseal custody model | S3 | enum datapoint `custody_model`; the production profile blocks one value | **caveat G4** (cross-datapoint rule) and G1 |
|
||||
| 5 | OpenBao init ceremony | S3 | step with alternatives (attended ceremony / automated init), recommended by `custody_model` | alternatives fit, but the automated path is executed by a script: **needs execution (G6)**, and refusing live init under some profiles is G1 |
|
||||
| 6 | OpenBao initial configuration | S3 | step, then gate on an evidence datapoint | direct |
|
||||
| 7 | KeyCape OpenBao client definition | S4 | gate check `command` probing the source | direct; **G3** (recheck) |
|
||||
| 8 | KeyCape OpenBao client deployed | S4 | gate check `command` probing the live Secret | direct; **G3** |
|
||||
| 9 | OpenBao OIDC auth | S4 | step plus evidence datapoint | direct |
|
||||
| 10 | OIDC admin login | S4 | manual check (a browser login through KeyCape and MFA), plus a claims check by command | direct |
|
||||
| 11 | Root-token disposition | S5 | enum datapoint limited to `revoked` and `offline-sealed`; gate `datapoints_ok` | direct |
|
||||
| 12 | Restore drill | S5 | a separate pack (7 command blocks, evidence validator); gate check runs the validator | **caveat**: needs a dependency between runbooks (`requires_packs`, RBT-WP-0006-T04), or the drill inlined |
|
||||
| 13 | Cleanup and rotation | S5 | gate with several manual checks | direct |
|
||||
| 14 | Platform reopen | S6 | gate check by the custodian actor, with an irreversible confirmation | direct |
|
||||
|
||||
**Ten map directly, three with a caveat, one needs execution.** The console does not tie gates to stages explicitly; v0.2 does, which is
|
||||
the improvement asked for in the UX review (each gate belongs to one stage and names its quality goal). The sub-checklists map to
|
||||
datapoints and steps in the stage they belong to.
|
||||
|
||||
## The rest of the model
|
||||
|
||||
| Console | v0.2 | Fit |
|
||||
| --- | --- | --- |
|
||||
| Stages S1 to S6 | `stages`, completion derived from members | good; order by `requires` |
|
||||
| Roles with designated contacts | `actors`, plus a datapoint per contact carrying the `actor` dimension | good; see G5 for the contacts |
|
||||
| Subsystems | the `subsystem` dimension on datapoints | good; the data view already groups by it |
|
||||
| Artefacts (nil, set, ok) | `artefacts` with a location datapoint | good; artefact state is derived from the location datapoint |
|
||||
| The 7 runbooks | 7 native packs | good and independent of the gaps: each is a linear procedure with commands |
|
||||
| The 23 command blocks | step commands; the interactive `read -rs` prompts stay operator-run | good; nothing secret is ever entered into the engine |
|
||||
| Typed approval phrase | `confirm_phrase` on an irreversible step | good |
|
||||
| Evidence validators (`validate-*`) | gate or step checks by `command`, exit 0 | good |
|
||||
| Copyable command blocks, next action | the guided flow | the new UI does both |
|
||||
|
||||
## The gaps
|
||||
|
||||
These are candidates for a v0.3. None blocks closing the runbook-tutorials workplans, and none affects the procedures that exist today.
|
||||
|
||||
- **G1 Conditional applicability.** Stages, steps and gates that apply only for some choices (`applies_when` on a datapoint value). `one_of`
|
||||
chooses between alternatives inside a step; it cannot switch a whole gate on or off.
|
||||
- **G2 A longer horizon.** A run untouched for seven days counts as abandoned. A multi-week ceremony needs a per-pack (or per-run) horizon.
|
||||
- **G3 Re-evaluating a gate.** A passed gate is final in a run. The console's gates regress when the system changes. A gate needs a recheck,
|
||||
and a passed gate that fails a recheck needs a state of its own.
|
||||
- **G4 Value predicates.** `datapoints_ok` only asks that a datapoint is `ok`. The console needs "this datapoint is one of these values" and
|
||||
rules across two datapoints (`production` excludes `sops-held-automation`).
|
||||
- **G5 Local-only attributes.** The console keeps role contacts (email addresses) in an ignored `.local` file. Attribute sets and project
|
||||
files are meant to be committed, so personal data would land in git. An attribute needs a `local` visibility that is never written into a
|
||||
repository file.
|
||||
- **G6 Gates satisfied by an automation path.** The console's `automation` status means an unattended script did the work. Auto-confirm
|
||||
only confirms; running the script is the opt-in execution level (RBT-WP-0006-T01).
|
||||
- **G7 Outputs feed later members.** A project run snapshots its attributes at the start. Facts established by one member (the custody
|
||||
model chosen in S2, "OpenBao initialized" in S3) do not flow into the members after it. A staged bootstrap as a project needs that flow.
|
||||
|
||||
## Consequences
|
||||
|
||||
- **The seven runbooks and the three NetKingdom packs can be native v0.2 packs now.** The three NetKingdom packs are ported in
|
||||
RBT-WP-0009-T06. The seven console runbooks are ready to port as a separate content task in net-kingdom; they need none of G1 to G7.
|
||||
- **The console stays.** It is a permanent legacy pack, launched unchanged. What it does well and v0.2 cannot yet do (live probes,
|
||||
regression, a fact store that outlives a session, conditional gates) is exactly G1, G3, G5 and G7.
|
||||
- **The engine extraction (RBT-WP-0005-T04) waits for G1, G3 and G7.** Extracting the generic parts first would freeze the console's
|
||||
workarounds into the engine.
|
||||
- **The console is a project, not a run.** The right long-term shape is a project whose members are runbook packs per stage, with facts
|
||||
flowing between them (G7). That is a design task for a v0.3, not a migration.
|
||||
|
|
@ -50,12 +50,12 @@ with a stub server.
|
|||
|
||||
```task
|
||||
id: RBT-WP-0005-T03
|
||||
status: todo
|
||||
status: done
|
||||
priority: high
|
||||
state_hub_task_id: "dbb5553d-fb0c-5298-85c8-cebc9dd63312"
|
||||
```
|
||||
|
||||
Classify the 5,300-line `security_bootstrap_console.py` into generic engine
|
||||
Done 2026-09-29 (RBT-WP-0009-T05): `docs/console-mapping.md`. Classify the 5,300-line `security_bootstrap_console.py` into generic engine
|
||||
concerns (record and state model, gates, stage derivation, copyable blocks,
|
||||
approval phrase, localhost server) and NetKingdom-specific content (custody,
|
||||
OpenBao ceremony, KeyCape, privacyIDEA checks). Output: a migration map with
|
||||
|
|
@ -65,12 +65,13 @@ the tests that pin current behaviour.
|
|||
|
||||
```task
|
||||
id: RBT-WP-0005-T04
|
||||
status: todo
|
||||
status: cancel
|
||||
priority: medium
|
||||
state_hub_task_id: "14261c00-65d0-55be-8ab2-bd81e579e20d"
|
||||
```
|
||||
|
||||
Move the generic parts into `rtut` behind the run record. The console in
|
||||
Cancelled 2026-09-29: extracting the console's engine now would freeze its workarounds into the engine, because v0.2 lacks conditional applicability, gate
|
||||
recheck and outputs that feed later members (`docs/console-mapping.md` G1, G3, G7). It may return as part of a v0.3 design. Original scope: move the generic parts into `rtut` behind the run record. The console in
|
||||
`net-kingdom` then imports them. Gate: the existing
|
||||
`tools/security-bootstrap-console/tests` pass unchanged before and after, and
|
||||
`make security-bootstrap-ui` behaves the same.
|
||||
|
|
@ -79,13 +80,14 @@ Move the generic parts into `rtut` behind the run record. The console in
|
|||
|
||||
```task
|
||||
id: RBT-WP-0005-T05
|
||||
status: todo
|
||||
status: done
|
||||
priority: low
|
||||
state_hub_task_id: "c54cfa35-1a34-5d5a-b85b-86ae8771dcfb"
|
||||
```
|
||||
|
||||
With Bernd: keep the console as a permanent legacy pack, migrate its runbooks
|
||||
to native packs, or a mix. Record as a decision.
|
||||
Decided 2026-09-29 (Bernd, with RBT-WP-0009): the console stays a permanent legacy pack, launched unchanged. Its seven runbooks can become native v0.2
|
||||
packs as separate content work (they need none of G1 to G7). Original question: keep the console as a permanent legacy pack, migrate its runbooks
|
||||
to native packs, or a mix.
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
|
|
|
|||
|
|
@ -77,11 +77,11 @@ refused (409). Added `rtut seal <file>` so an exported record can be verified an
|
|||
|
||||
```task
|
||||
id: RBT-WP-0009-T05
|
||||
status: todo
|
||||
status: done
|
||||
priority: high
|
||||
```
|
||||
|
||||
`docs/console-mapping.md`: map the security bootstrap console's 6 stages, 14 gates, roles, subsystems, integrations, 12 artefacts
|
||||
Done 2026-09-29. Verdict: the structure maps, the behaviour does not fully; seven gaps (G1 to G7) are the v0.3 candidates. `docs/console-mapping.md`: map the security bootstrap console's 6 stages, 14 gates, roles, subsystems, integrations, 12 artefacts
|
||||
and 7 runbooks onto v0.2 and say honestly where a special case is needed. This is the acceptance evidence for the model. It closes
|
||||
RBT-WP-0005-T03, records the decision to keep the console as a permanent legacy pack (T05), and moves the extraction (T04) to the backlog.
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue