From 9b0999fc377ebeb83f66427b2827d2c098681c83 Mon Sep 17 00:00:00 2001 From: tegwick Date: Sat, 17 Oct 2026 11:25:11 +0200 Subject: [PATCH] Record Apps owner review for NK-WP-0048-T16 and plan consumer seams Needs-change verdict on deliver-consumer-secret and hand-over adapters (net-kingdom ff8f597); option C preferred. WP-0016 T02 moves to the platform/workloads/keycape/forgejo custody path; new T05 for the real Apps owner seams. Co-Authored-By: Claude Opus 5.5 Assistant: claude-code Assistant-Model: opus Assistant-Process: 1031639@bnt-lap001 Assistant-Session: e5073fee-f4ae-4fc3-a75a-6c1fc83e0576 --- .custodian-brief.md | 7 ++- WORK-RECORDS.md | 6 +- .../owner-review-railiance-apps.json | 63 +++++++++++++++++++ .../RAPPS-WP-0016-forgejo-netkingdom-login.md | 30 ++++++++- 4 files changed, 101 insertions(+), 5 deletions(-) create mode 100644 docs/evidence/nk48-t16-owner-review/owner-review-railiance-apps.json diff --git a/.custodian-brief.md b/.custodian-brief.md index c76ea12..51265c8 100644 --- a/.custodian-brief.md +++ b/.custodian-brief.md @@ -2,7 +2,7 @@ # Custodian Brief — railiance-apps **Domain:** financials -**Last synced:** 2026-10-11 01:12 UTC +**Last synced:** 2026-10-13 12:02 UTC **State Hub:** http://127.0.0.1:8000 *(adjust if running on a remote machine)* ## Active Workstreams @@ -12,8 +12,11 @@ Progress: 0/4 done | workplan_id: `f6b1d6f6-0abb-5774-87b9-bf3cfb640a3b` **Open tasks:** - ! T01 — Make the local administrator a sealed break-glass `13cd3aec` + *(wait: Needs break-glass in place and the NetKingdom client registered with its secret in custody.)* - ! T02 — Add the NetKingdom authentication source `81f072aa` + *(wait: Linking and team mapping follow a working authentication source.)* - ! T03 — Link accounts and map groups to teams `32c54737` + *(wait: Restricting local password sign-in is a founder decision once NetKingdom sign-in is proven.)* - · Tasks `98004ed0` ### Coulomb-social persistent personal workspace release @@ -31,7 +34,7 @@ Progress: 2/3 done | workplan_id: `c7fdaa7e-cab8-5d1d-86c2-f1aad7927c57` ## Inbox Hygiene -**Stale unread:** 2 message(s) older than 3 day(s) — triage at session start. +**Stale unread:** 4 message(s) older than 3 day(s) — triage at session start. **Missing thread_id:** 4 unread message(s) lack supersession chains. --- diff --git a/WORK-RECORDS.md b/WORK-RECORDS.md index dba8a65..c785214 100644 --- a/WORK-RECORDS.md +++ b/WORK-RECORDS.md @@ -13,7 +13,8 @@ | workplan | RAPPS-WP-0003 | finished | — | workplans/RAPPS-WP-0003-policy-nexus-production-binding.md | | workplan | RAPPS-WP-0014 | blocked | — | workplans/RAPPS-WP-0014-vergabe-invited-pilot.md | | workplan | RAPPS-WP-0015 | active | — | workplans/RAPPS-WP-0015-coulomb-personal-content-release.md | -| workplan | RAPPS-WP-0016 | ready | — | workplans/RAPPS-WP-0016-forgejo-netkingdom-login.md | +| workplan | RAPPS-WP-0016 | active | — | workplans/RAPPS-WP-0016-forgejo-netkingdom-login.md | +| workplan | RAPPS-WP-0017 | finished | — | workplans/RAPPS-WP-0017-reuse-private-reader-release.md | | task | RAPPS-WP-0001-T01 | done | — | workplans/RAPPS-WP-0001-cnpg-backup-scheduledbackup-coverage.md | | task | RAPPS-WP-0001-T02 | done | — | workplans/RAPPS-WP-0001-cnpg-backup-scheduledbackup-coverage.md | | task | RAPPS-WP-0001-T03 | done | — | workplans/RAPPS-WP-0001-cnpg-backup-scheduledbackup-coverage.md | @@ -41,3 +42,6 @@ | task | RAPPS-WP-0016-T02 | wait | — | workplans/RAPPS-WP-0016-forgejo-netkingdom-login.md | | task | RAPPS-WP-0016-T03 | wait | — | workplans/RAPPS-WP-0016-forgejo-netkingdom-login.md | | task | RAPPS-WP-0016-T04 | wait | — | workplans/RAPPS-WP-0016-forgejo-netkingdom-login.md | +| task | RAPPS-WP-0017-T01 | done | — | workplans/RAPPS-WP-0017-reuse-private-reader-release.md | +| task | RAPPS-WP-0017-T02 | done | — | workplans/RAPPS-WP-0017-reuse-private-reader-release.md | +| task | RAPPS-WP-0017-T03 | done | — | workplans/RAPPS-WP-0017-reuse-private-reader-release.md | diff --git a/docs/evidence/nk48-t16-owner-review/owner-review-railiance-apps.json b/docs/evidence/nk48-t16-owner-review/owner-review-railiance-apps.json new file mode 100644 index 0000000..b1ae754 --- /dev/null +++ b/docs/evidence/nk48-t16-owner-review/owner-review-railiance-apps.json @@ -0,0 +1,63 @@ +{ + "schema": "custodian.owner-review.v1", + "review": "NK-WP-0048-T16", + "owner": "railiance-apps", + "reviewed_at": "2026-10-17", + "reviewer": "railiance-apps (Claude Code session, source-only)", + "verdict": "needs-change", + "grants": "nothing; no admission, pin, dispatch or native action", + "request": "the-custodian docs/changes/netkingdom-target-2026-10-17/nk48-t16-owner-review/README.md @ bffeee9", + "frozen_input": { + "repo": "net-kingdom", + "commit": "ff8f597d5f2f32ce8e82e370c0ad43aa98dc31b7", + "files": { + "sso-mfa/k8s/keycape/deliver-consumer-secret-adapter.py": "sha256:d046eed63090d4e0849a931e2650ccfd89d3b686843aed9e5cb35a0e18e513ee", + "sso-mfa/k8s/keycape/handover-adapter.py": "sha256:0efc300a7b2765bce8da140d5c4666d9cb30daf02b4cbf0e0df96cba7c33d026", + "sso-mfa/k8s/keycape/deliver-consumer-secret-adapter.md": "sha256:4662cff37f2a445f450d5d9d9255cd4315f9d4e4a9adde2cb8d52bd8f1f1212b", + "sso-mfa/k8s/keycape/handover-adapter.md": "sha256:9756921a9a51eea3d9b2dd04b9f135bf0712dfe0c0cff638173da85ce7f5ddaa", + "sso-mfa/k8s/keycape/descriptor-composition-1.2.candidate.json": "sha256:745bb053e6776e8b96224563188405920227e4a17d7783ffa6b36c122be41b09" + }, + "hash_check": "both adapter .py hashes equal coordinator-review-r3.json hashes_verified" + }, + "option_preference": { + "choice": "C", + "reason": "Both Apps steps change the production forgejo namespace and stay owner-run with the founder's go per change. Apps does not want Warden to dispatch them; Warden verifying Apps receipts is acceptable. Apps does not object to B for mint-secret, which is Platform's step." + }, + "will_implement": { + "deliver-consumer-secret": { + "answer": "yes, as an owner-run operator path, not a Warden-dispatched one", + "owner_apply": "Commit the consumer ServiceAccount (automount false), SecretStore (serviceAccountRef, audiences [openbao], role workload-kv-read-keycape-forgejo-forgejo) and ExternalSecret (Owner creation, Retain deletion, path workloads/keycape/forgejo, key CLIENT_SECRET only) as manifests in this repo, apply them under RAPPS-WP-0016-T02, and emit the value-free netkingdom.consumer-secret-delivery.v1 receipt from kubectl metadata (uid, created, Ready).", + "owner_remove": "Revert the Forgejo oauth source secret reference first (helm rollback to the noted revision), then remove only the created objects in the order ExternalSecret, SecretStore, ServiceAccount, and report consumer_reference_reverted=true.", + "accepted_as_is": ["receipt schema and per-object metadata", "value-free rule", "created-only rollback", "custody path platform/workloads/keycape/forgejo field CLIENT_SECRET (net-kingdom 074b3a0)"] + }, + "hand-over": { + "answer": "yes, attended (actor human), lane name apps-consumer-handover accepted", + "record_handover": "Receipt store is this repo: a committed evidence file docs/evidence/-forgejo-netkingdom-handover.json; identifier is path@commit; created=false when a file with the same observation digest is already committed.", + "remove_handover": "A revert commit of that evidence file; confirmed only when the revert is on main." + } + }, + "consumer_verification": { + "principle": "Login and group enforcement are observed at the consumer, never inferred from registry CAS, the client registration or the ExternalSecret being Ready.", + "login_verified": "An attended browser sign-in through 'Sign in with netkingdom' on Forgejo by a member of the case access group succeeds, and Forgejo shows the account linked to auth source 'netkingdom' (admin API: user's login_source / external login entry).", + "enforces_groups": "Positive and negative probe: (1) a NetKingdom test user that is not in any case access group is refused or gets no team access; (2) adding that user to the mapped group grants the mapped Forgejo team membership on next sign-in; (3) removing it revokes the team membership. This is the RAPPS-WP-0016-T03 acceptance test.", + "observation_body": "The digest passed to record_handover covers the client_id, the groups probed, the Forgejo user ids and team ids observed, and the timestamps of the three probes. No tokens, cookies or secret values." + }, + "needs_change": [ + { + "file": "sso-mfa/k8s/keycape/handover-adapter.py", + "finding": "verify_consumer returns bare booleans (login_verified, enforces_groups). The adapter cannot tell an observed consumer result from a self-asserted one.", + "requested": "Require the verifier result to carry the observation evidence (or its authenticated identifier) for a positive login, a negative non-member probe and an add/remove membership probe, and include that in the digest." + }, + { + "file": "sso-mfa/k8s/keycape/deliver-consumer-secret-adapter.py", + "finding": "Descriptor actor is 'agent' for a step that changes a production consumer namespace. Under railiance-apps rules, production-touching applies need the founder's go per change.", + "requested": "Actor 'human' (attended), or an explicit per-change founder approval reference in the binding. Lane name consumer-owner-deployment is otherwise accepted." + } + ], + "carried_limits": { + "5_injected_stand_ins": "Accepted as a known limit; turned into task RAPPS-WP-0016-T05 (real Apps owner_apply/owner_remove, verifier and receipt store).", + "6_mint_then_revoke_failure": "Platform-owned; no Apps position.", + "others": "1-4 are net-kingdom / ops-warden concerns; Apps accepts them as known limits for its two steps." + }, + "not_reviewed": ["mint-secret", "deliver-secret", "ensure-groups", "bind-env", "register-client", "composer", "checker artifact", "kernel admission"] +} diff --git a/workplans/RAPPS-WP-0016-forgejo-netkingdom-login.md b/workplans/RAPPS-WP-0016-forgejo-netkingdom-login.md index 2b2bd70..85f518f 100644 --- a/workplans/RAPPS-WP-0016-forgejo-netkingdom-login.md +++ b/workplans/RAPPS-WP-0016-forgejo-netkingdom-login.md @@ -74,8 +74,14 @@ state_hub_task_id: "13cd3aec-c87d-5d3f-a421-39d8ff131edd" ### T02 — Add the NetKingdom authentication source -- an ExternalSecret delivering the `forgejo` client secret from OpenBao (path - from KEY-WP-0038-T02) to a Secret in the `forgejo` namespace +- an ExternalSecret delivering the `forgejo` client secret from OpenBao to a + Secret in the `forgejo` namespace. Custody path is + `platform/workloads/keycape/forgejo`, field `CLIENT_SECRET`, read through role + `workload-kv-read-keycape-forgejo-forgejo` (net-kingdom 074b3a0; replaces the + earlier `platform/workloads/forgejo/netkingdom-oidc-client` proposal). The + SA/SecretStore/ExternalSecret shape follows the NK-WP-0048 + `deliver-consumer-secret` receipt contract + (`docs/evidence/nk48-t16-owner-review/owner-review-railiance-apps.json`) - `gitea.oauth`: name `netkingdom` (must match the redirect URI registered in key-cape), provider `openidConnect`, auto-discovery from `https://kc.coulomb.social/.well-known/openid-configuration`, scopes @@ -130,6 +136,26 @@ decides whether local password sign-in is turned off for everyone except break-glass. This is not required to close the forge; it is the next tightening step, taken separately. +```task +id: RAPPS-WP-0016-T05 +status: wait +depends_on: [RAPPS-WP-0016-T02] +blocking_reason: "Waits for the NK-WP-0048-T16 option decision and net-kingdom's answer to the Apps needs-change record." +priority: medium +``` + +### T05 — Apps owner seams for NK-WP-0048 consumer steps + +Implement the real Apps capabilities behind the `deliver-consumer-secret` and +`hand-over` adapters, as owner-run paths (option C): `owner_apply` / +`owner_remove` emitting `netkingdom.consumer-secret-delivery.v1` receipts from the +T02 objects; a consumer verifier that observes Forgejo sign-in and the T03 +positive/negative group probes; and a committed-evidence hand-over receipt store. +See the owner-review record for the contract. + +Acceptance: receipts produced from the live T02/T03 run validate against the +adapters' checks with no value-bearing keys. + ## Also in scope: stale node credential The k3s `registries.yaml` on railiance01 still holds a login for the frozen Gitea