diff --git a/WORK-RECORDS.md b/WORK-RECORDS.md index 3b8aad2..60aee29 100644 --- a/WORK-RECORDS.md +++ b/WORK-RECORDS.md @@ -51,9 +51,10 @@ | workplan | RPF-WP-0069 | active | — | workplans/RPF-WP-0069-bounded-executor-lanes.md | | workplan | RPF-WP-0070 | finished | — | workplans/RPF-WP-0070-mas-evidence-recovery.md | | workplan | RPF-WP-0071 | backlog | — | workplans/RPF-WP-0071-attended-credential-rotation-lane.md | -| workplan | RPF-WP-0072 | backlog | — | workplans/RPF-WP-0072-audit-core-recovery-compatibility.md | +| workplan | RPF-WP-0072 | active | — | workplans/RPF-WP-0072-audit-core-recovery-compatibility.md | | workplan | RPF-WP-0073 | blocked | — | workplans/RPF-WP-0073-phase-b-contained-openbao-restore.md | | workplan | RPF-WP-0074 | active | — | workplans/RPF-WP-0074-workstation-disk-capacity.md | +| workplan | RPF-WP-0075 | proposed | — | workplans/RPF-WP-0075-net-kingdom-identity-scaleway-secondary.md | | task | RPF-WP-ADHOC-2026-10-10-T01 | done | — | workplans/ADHOC-2026-10-10.md | | task | RPF-WP-ADHOC-2026-10-11-T01 | done | — | workplans/ADHOC-2026-10-11.md | | task | RPF-WP-ADHOC-2026-10-11-T02 | done | — | workplans/ADHOC-2026-10-11.md | @@ -253,6 +254,7 @@ | task | RPF-WP-0074-T03 | todo | — | workplans/RPF-WP-0074-workstation-disk-capacity.md | | task | RPF-WP-0074-T04 | todo | — | workplans/RPF-WP-0074-workstation-disk-capacity.md | | task | RPF-WP-0074-T05 | todo | — | workplans/RPF-WP-0074-workstation-disk-capacity.md | +| task | RPF-WP-0075-T01 | todo | — | workplans/RPF-WP-0075-net-kingdom-identity-scaleway-secondary.md | | intake | RPF-IN-0001 | closed | — | intakes/intakes.md | | intake | RPF-IN-0002 | open | — | intakes/intakes.md | | intake | RPF-IN-0003 | open | — | intakes/intakes.md | diff --git a/credential-change-requests/CCR-2026-0050-flex-auth-envelope-signing.yaml b/credential-change-requests/CCR-2026-0050-flex-auth-envelope-signing.yaml index 7ea8138..3c32cfb 100644 --- a/credential-change-requests/CCR-2026-0050-flex-auth-envelope-signing.yaml +++ b/credential-change-requests/CCR-2026-0050-flex-auth-envelope-signing.yaml @@ -5,7 +5,7 @@ request_type: workload-kv-read title: Retained flex-auth lifecycle PDP Ed25519 seed ESO read lane status: proposed created: '2026-10-16' -updated: '2026-10-21' +updated: '2026-11-07' requester: agent: railiance-platform reason: CUST-WP-0080 / RPF-WP-0035-T12 / FLEX-WP-0024-T06 source proposal. Exact @@ -32,6 +32,9 @@ review: - reviewer: railiance-platform-owner (agent railiance-platform, claude) decision: approved comment: "2026-10-21 runbook review: docs/runbooks/flex-auth-envelope-signing-attended-creation.md prepared. Secrets condition 1 is met for kid/public key/fingerprint/kv_version/source/image hashes by deriving the consumer receipt from the writer receipt (no KV read); the evaluator/mode/policy_package/policy_version/policy_package_digest fields are not in the writer receipt and must come from Access's published pin. Review-scope digest no longer binds expires_at so owner reviews can precede the 120 s window. Pending: cluster-runtime-storage-owner (railiance-cluster, requested f8b4b229), founder. Nothing executed." + - reviewer: founder (Bernd Worsch, decision 18731e84) + decision: approved + comment: "Recorded 2026-11-07 from the resolved State Hub decision 18731e84 (decided 2026-10-21, rationale starts APPROVE). Scope approval only. Execution still needs the cluster-runtime-storage-owner review, and each live change still needs the founder's go at the time. Status stays proposed: sync-decision would mark this workload-kv-read CCR approved before that review. Nothing executed." target: domain: infotech tenant: platform diff --git a/docs/credential-lane-designs/bounded-executor.md b/docs/credential-lane-designs/bounded-executor.md index d7de9dc..721bb3c 100644 --- a/docs/credential-lane-designs/bounded-executor.md +++ b/docs/credential-lane-designs/bounded-executor.md @@ -87,8 +87,9 @@ Shape (as `docs/credential-lane-designs/factory-audit-senders-review.md`): `nk-bounded-executor`, `tenant:platform`, write true, read false, `evidence_kind: load-bearing`, `secret_policy: redact`); no existing sender changes; - exact-path policy, Kubernetes role for `external-secrets/external-secrets` only, ClusterSecretStore - restricted to namespace `sso`; ExternalSecret into `sso/nk-bind-executor-audit` key `audit-token`, - mounted as a file in the executor pod; + restricted to namespace `sso`; ExternalSecret into `sso/bounded-executor-tokens` key `audit-core`, + mounted as a file in the executor pod. CCR-2026-0063 settled this name on 2026-11-04. + The earlier `sso/nk-bind-executor-audit` key `audit-token` is not the delivery; - coding-agent fence on the new data and metadata paths. The bearer lets the executor append its own receipts only. It is not an OpenBao identity. The ESO diff --git a/docs/openbao-isolated-restore.md b/docs/openbao-isolated-restore.md index 15875ca..8d93c8d 100644 --- a/docs/openbao-isolated-restore.md +++ b/docs/openbao-isolated-restore.md @@ -55,6 +55,10 @@ Readback is metadata only. The allow-list in `ALLOWED_READS` contains no | --- | --- | --- | | `auth_mount_keycape_services` | `sys/auth` | type `jwt` | | `auth_mount_netkingdom` | `sys/auth` | type `oidc`/`jwt` | + +The OIDC mount `auth/keycape` is not in this inventory. The founder disabled +it on 2026-11-07. Do not add it. `auth/keycape-services` is the separate JWT +mount and stays. | `kv_mount_platform` | `sys/mounts` | type `kv`, version 2 | | `keycape_services_config` | `auth/keycape-services/config` | `openbao/auth/keycape-services-config.json` | | `secrets_engine_jwt_role` | `auth/keycape-services/role/secrets-engine-openbao` | `openbao/auth/secrets-engine-jwt-role.json` | diff --git a/docs/openbao.md b/docs/openbao.md index f72c0aa..93bd050 100644 --- a/docs/openbao.md +++ b/docs/openbao.md @@ -650,9 +650,12 @@ returns through the same local tunnel to: http://127.0.0.1:18200/ui/vault/auth/netkingdom/oidc/callback ``` -The legacy `keycape` mount remains a compatibility alias for existing -operator notes and CLI experiments. The preferred browser mount is -`netkingdom`. +The browser mount is `netkingdom`. The legacy `auth/keycape` OIDC mount was a +compatibility alias. The founder disabled it on 2026-11-07 (NK-WP-0054-T04, +receipt status `disabled_verified`). It is not declared. Do not enable it on +restore or re-apply. The KeyCape client `openbao-admin` stays, because +`auth/netkingdom` uses it. The JWT mount `auth/keycape-services` is a different +mount and stays declared. The browser callback URI must be present in both: @@ -668,9 +671,8 @@ Declared state of the administrator login (verified live 2026-09-23, `configure-openbao-oidc.sh` no longer writes the role. The retired `bao.coulomb.social` callbacks were pruned on 2026-09-23 (`docs/evidence/2026-09-24-platform-admin-callback-prune.json`). -- OIDC mount config: `openbao/auth/netkingdom-oidc-config.json` and - `openbao/auth/keycape-oidc-config.json`, owned by railiance-platform. The - compatibility `oidc_client_secret` is not declared. +- OIDC mount config: `openbao/auth/netkingdom-oidc-config.json`, owned by + railiance-platform. The `oidc_client_secret` is not declared. - policies `openbao/policies/platform-admin.hcl` and `openbao/policies/operator-custody.hcl`, plus the built-in `default` (`token_no_default_policy: false`). `default` grants `auth/token/revoke-self` @@ -679,10 +681,6 @@ Declared state of the administrator login (verified live 2026-09-23, `scripts/openbao-platform-admin-check.sh --receipt `. Run it through `scripts/openbao-attended-exec.py`. It only reads. -If the compatibility alias is kept enabled, also keep -`http://127.0.0.1:18200/ui/vault/auth/keycape/oidc/callback` in the -KeyCape client and `auth/keycape/role/platform-admin`. - Use the browser UI for metadata inspection and attended operator workflows. Do not use the OpenBao root token through the browser UI. Do not copy secret values, Inter-Hub keys, unseal shares, root tokens, OIDC client secrets, or diff --git a/openbao/auth/keycape-oidc-config.json b/openbao/auth/keycape-oidc-config.json deleted file mode 100644 index 0f1d01e..0000000 --- a/openbao/auth/keycape-oidc-config.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "_note": "Declared from attended read 2026-09-23 (docs/evidence/2026-09-24-platform-admin-callback-prune.json). oidc_client_secret is a KeyCape public-PKCE compatibility value, never returned by OpenBao and deliberately not declared here.", - "bound_issuer": "", - "default_role": "platform-admin", - "jwt_supported_algs": [], - "namespace_in_state": true, - "oidc_client_id": "openbao-admin", - "oidc_discovery_url": "https://kc.coulomb.social", - "oidc_response_mode": "", - "oidc_response_types": [], - "provider_config": {} -} diff --git a/tests/test_flex_auth_signer_native_preparation.py b/tests/test_flex_auth_signer_native_preparation.py index 6c9bc5b..8e302df 100644 --- a/tests/test_flex_auth_signer_native_preparation.py +++ b/tests/test_flex_auth_signer_native_preparation.py @@ -20,12 +20,14 @@ def test_real_schema_and_apply_refusal(): assert any('status, got proposed' in x for x in blockers) assert any('confirmed OpenBao auth binding' in x for x in blockers) assert ccr['access_frontdoor']['resolvable'] is False - # 2026-10-21: scoped owner reviews are recorded (RPF-WP-0035-T14), but the founder and - # cluster-runtime-storage-owner have not approved, so the CCR stays proposed. + # Founder scope approval is recorded from decision 18731e84. The CCR stays + # proposed until cluster-runtime-storage-owner approves. + assert ccr['status']=='proposed' approvers=set(ccr['review']['required_approvers']) for comment in ccr['review']['comments']: role=comment['reviewer'].split(' (')[0] - assert role in approvers and role not in {'founder','cluster-runtime-storage-owner'} + assert role in approvers and role != 'cluster-runtime-storage-owner' + assert any(c['reviewer'].startswith('founder') and c['decision']=='approved' for c in ccr['review']['comments']) # Pure synthetic candidate only: ensure admitted-pattern scope has no latent # schema/applier role/field failures once the real owners eventually approve. admitted=deepcopy(ccr);admitted['status']='approved';admitted['openbao']['auth']['bound_claims_confirmed']=True diff --git a/workplans/RPF-WP-0035-credential-lane-implementation.md b/workplans/RPF-WP-0035-credential-lane-implementation.md index 89d8fc6..f506cd5 100644 --- a/workplans/RPF-WP-0035-credential-lane-implementation.md +++ b/workplans/RPF-WP-0035-credential-lane-implementation.md @@ -8,7 +8,7 @@ status: blocked flavor: implementation owner: codex created: "2026-09-05" -updated: "2026-10-21" +updated: "2026-11-07" related: - RPF-WP-0032 - RPF-WP-0033 @@ -878,8 +878,8 @@ native/adoption obligations. Historical per-step exclusions remain above. id: RPF-WP-0035-T10 status: wait priority: medium -blocked_on: message-from:approval-engine -blocking_reason: "Blue lane under the standing change rule (removing access, with reviewed order, rollback and receipts): executes once approval-engine confirms there is no presenter. No founder window needed." +blocked_on: message-from:key-cape +blocking_reason: "approval-engine confirmed on 2026-10-23 (b3c8e9f9) that there is no presenter. Platform steps 4-5 run after KeyCape proves invalid_client and net-kingdom removes the Deployment env." state_hub_task_id: "af2d4dba-f83a-5819-9a8b-671bae799364" ``` @@ -1414,7 +1414,7 @@ id: RPF-WP-0035-T14 status: wait priority: high needs_human: true -blocking_reason: "Founder resolves decision 18731e84 approving the exact CCR-2026-0050 custody scope (KV document, one CAS0 bootstrap, read policy and ESO role)" +blocking_reason: "Founder approved scope in decision 18731e84 on 2026-10-21. CCR stays proposed until cluster-runtime-storage-owner reviews. Each live change still needs the founder's go." depends_on: [RPF-WP-0035-T12] decision_id: 18731e84-a6ab-4ac5-bf0e-7e7c3a9c4508 state_hub_task_id: "e310197f-d55c-5732-b606-8b0d88a69836" @@ -1444,5 +1444,10 @@ reviews can be given ahead of the 120 s attended window; the expiry check is unchanged. Recorded as a build-mode change in the-custodian `docs/security-close-down-checklist.md`. Nothing generated, written or applied. +2026-11-07: decision 18731e84 is resolved APPROVE. The founder comment is in +the CCR. Status stays `proposed` until cluster-runtime-storage-owner reviews. +`sync-decision` was not run, because this request type would become `approved` +before that review. + Done when: the decision is resolved, `sync-decision` copies it into the CCR, all five dispositions are recorded, and the runbook preconditions hold. diff --git a/workplans/RPF-WP-0038-forgejo-scaleway-primary-coverage.md b/workplans/RPF-WP-0038-forgejo-scaleway-primary-coverage.md index d8a1baa..d6a3646 100644 --- a/workplans/RPF-WP-0038-forgejo-scaleway-primary-coverage.md +++ b/workplans/RPF-WP-0038-forgejo-scaleway-primary-coverage.md @@ -8,7 +8,7 @@ status: blocked flavor: implementation owner: codex created: "2026-09-06" -updated: "2026-10-13" +updated: "2026-11-07" state_hub_workstream_id: "7beec1a7-aa82-5a36-9a66-6b60008a2455" --- @@ -73,13 +73,15 @@ removed. Evidence: `docs/evidence/forgejo-scaleway-restore-2026-09-06.json`. ```task id: RPF-WP-0038-T04 status: wait -blocking_reason: "Durable scheduled caller, verified inventory and quota/retention gates remain open; September 15 prohibits expiration and scheduled secondary cutover." +blocking_reason: "Durable scheduled caller, verified Scaleway inventory and quota/retention gates remain open. The 2026-10-29 founder removal of the Nextcloud forgejo folder lifted the September 15 no-expiry hold for that folder only." priority: high state_hub_task_id: "a4807df0-ec96-58f1-9cbd-42b1dcde0d6f" ``` 2026-10-11: requalified — founder chose prefix .../application-archives/forgejo/, retention 7d+4w+3m via lifecycle, Nextcloud essentials-only secondary. If issuing the prefix-scoped credential needs the founder's Scaleway console or OpenBao login, add one exact command to the attended-window checklist. See the-custodian docs/decisions/2026-10-11-security-unblock-decisions.md (Round 3). +2026-10-29 (net-kingdom f8eae91a): the Backup account was full and the founder removed the contents of the Nextcloud forgejo folder. That lifts the 2026-09-15 no-expiry hold for that folder. Still open here: confirm a verified full archive on Scaleway, switch the scheduled secondary to essentials-only, remote retention for cnpg-option-a uploads, and a Backup-account quota gate. This pass did not read Scaleway or Nextcloud. + Choose an independent archive prefix and confirm storage retention/caller contract, bounded worker credential delivery and multipart transfer/abort. Then retrieve a primary full archive and execute isolated application recovery. diff --git a/workplans/RPF-WP-0066-openbao-durable-audit-snapshots-conformance.md b/workplans/RPF-WP-0066-openbao-durable-audit-snapshots-conformance.md index 1757123..d1b77c5 100644 --- a/workplans/RPF-WP-0066-openbao-durable-audit-snapshots-conformance.md +++ b/workplans/RPF-WP-0066-openbao-durable-audit-snapshots-conformance.md @@ -8,7 +8,7 @@ status: proposed flavor: implementation owner: claude created: "2026-10-27" -updated: "2026-10-27" +updated: "2026-11-07" related: - NK-WP-0055 - RPF-WP-0036 @@ -102,11 +102,13 @@ Needed from audit-core (AUDIT-WP-0013 sender admission): - an acknowledgement and backpressure contract. Correlation: the NetKingdom-owned cross-stream correlation id (NK-WP-0055-T11) has to -reach OpenBao requests. Set a request header such as `X-Correlation-Id`. If the -listener allows it, record it through the auth mount `audit_non_hmac_request_keys` / -`passthrough_request_headers` or the listener header settings. Otherwise derive it from -the OIDC `jti`/session claim in entity metadata. Verify which of these OpenBao records -unhashed without exposing a secret. +reach OpenBao requests. NetKingdom answered on 2026-10-27 (hub message 578667ff, +commit 169c938): W3C `traceparent`, no custom header, and the id is not a token +claim. The chart pins OpenBao 2.5.4. OpenBao 2.5 documents +`sys/config/auditing/request-headers/:name` with an `hmac` flag +(https://openbao.org/api-docs/system/config-auditing/). That is the API their +proposal names. Enabling it on the live file device is a separate reviewed +change and is not done. The audit-core sender contract below is still open. **Done when:** a written contract exists in both repos, and NetKingdom's correlation-id definition is cited. diff --git a/workplans/RPF-WP-0072-audit-core-recovery-compatibility.md b/workplans/RPF-WP-0072-audit-core-recovery-compatibility.md index 4929fd6..d989ebb 100644 --- a/workplans/RPF-WP-0072-audit-core-recovery-compatibility.md +++ b/workplans/RPF-WP-0072-audit-core-recovery-compatibility.md @@ -4,12 +4,12 @@ type: workplan title: "Check the audit-core receiver against audit-core's own recovery-compatibility declaration" domain: financials repo: railiance-platform -status: backlog +status: active flavor: implementation owner: claude-code topic_slug: railiance-platform created: "2026-11-03" -updated: "2026-11-03" +updated: "2026-11-07" related: - RPF-WP-0015 - RAILIANCE-WP-0024 @@ -38,8 +38,14 @@ priority: medium state_hub_task_id: "39998c0f-3f13-562a-aba0-4de8ff15cf49" ``` -Start only after audit-core accepts the proposal and publishes the -declaration; until then this plan stays in the backlog. Replace +Audit-core accepted on 2026-11-07 (hub message 281acfb1, declaration in +audit-core 9a65fdc). The digest to accept is +`sha256:6600d4a6b96e552052687f41bfce8806c092f9451c4ed23e0f350d95ad3dff48` +(source d984ff0, audit-core d0a4bcf). `0c7e33b6` was superseded before apply. +The preflight still pins `5f3d01c8`. The switch and the final owner round are +not done. + +Replace `EXPECTED_IMAGE` with a check that both the deployment image and the running pod digest appear in audit-core's declaration, read from a reviewed path and revision. The check fails closed when the digest is missing, the file is diff --git a/workplans/RPF-WP-0075-net-kingdom-identity-scaleway-secondary.md b/workplans/RPF-WP-0075-net-kingdom-identity-scaleway-secondary.md new file mode 100644 index 0000000..4b2f32b --- /dev/null +++ b/workplans/RPF-WP-0075-net-kingdom-identity-scaleway-secondary.md @@ -0,0 +1,45 @@ +--- +id: RPF-WP-0075 +type: workplan +title: "Second-provider copy of the NetKingdom identity backup bundle" +domain: financials +repo: railiance-platform +status: proposed +flavor: implementation +owner: codex +topic_slug: railiance-platform +created: "2026-11-07" +updated: "2026-11-07" +related: + - NK-WP-0053 + - RPF-WP-0038 +--- + +# RPF-WP-0075 — Scaleway secondary for the NetKingdom identity bundle + +Intake from net-kingdom on 2026-10-29 (hub message 0d576c80), founder decision +e8935fa6 (NK-WP-0053-T03). The planned destination is +`s3://railiance-platform-pg-backup/platform-pg/application-archives/net-kingdom/`, +named in net-kingdom `tools/bootstrap-recovery/identity-backup-profile.json` +as `proposed_destinations.future_secondary`. + +Scope when this leaves `proposed`: a prefix-scoped write credential delivered +like the existing publisher (ExternalSecret, no operator password in the +runtime), lifecycle retention, upload of each bundle with ETag, size and +sha256 readback, and one independent owner retrieval from Scaleway. The G1 +single-provider acceptance holds until 2027-01-31 or until this copy is +proven. NetKingdom adapts its offsite tools after the bucket contract is named. + +No bucket, credential or object was created with this intake. + +## Name the prefix contract and the writer custody + +```task +id: RPF-WP-0075-T01 +status: todo +priority: medium +``` + +Write the bucket contract NetKingdom asked for: prefix, retention, credential +delivery and the readback fields. Keep it proposed until the founder admits +the credential change. Reply already sent: this task id.