diff --git a/WORK-RECORDS.md b/WORK-RECORDS.md index 2d5a210..6a470d6 100644 --- a/WORK-RECORDS.md +++ b/WORK-RECORDS.md @@ -25,6 +25,7 @@ | workplan | WARDEN-WP-0027 | backlog | — | workplans/WARDEN-WP-0027-credential-governance-lockdown.md | | workplan | WARDEN-WP-0028 | finished | — | workplans/WARDEN-WP-0028-tenant-secret-custody.md | | workplan | WARDEN-WP-0029 | finished | — | workplans/WARDEN-WP-0029-policy-front-door-and-founder-surface.md | +| workplan | WARDEN-WP-0030 | proposed | — | workplans/WARDEN-WP-0030-delegation-register.md | | task | ADHOC-2026-06-27-T01 | done | — | workplans/ADHOC-2026-06-27.md | | task | ADHOC-2026-06-29-T01 | done | — | workplans/ADHOC-2026-06-29.md | | task | ADHOC-2026-08-11-T01 | done | — | workplans/ADHOC-2026-08-11.md | @@ -97,3 +98,8 @@ | task | WARDEN-WP-0029-T03 | done | — | workplans/WARDEN-WP-0029-policy-front-door-and-founder-surface.md | | task | WARDEN-WP-0029-T04 | done | — | workplans/WARDEN-WP-0029-policy-front-door-and-founder-surface.md | | task | WARDEN-WP-0029-T05 | done | — | workplans/WARDEN-WP-0029-policy-front-door-and-founder-surface.md | +| task | WARDEN-WP-0030-T01 | todo | — | workplans/WARDEN-WP-0030-delegation-register.md | +| task | WARDEN-WP-0030-T02 | todo | — | workplans/WARDEN-WP-0030-delegation-register.md | +| task | WARDEN-WP-0030-T03 | todo | — | workplans/WARDEN-WP-0030-delegation-register.md | +| task | WARDEN-WP-0030-T04 | todo | — | workplans/WARDEN-WP-0030-delegation-register.md | +| task | WARDEN-WP-0030-T05 | todo | — | workplans/WARDEN-WP-0030-delegation-register.md | diff --git a/wiki/playbooks/ops-bridge-tunnel-cert.md b/wiki/playbooks/ops-bridge-tunnel-cert.md index e1bf883..3fa06ed 100644 --- a/wiki/playbooks/ops-bridge-tunnel-cert.md +++ b/wiki/playbooks/ops-bridge-tunnel-cert.md @@ -65,6 +65,16 @@ warden sign agt-state-hub-bridge --pubkey ~/.ssh/agt-state-hub-bridge_ed25519.pu Confirm exit 0 and cert line starts with `ssh-ed25519-cert-v01@openssh.com`. +> **Attended only.** The manual `export` above is the documented fallback +> (`wiki/playbooks/operator-openbao-token-hygiene.md`); prefer the credential broker +> (`ops-warden-warden-sign-token`). Neither answers **unattended renewal on the remote +> tunnel host**, which is an open question, not an oversight: running the broker there +> requires placing the railiance-platform checkout and its *issuer* token on that host. +> A narrower alternative — a `warden-sign` AppRole scoped to `ssh/sign/{agt,adm,atm}-role` +> — is validated but **parked** (`workplans/ADHOC-2026-08-11.md` T03, secrets-engine +> `SECRETS-WP-0004`). **Resolve the token source before the live cutover**; do not +> default to a long-lived exported token on the tunnel host. + --- ## Migration checklist diff --git a/workplans/ADHOC-2026-08-11.md b/workplans/ADHOC-2026-08-11.md index da5668f..3b260a3 100644 --- a/workplans/ADHOC-2026-08-11.md +++ b/workplans/ADHOC-2026-08-11.md @@ -70,7 +70,7 @@ read. Inbox is now empty. - [x] **secrets-engine warden-sign** (`80456912`) — see T03; replied with status and referred the live-apply question to the owner. -### T03 — Open question for the operator: withdraw or keep the warden-sign AppRole +### T03 — warden-sign AppRole: PARKED pending WP-0027 break-glass + ops-bridge cutover ```task id: ADHOC-2026-08-11-T03 @@ -91,9 +91,38 @@ need is served by the railiance-platform credential broker (`ops-warden-warden-sign-token`, active; `credential.py exec --grant ops-warden/warden-sign`, proven via `make credential-exec-ops-warden-smoke`) — no AppRole involved. -Decision needed from Bernd: keep the AppRole as a broker-independent fallback path to -signing, or withdraw SECRETS-WP-0004. ops-warden's recommendation is **withdraw** unless -there is a concrete failure mode the broker cannot cover — a second standing credential -to rotate and audit is a real cost for a lane that currently works. Not ops-warden's call; -asked secrets-engine to hold live apply until it resolves. Task stays `wait` pending that -answer. +**Resolved 2026-08-11: parked** — neither withdrawn nor proceeding. Founder decision +after reviewing the mechanics. Communicated to secrets-engine (msg `863c7b57`) with an +explicit instruction to stop holding apply readiness. + +An initial recommendation to **withdraw** was revised on inspection: + +- `warden sign` reads `VAULT_TOKEN` from the environment and has no AppRole login path + (`src/warden/vault.py:24-27`). The AppRole is a way for a *host* to obtain a token, + not an ops-warden code path — withdrawing costs no code and removes no working + capability. For the workstation, the broker plus attended operator OIDC is sufficient. +- The uncovered case is **unattended signing on a remote host** — the pending ops-bridge + cert_command cutover. `wiki/playbooks/ops-bridge-tunnel-cert.md:61` still falls back to + a manually exported `VAULT_TOKEN` there. +- Running the broker on that host means placing the railiance-platform checkout *and its + issuer token* (`credential-broker-warden-sign-issuer` — authority to mint warden-sign + tokens repeatedly) on it. The AppRole exchanges for a `warden-sign`-only token + (`update` on `ssh/sign/{agt,adm,atm}-role`). Both are standing credentials on a remote + host; **the AppRole is the narrower one**, and is the established NetKingdom pattern + for this shape (`rein-openweights-openrouter-approle`, + `agent-harness-binky-mail-approle`). + +No circular dependency exists today: OpenBao is a public endpoint +(`https://bao.coulomb.social`), so obtaining a cert never requires already holding one. + +**Un-park triggers** (either one re-opens the question): + +1. **WARDEN-WP-0027** (backlog) designs the graded lockdown / break-glass path and its + explicit trust-root — a second autonomous path to signing is an input to that design, + not an isolated decision. +2. **ops-bridge cert_command live cutover** reaches unattended signing on a remote host. + +Cheap to reverse: the secrets-engine dry-run plan is validated, re-runnable, and correct +as drafted. The two operator gates (SECRETS-WP-0004 decision, mode-0600 lane bootstrap +token) are deliberately *not* being satisfied while parked. Task stays `wait` until a +trigger fires. diff --git a/workplans/WARDEN-WP-0027-credential-governance-lockdown.md b/workplans/WARDEN-WP-0027-credential-governance-lockdown.md index 2559c23..8b26aa7 100644 --- a/workplans/WARDEN-WP-0027-credential-governance-lockdown.md +++ b/workplans/WARDEN-WP-0027-credential-governance-lockdown.md @@ -104,6 +104,19 @@ step is opt-in and attended. trust-root and quorum, and soft-lockdown is executable via capabilities-based policy toggles. +**Parked input — the warden-sign AppRole (2026-08-11).** secrets-engine holds a +validated dry-run for a `warden-sign` AppRole (policy + role, `update` on +`ssh/sign/{agt,adm,atm}-role` only). It was **parked** rather than withdrawn +specifically because it is an input to this task: today the credential broker is the +only *autonomous* path to a signing token, so if its issuer lapses, recovery is a +founder OIDC act. Whether a second autonomous path should exist — and whether it is +the AppRole or something this trust-root design supersedes — is a break-glass +question, not a routing one. Resolve it here. Context and the counter-argument +(AppRole is narrower in capability than placing the broker's issuer token on a remote +host) are in `workplans/ADHOC-2026-08-11.md` T03; secrets-engine was told to stop +holding apply readiness until this task or the ops-bridge cutover fires +(msg `863c7b57`). + ## Task: Tamper-evident policy governance + reconcile ```task @@ -130,3 +143,6 @@ manifest, and an attended reconcile can restore it. - `.claude/rules/credential-routing.md` — ops-warden custodies no secret values - `railiance-platform` — OpenBao cluster, policy custody, credential broker - `wiki/AccessRouting.md` — issue vs route vs assist boundary +- `workplans/ADHOC-2026-08-11.md` T03 — parked warden-sign AppRole; un-parks on this + workplan's break-glass task or the ops-bridge cert_command cutover +- `secrets-engine` `SECRETS-WP-0004` — the parked AppRole apply/handoff diff --git a/workplans/WARDEN-WP-0030-delegation-register.md b/workplans/WARDEN-WP-0030-delegation-register.md index 09f928a..c0ec772 100644 --- a/workplans/WARDEN-WP-0030-delegation-register.md +++ b/workplans/WARDEN-WP-0030-delegation-register.md @@ -11,6 +11,7 @@ planning_priority: high planning_order: 30 created: "2026-08-11" updated: "2026-08-11" +state_hub_workstream_id: "29f3fcb3-e3c5-4f9d-bdfd-f76254754e21" --- # WARDEN-WP-0030 — Delegation register @@ -88,6 +89,7 @@ to *"who should own this front door, and what is missing?"* id: WARDEN-WP-0030-T01 status: todo priority: high +state_hub_task_id: "3d76f6c2-5007-4ad5-8d6f-360f9303c929" ``` Add a doctrine section to `wiki/AccessRouting.md` stating the boundary: the only @@ -103,6 +105,7 @@ targets. Cross-link INTENT.md §9. id: WARDEN-WP-0030-T02 status: todo priority: high +state_hub_task_id: "8013020b-d0a5-4e89-8e0b-bc418a761c84" ``` Extend the catalog entry schema with: @@ -126,6 +129,7 @@ flagged in the workplan for founder review rather than asserted as settled. id: WARDEN-WP-0030-T03 status: todo priority: medium +state_hub_task_id: "e7755708-e1bf-4d42-999c-4a60330cf154" ``` `warden route gaps [--json]` lists interim lanes with intended owner, blocker, and @@ -140,6 +144,7 @@ entries in the existing drift/stale review cadence. id: WARDEN-WP-0030-T04 status: todo priority: medium +state_hub_task_id: "ddc0268b-1279-4875-b223-0627c97d657a" ``` Update `wiki/playbooks/catalog-lane-promotion.md`: draft→active requires a @@ -153,6 +158,7 @@ checklist. id: WARDEN-WP-0030-T05 status: todo priority: medium +state_hub_task_id: "d8796e25-e896-463d-9476-f002e38b6897" ``` Once T02 is reviewed, send the interim register to secrets-engine, tenant-engine,