From fff76ef089d9940903c7b1ef3817744c1e09bedf Mon Sep 17 00:00:00 2001 From: tegwick Date: Sat, 22 Aug 2026 20:36:49 +0200 Subject: [PATCH] docs: activate credential break-glass planning Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a0290b-3241-74c3-b868-6049545af836 --- SCOPE.md | 2 +- WORK-RECORDS.md | 4 +- docs/credential-governance-break-glass.md | 117 ++++++++++++++++++ registry/generated/high-risk-data-paths.yaml | 8 +- ...-WP-0027-credential-governance-lockdown.md | 61 ++++++--- 5 files changed, 169 insertions(+), 23 deletions(-) create mode 100644 docs/credential-governance-break-glass.md diff --git a/SCOPE.md b/SCOPE.md index 4c3490c..ae19ee4 100644 --- a/SCOPE.md +++ b/SCOPE.md @@ -280,7 +280,7 @@ for the rest. | WP | Status | Focus | | --- | --- | --- | -| WP-0027 | `backlog` | Tamper-resistant credential governance + mass rotation/lockdown (Strand B follow-on to WP-0026) | +| WP-0027 | `active` | Break-glass design/rehearsal activated narrowly on T02; mass rotation and policy-manifest reconcile remain deferred | | WP-0032 | `finished` | Security zones adopted — global switch retired, explicit workload references compiled, and owner policy live | | WP-0030 | `proposed` | Delegation register — record intended owner + blocker on every interim lane, `warden route gaps`, promotion gate | diff --git a/WORK-RECORDS.md b/WORK-RECORDS.md index 40db1ba..0bc6497 100644 --- a/WORK-RECORDS.md +++ b/WORK-RECORDS.md @@ -23,7 +23,7 @@ | workplan | WARDEN-WP-0024 | finished | — | workplans/WARDEN-WP-0024-experiential-memory-and-agent-sessions.md | | workplan | WARDEN-WP-0025 | finished | — | workplans/WARDEN-WP-0025-forgejo-admin-api-token-lane.md | | workplan | WARDEN-WP-0026 | finished | — | workplans/WARDEN-WP-0026-credential-disclosure-hygiene.md | -| workplan | WARDEN-WP-0027 | backlog | — | workplans/WARDEN-WP-0027-credential-governance-lockdown.md | +| workplan | WARDEN-WP-0027 | active | — | 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 | finished | — | workplans/WARDEN-WP-0030-delegation-register.md | @@ -92,7 +92,7 @@ | task | WARDEN-WP-0026-T06 | done | — | workplans/WARDEN-WP-0026-credential-disclosure-hygiene.md | | task | WARDEN-WP-0026-T07 | done | — | workplans/WARDEN-WP-0026-credential-disclosure-hygiene.md | | task | WARDEN-WP-0027-T01 | cancel | — | workplans/WARDEN-WP-0027-credential-governance-lockdown.md | -| task | WARDEN-WP-0027-T02 | cancel | — | workplans/WARDEN-WP-0027-credential-governance-lockdown.md | +| task | WARDEN-WP-0027-T02 | progress | — | workplans/WARDEN-WP-0027-credential-governance-lockdown.md | | task | WARDEN-WP-0027-T03 | cancel | — | workplans/WARDEN-WP-0027-credential-governance-lockdown.md | | task | WARDEN-WP-0028-T01 | done | — | workplans/WARDEN-WP-0028-tenant-secret-custody.md | | task | WARDEN-WP-0028-T02 | done | — | workplans/WARDEN-WP-0028-tenant-secret-custody.md | diff --git a/docs/credential-governance-break-glass.md b/docs/credential-governance-break-glass.md new file mode 100644 index 0000000..9262258 --- /dev/null +++ b/docs/credential-governance-break-glass.md @@ -0,0 +1,117 @@ +# Credential governance break-glass contract + +Status: active design contract for WARDEN-WP-0027-T02. This document does not +authorize a seal, re-key, token mint, policy write, workload restart, or host +reboot. + +## Decision boundary + +ops-warden consumes and verifies credential-control evidence; it does not own +the OpenBao cluster, unseal shares, recovery snapshots, policies, or root token. +`railiance-platform` is accountable for the OpenBao operation. The share +custodians, platform driver, abort operator, provider-console operator, and +affected workload owners participate through an attended approval window. + +The current production trust-root is the rotated Shamir barrier restored to +railiance01 in RMASTER-WP-0020: three separately custodied shares with a +threshold of two. Share-holder identities and share material remain in the +approved out-of-band custody system, never Git, State Hub, shell history, logs, +or chat. A readiness receipt names participating *roles* and attests that two +distinct custodians are present; it never contains a share or recovery value. + +Root is offline bootstrap/break-glass material only. It is not a substitute for +`platform-admin` OIDC and must not be used through the browser UI. An ordinary +unseal uses threshold shares and does not require a root token. + +## Graded response + +| Grade | Trigger | Action owner | Exit evidence | +| --- | --- | --- | --- | +| Observe | Suspicion without confirmed credential disclosure | lane owner + risk-nexus | Metadata-only taint, audit, policy, and capability review | +| Soft lockdown | Coding-agent access must stop while human recovery remains available | railiance-platform | `agent-high-risk-boundary` source/live equality; all concrete high-risk data paths denied; metadata readable | +| Lane containment | One or more concrete credentials are exposed | each credential owner | Front door disabled, provider/OpenBao rotation through the owner-native procedure, consumer cutover, taint cleared only after verification | +| Hard lockdown | OpenBao trust or control-plane integrity is in doubt | platform driver under attended approval | Fresh encrypted snapshot receipt, intentional seal, sealed-state proof, 2-of-3 unseal, post-unseal and consumer verification | +| Re-key | A Shamir share or the barrier custody model is compromised | platform owner + threshold custodians | Separately approved OpenBao re-key ceremony, new threshold custody attestation, old-share retirement, recovery drill | + +Hard lockdown is not an agent command. The irreversible hold point is the +platform owner's attended seal action. All prerequisites below must be true +before that hold point; repository access alone grants no authority to cross it. + +## Pre-seal hold point + +- An approved, bounded window names the accountable platform driver and a + distinct abort operator. +- Two distinct Shamir custodians attest availability through the approved + out-of-band channel. +- Independent provider-console access is verified by its owner. +- A current Raft snapshot is encrypted and stored off-host; the non-secret + receipt binds cluster id, Raft index, plaintext/encrypted hashes, location, + age, and verification without including protected material. +- Current OpenBao health, seal state, Raft peers, audit device, auth methods, + policy fingerprints, and consumer readiness are captured as metadata. +- A rollback/re-entry order and stop conditions are acknowledged by affected + workload owners. + +Any missing or stale item aborts before sealing. A live incident may require +immediate network isolation, but that does not authorize improvising share or +root-token handling. + +## Re-entry sequence + +The platform owner performs the exact commands from +`railiance-platform/docs/openbao.md`; ops-warden does not copy a second +execution procedure here. + +1. Confirm the instance is intentionally sealed and the approved window is + still open. +2. Two custodians supply shares through hidden, non-logged prompts. No agent + observes the values. +3. Prove `initialized=true` and `sealed=false`, then run the owner post-unseal + verification. +4. Verify Raft, persistent audit output, OIDC metadata, SSH roles, and policy + fingerprints before restoring normal access. +5. Reconcile ExternalSecret stores and bounded consumers in dependency order. +6. Run value-safe capability probes, including the coding-agent deny-wins check + and an ops-warden signing smoke that records only backend and decision ids. +7. Revoke temporary operator tokens and close the window with non-secret + timing, status, and abort/rollback evidence. + +The August 3 migration already proved two attended restart/unseal cycles under +the same 2-of-3 barrier. T02 still requires one current emergency-seal drill +against the authoritative runtime because restore rehearsal and intentional +production lockdown are different claims. + +## Warden signing recovery + +Do not apply the parked standalone `warden-sign` AppRole as a T02 break-glass +path. + +- Normal operation uses the railiance-platform credential broker and short-lived + `warden-sign` child token. +- Broker/issuer recovery uses an attended OIDC platform operation. +- A sealed or integrity-compromised OpenBao is recovered by the Shamir + trust-root; another AppRole cannot bypass the seal. +- Placing standing AppRole material outside the broker expands credential + custody without improving root recovery. + +The AppRole dry-run in SECRETS-WP-0004 remains useful negative evidence: its +capability set is narrow. It is not apply authorization. A separately approved +ops-bridge unattended-signing design may re-evaluate it under its own workplan; +that service-access question is outside T02 and does not create recovery +authority. + +## Evidence and owner surfaces + +- Current barrier/re-entry evidence: `railiance-master` RMASTER-WP-0020 and + `docs/evidence/openbao-isolated-restore-2026-08-03.json` +- Authoritative execution and recovery runbook: + `railiance-platform/docs/openbao.md` +- Current coordinated recovery gates: + `railiance-platform/docs/railiance01-coordinated-reboot.md` +- Emergency evidence contract and validator: + `railiance-platform/docs/openbao-emergency-drill-evidence.example.json` and + `make openbao-validate-emergency-evidence` +- Soft-lockdown policy and proof: railiance-platform RAILIANCE-WP-0022 and + ops-warden `scripts/check_agent_read_boundary.py` +- Warden-sign recovery input: secrets-engine SECRETS-WP-0004 and + `workplans/ADHOC-2026-08-11.md` T03 diff --git a/registry/generated/high-risk-data-paths.yaml b/registry/generated/high-risk-data-paths.yaml index 0c3bf94..28602e2 100644 --- a/registry/generated/high-risk-data-paths.yaml +++ b/registry/generated/high-risk-data-paths.yaml @@ -10,11 +10,11 @@ # declares it, and is null where the field set has not been established -- # null means unknown, never 'one field'. -generated_at: "2026-08-22T16:46:29Z" +generated_at: "2026-08-22T18:21:24Z" source: ops-warden/registry/routing/catalog.yaml -catalog_revision: "7ce58ae638b89ef07340a4dd72c80ec34fc35c78" -catalog_revision_date: "2026-08-22T15:36:37+02:00" -catalog_dirty: true +catalog_revision: "8280c0b7b7f1e134be29d64bf24483247932c661" +catalog_revision_date: "2026-08-22T19:08:21+02:00" +catalog_dirty: false high_risk_lane_count: 20 concrete_path_count: 14 diff --git a/workplans/WARDEN-WP-0027-credential-governance-lockdown.md b/workplans/WARDEN-WP-0027-credential-governance-lockdown.md index f0ded6f..ffe2354 100644 --- a/workplans/WARDEN-WP-0027-credential-governance-lockdown.md +++ b/workplans/WARDEN-WP-0027-credential-governance-lockdown.md @@ -4,13 +4,13 @@ type: workplan title: "Tamper-resistant credential governance + mass rotation/lockdown (Strand B)" domain: infotech repo: ops-warden -status: backlog +status: active owner: codex topic_slug: custodian planning_priority: medium planning_order: 27 created: "2026-07-16" -updated: "2026-08-15" +updated: "2026-08-22" state_hub_workstream_id: "7d697c52-766a-4562-b2ad-a722880bcdcb" --- @@ -27,20 +27,19 @@ Strand A makes accidental disclosure structurally hard and gives every lane layer: turning that advisory guidance into one-command action and hardening policy governance against silent drift or malicious change. -## Status: backlog (captured, not scheduled) +## Status: active, narrowly on T02 -Tasks are **`cancel`** (deferred with the workplan, not abandoned) so hub -consistency C-23 does not force `active`. On activation: set workplan to -`ready`/`active` and re-open tasks as `todo`/`progress`. +Activated by the operator on 2026-08-22 after the second activation gate became +concrete. `RAILIANCE-WP-0024-T03` now requires an approved recovery window, +fresh encrypted Raft snapshot evidence, provider-console access, named abort +authority, and the live **2-of-3 Shamir quorum** before a coordinated reboot. +That is fleet policy requiring a designed break-glass path, not speculative +heavyweight machinery. -Frontmatter `status: backlog` as of 2026-07-17 (Strand A / WP-0026 and tenant -custody WP-0028 are finished; no activation gate has fired). Tasks remain -`todo` (not `wait`/`progress`) so hub consistency **C-23** does not force the -workplan back to `active`. This is deliberately **not `ready`**. It carries -real cost and blast radius (break-glass re-key, trust-root design) that is not -justified until a concrete trigger appears. See **Activation gate** below. -Nothing here is implemented until the gate is met and Bernd promotes it to -`ready` (then move tasks `todo` → `progress` as work starts). +Activation is deliberately narrow. No mass-disclosure incident triggers T01, +and no fleet policy currently mandates T03's signed policy-manifest reconcile. +Those tasks remain `cancel`; cancellation here continues to mean deferred, not +abandoned. T02 alone is `progress`. ## Activation gate (promote to `ready` only when ≥1 holds) @@ -89,7 +88,7 @@ each verified capabilities-safe, taint cleared only on success. ```task id: WARDEN-WP-0027-T02 -status: cancel +status: progress priority: medium state_hub_task_id: "9d004d8f-6215-4178-bd13-5785d24fd152" ``` @@ -117,6 +116,35 @@ host) are in `workplans/ADHOC-2026-08-11.md` T03 (ad-hoc **finished** 2026-08-15 question lives here now); secrets-engine was told to stop holding apply readiness until this task or the ops-bridge cutover fires (msg `863c7b57`). +**Rebaselined 2026-08-22.** The July description predates the authoritative +OpenBao migration. The current barrier is a rotated **2-of-3**, not the +aspirational 3-of-5 value still present in ops-warden's legacy posture +descriptor. `RMASTER-WP-0020` records two attended restart/unseal cycles on +2026-08-03 with shares supplied through hidden prompts, matching inventory, +audit continuity, exact-path read, and sibling denial. That is valid rehearsal +evidence for re-entry, but it is not misreported as a current production +emergency-seal drill. + +The soft half is also already live: `RAILIANCE-WP-0022` reports total concrete +high-risk path coverage and a dedicated coding-agent AppRole proving deny-wins +without reading a secret value. ops-warden consumes that owner control through +`scripts/check_agent_read_boundary.py`; it does not take ownership of the live +OpenBao policy. + +The consumer contract and remaining acceptance gate are now documented in +`docs/credential-governance-break-glass.md`. One attended production emergency +seal/unseal drill remains. It must use railiance-platform's evidence template +and validator, have snapshot/quorum/console/driver/abort receipts before the +seal hold point, and be executed by the platform owner—not by a coding agent. + +**Parked AppRole disposition:** do not unpark the standalone `warden-sign` +AppRole for T02 break-glass. The normal broker remains autonomous; an issuer +failure deliberately crosses into attended OIDC and, below that, the 2-of-3 +platform trust-root. A standing AppRole placed outside the broker would weaken +that boundary and still would not recover a sealed OpenBao. A separately +approved ops-bridge unattended-signing design may re-evaluate the narrow +AppRole under its own workplan; that is service access, not recovery authority. + ## Task: Tamper-evident policy governance + reconcile ```task @@ -144,6 +172,7 @@ manifest, and an attended reconcile can restore it. - `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 (ad-hoc finished - 2026-08-15); un-parks on this workplan's break-glass task or the ops-bridge + 2026-08-15); T02 resolves it as unsuitable for break-glass, while a separately + approved ops-bridge unattended-signing design may still re-evaluate it cert_command cutover - `secrets-engine` `SECRETS-WP-0004` — the parked AppRole apply/handoff