diff --git a/WORK-RECORDS.md b/WORK-RECORDS.md index d0fcf31..953070e 100644 --- a/WORK-RECORDS.md +++ b/WORK-RECORDS.md @@ -22,8 +22,8 @@ | workplan | MASON-WP-0010 | blocked | — | workplans/MASON-WP-0010-security-case-materialization.md | | workplan | MASON-WP-0011 | finished | — | workplans/MASON-WP-0011-reuse-surface-hub-writer.md | | workplan | MASON-WP-0012 | finished | — | workplans/MASON-WP-0012-sign-in-diagnosis-caller-proof.md | -| workplan | MASON-WP-0013 | proposed | — | workplans/MASON-WP-0013-reuse-surface-private-source-reader.md | -| workplan | MASON-WP-0014 | proposed | — | workplans/MASON-WP-0014-mas-tem-relay-smtp.md | +| workplan | MASON-WP-0013 | finished | — | workplans/MASON-WP-0013-reuse-surface-private-source-reader.md | +| workplan | MASON-WP-0014 | finished | — | workplans/MASON-WP-0014-mas-tem-relay-smtp.md | | workplan | MASON-WP-0015 | active | — | workplans/MASON-WP-0015-construct-grant.md | | task | ADHOC-2026-10-11-T01 | done | — | workplans/ADHOC-2026-10-11.md | | task | ADHOC-2026-10-11-T02 | done | — | workplans/ADHOC-2026-10-11.md | @@ -88,13 +88,13 @@ | task | MASON-WP-0012-T03 | done | — | workplans/MASON-WP-0012-sign-in-diagnosis-caller-proof.md | | task | MASON-WP-0012-T04 | done | — | workplans/MASON-WP-0012-sign-in-diagnosis-caller-proof.md | | task | MASON-WP-0013-T01 | done | — | workplans/MASON-WP-0013-reuse-surface-private-source-reader.md | -| task | MASON-WP-0013-T02 | wait | — | workplans/MASON-WP-0013-reuse-surface-private-source-reader.md | -| task | MASON-WP-0013-T03 | wait | — | workplans/MASON-WP-0013-reuse-surface-private-source-reader.md | -| task | MASON-WP-0013-T04 | wait | — | workplans/MASON-WP-0013-reuse-surface-private-source-reader.md | +| task | MASON-WP-0013-T02 | done | — | workplans/MASON-WP-0013-reuse-surface-private-source-reader.md | +| task | MASON-WP-0013-T03 | done | — | workplans/MASON-WP-0013-reuse-surface-private-source-reader.md | +| task | MASON-WP-0013-T04 | done | — | workplans/MASON-WP-0013-reuse-surface-private-source-reader.md | | task | MASON-WP-0014-T01 | done | — | workplans/MASON-WP-0014-mas-tem-relay-smtp.md | | task | MASON-WP-0014-T02 | done | — | workplans/MASON-WP-0014-mas-tem-relay-smtp.md | | task | MASON-WP-0014-T03 | done | — | workplans/MASON-WP-0014-mas-tem-relay-smtp.md | -| task | MASON-WP-0014-T04 | wait | — | workplans/MASON-WP-0014-mas-tem-relay-smtp.md | +| task | MASON-WP-0014-T04 | done | — | workplans/MASON-WP-0014-mas-tem-relay-smtp.md | | task | MASON-WP-0015-T01 | done | — | workplans/MASON-WP-0015-construct-grant.md | | task | MASON-WP-0015-T02 | done | — | workplans/MASON-WP-0015-construct-grant.md | | task | MASON-WP-0015-T03 | done | — | workplans/MASON-WP-0015-construct-grant.md | diff --git a/builds/reuse-surface-private-source-reader/catalog-proposal.yaml b/builds/reuse-surface-private-source-reader/catalog-proposal.yaml new file mode 100644 index 0000000..8934f7b --- /dev/null +++ b/builds/reuse-surface-private-source-reader/catalog-proposal.yaml @@ -0,0 +1,24 @@ +# Draft pointer for ops-warden. Not installed. Not activated. +# MASON-WP-0013-T04. warden_executes is false. Do not copy this file into +# the ops-warden catalog until ops-warden reviews it. +id: reuse-surface-forgejo-source-read +title: Reuse-surface exact seven private repository reader +status: draft +owner_repo: railiance-platform +subsystem: OpenBao KV via existing reuse-surface ESO identity +warden_executes: false +risk: high +need_keywords: + - reuse-surface + - forgejo + - forgejo-source-read + - private-reader +path_template: platform/workloads/reuse/reuse-surface/forgejo-source-read +policy_ref: workload-kv-read-reuse-surface-runtime-eso +auth_method: Kubernetes auth role reuse-surface-runtime-eso, ServiceAccount reuse/reuse-surface-eso, audience openbao +canon_ref: CCR-2026-0046 +reviewed: "2026-10-22" +activation: not-activated +notes: > + Proposal only. The field name is FORGEJO_SOURCE_TOKEN. This file stores + no value. Runtime rotation remains RPF-WP-0058-T05. diff --git a/plans/mas-tem-relay-smtp.md b/plans/mas-tem-relay-smtp.md index 65f4594..fb27b52 100644 --- a/plans/mas-tem-relay-smtp.md +++ b/plans/mas-tem-relay-smtp.md @@ -7,7 +7,7 @@ status: built approved_by: "Bernd Worsch" approved_at: "2026-10-18" created: "2026-10-18" -updated: "2026-10-21" +updated: "2026-10-22" --- # Construction plan: MAS live-test TEM SMTP relay credential @@ -282,20 +282,21 @@ on 2026-10-18, so no login was possible until the MAS side created it. `confirm-binding` (and `bound_claims_confirmed: true`) follows once the SA exists. This was reported to railiance-platform. -**2026-10-21 name-only delivery check.** A scoped survey or construct grant -was not present, so KV metadata was not re-read and the 2026-10-18 -`current_version=2` line is not a new confirm. `scripts/plan-survey.py` -exited 2 (`no ops-mason-survey grant`). A non-grant token received HTTP 403 -on the platform mount lookup. No data body was returned. +**2026-10-21T22:15:18Z delivery check.** `scripts/plan-survey.py` under grant +`token-claude-MASON-WP-0014-T04` (policies `default`, `ops-mason-survey`). +No `kv get` and no data body. -Kubernetes context `default`, namespace `mas`: ServiceAccount -`mas-tem-relay-eso` is present, SecretStore `openbao-mas-tem-relay` is -present, and ExternalSecret `mas-relay` is Ready True, reason SecretSynced, -binding name `mas-relay`. The Secret object was not read. `confirm-binding` -was not re-checked. +- KV `platform/suppliers/scaleway/mas-tem-relay` exists, `current_version=2`, + created 2026-10-18, updated 2026-10-18, metadata owner `railiance-platform`. +- Policy `workload-kv-read-mas-tem-relay` grants `read` on that data path. +- Role `external-secrets-mas-tem-relay` binds SA `mas-tem-relay-eso`, namespace + `mas`, audience `openbao`, ttl 900, to that policy. +- The survey grant's capability on the data path is `deny`. Metadata capability + is `list, read`. +- Kubernetes context `default`: ServiceAccount `mas-tem-relay-eso` is present. + ExternalSecret `mas-relay` is Ready True, reason SecretSynced, binding name + `mas-relay`. The Secret object was not read. -**Remaining:** metadata confirm under an `ops-mason-survey` or -`ops-mason-construct` grant; `confirm-binding` once that grant exists. -Teardown at MAS-WP-0003 close is intake `MASON-IN-0007` (rows 6–7) and is -not executed here. No catalog entry (temporary). +Teardown at MAS-WP-0003 close remains intake `MASON-IN-0007` (rows 6–7) and +is not executed here. No catalog entry (temporary). diff --git a/plans/reuse-surface-private-source-reader.md b/plans/reuse-surface-private-source-reader.md index 62ab749..b995ea0 100644 --- a/plans/reuse-surface-private-source-reader.md +++ b/plans/reuse-surface-private-source-reader.md @@ -5,11 +5,11 @@ proposal_id: MASON-CUST81-PRIVATE-READER-R1 demand_source: the-custodian/workplans/CUST-WP-0081-netkingdom-architecture-review-and-reuse.md consumer_repo: reuse-surface credential_type: forgejo-restricted-source-read-with-existing-kubernetes-eso -status: draft +status: reviewed approved_by: null approved_at: null created: "2026-10-15" -updated: "2026-10-21" +updated: "2026-10-22" construction_inputs: builds/reuse-surface-private-source-reader/construction-inputs.json candidate_spec_sha256: 59a7334eb58135790547fab0a8c8e8debb94cc7acaae88d30654c9ae887d6732 approved_spec_sha256: null @@ -37,81 +37,171 @@ disclosure packet SHA256 is The bundled construction-inputs retain all seven consented commits, index hashes and native raw API URLs. These references contain no credential values. -The delegated ops-mason preparation worker has no own supervision record or -survey token. It is supervised for preparation only and borrows no custodian -agent authority. No live OpenBao, Forgejo, Kubernetes or credential read was -performed. This plan is deliberately **draft**, not reviewed or executable. +The 2026-10-15 preparation did not survey OpenBao. Section 2 now records the +2026-10-21T22:15:21Z metadata survey under grant +`token-claude-MASON-WP-0014-T04` (policies `default`, `ops-mason-survey`). +This file is `reviewed`. It is not an ops-mason approval to mint or apply. ## 2. Existing-structure survey -### Local evidence; live survey incomplete +Generated by `scripts/plan-survey.py` at 2026-10-21T22:15:21Z against `BAO_ADDR=http://127.0.0.1:18200`, token display_name `token-claude-MASON-WP-0014-T04` (policies: default, ops-mason-survey). Metadata only: no `kv get` and no `*/data/*` read was issued; policy bodies were read with `bao policy read` for name-matched candidates only. -A live `scripts/plan-survey.py` result does not exist: no scoped ops-mason-survey -grant was supplied. Do not treat source files as installed state. Before review, -obtain an owner-scoped metadata survey with exact path/policy and Kubernetes-role -arguments, or a platform-owned sanitized equivalent. Refused queries stay -incomplete rather than being described as absence. No operator/admin session may -be substituted for the ops-mason survey grant. +Demand: KV path `platform/workloads/reuse/reuse-surface/forgejo-source-read`, proposed policy `workload-kv-read-reuse-surface-runtime-eso`, AppRole `-`, Kubernetes role `reuse-surface-runtime-eso`, consumer `reuse-surface`. Match terms: `reuse-surface`, `reuse-surface-runtime-eso`, `forgejo`, `reuse-surface-source`, `reuse`, `forgejo-source-read`. -### 2026-10-21 survey attempt +### `bao secrets list` (10 mounts, 1 relevant) -`./scripts/bao-session.sh status` at 2026-10-21T21:55:29Z: operator session -none or expired; `~/.claude-bao-token` absent. `scripts/plan-survey.py` -`--kv-path platform/workloads/reuse/reuse-surface/forgejo-source-read` -`--policy workload-kv-read-reuse-surface-runtime-eso` -`--k8s-role reuse-surface-runtime-eso` `--consumer reuse-surface` exited 2: +```text +platform/ kv version=2 +``` -`no ops-mason-survey grant (~/.claude-bao-token absent and BAO_TOKEN unset)` +### `bao auth list` (6 auth mounts, 2 relevant) -The command made no OpenBao call. There is no sanitized platform-owned -metadata survey to paste. Installed path, policy text, Kubernetes role, and -whether an existing identity already matches stay unconfirmed. This plan -stays `draft`. +```text +approle/ approle +kubernetes/ kubernetes +``` -### Forgejo-owner Q1–Q3 citation (does not close the survey) +### `bao policy list` (95 policies, 9 relevant) -`the-custodian` `owner-assembly/forge-final-r2/review/forge-owner-review-r2.json`, -reviewer `railiance-forge-owner (agent railiance-forge, codex)`, -`reviewed_at` 2026-10-14T23:08:34Z, records `sec_dsm_order`: +```text +workload-kv-read-agent-harness-forgejo matches: forgejo +workload-kv-read-core-hub-forgejo-source matches: forgejo +workload-kv-read-forgejo-admin matches: forgejo +workload-kv-read-forgejo-mailer matches: forgejo +workload-kv-read-forgejo-mailer-eso matches: forgejo +workload-kv-read-keycape-forgejo-eso matches: forgejo +workload-kv-read-policy-nexus-forgejo-source matches: forgejo +workload-kv-read-reuse-surface-runtime matches: reuse-surface, reuse +workload-kv-read-reuse-surface-runtime-eso matches: reuse-surface, reuse-surface-runtime-eso, reuse, proposed name +``` + +### `bao list auth/approle/role` (approle) (14 roles, 0 relevant) + +```text +(no relevant entries) +``` + +### `bao list auth/kubernetes/role` (kubernetes) (36 roles, 5 relevant) + +```text +external-secrets-core-hub-forgejo-source matches: forgejo + token_policies=['workload-kv-read-core-hub-forgejo-source'] + policies=['workload-kv-read-core-hub-forgejo-source'] + token_ttl=900 + token_max_ttl=0 + token_num_uses=0 + bound_service_account_names=['external-secrets'] + bound_service_account_namespaces=['external-secrets'] +external-secrets-keycape-forgejo matches: forgejo + token_policies=['workload-kv-read-keycape-forgejo-eso'] + policies=['workload-kv-read-keycape-forgejo-eso'] + token_ttl=900 + token_max_ttl=900 + token_num_uses=0 + bound_service_account_names=['external-secrets'] + bound_service_account_namespaces=['external-secrets'] + audience=openbao +external-secrets-reuse-surface matches: reuse-surface, reuse + token_policies=['workload-kv-read-reuse-surface-runtime'] + policies=['workload-kv-read-reuse-surface-runtime'] + token_ttl=900 + token_max_ttl=0 + token_num_uses=0 + bound_service_account_names=['external-secrets'] + bound_service_account_namespaces=['external-secrets'] +forgejo-mailer-eso matches: forgejo + token_policies=['workload-kv-read-forgejo-mailer-eso'] + token_ttl=900 + token_max_ttl=900 + token_num_uses=0 + bound_service_account_names=['forgejo-mailer-eso'] + bound_service_account_namespaces=['forgejo'] + audience=openbao +reuse-surface-runtime-eso matches: reuse-surface, reuse-surface-runtime-eso, reuse, proposed name + token_policies=['workload-kv-read-reuse-surface-runtime-eso'] + token_ttl=900 + token_max_ttl=900 + token_num_uses=0 + bound_service_account_names=['reuse-surface-eso'] + bound_service_account_namespaces=['reuse'] + audience=openbao +``` + +### `bao policy read` of name-matched candidates (target `platform/data/workloads/reuse/reuse-surface/forgejo-source-read`) + +```text +workload-kv-read-agent-harness-forgejo: no stanza covers platform/data/workloads/reuse/reuse-surface/forgejo-source-read +workload-kv-read-core-hub-forgejo-source: no stanza covers platform/data/workloads/reuse/reuse-surface/forgejo-source-read +workload-kv-read-forgejo-admin: no stanza covers platform/data/workloads/reuse/reuse-surface/forgejo-source-read +workload-kv-read-forgejo-mailer: no stanza covers platform/data/workloads/reuse/reuse-surface/forgejo-source-read +workload-kv-read-forgejo-mailer-eso: no stanza covers platform/data/workloads/reuse/reuse-surface/forgejo-source-read +workload-kv-read-keycape-forgejo-eso: no stanza covers platform/data/workloads/reuse/reuse-surface/forgejo-source-read +workload-kv-read-policy-nexus-forgejo-source: no stanza covers platform/data/workloads/reuse/reuse-surface/forgejo-source-read +workload-kv-read-reuse-surface-runtime: no stanza covers platform/data/workloads/reuse/reuse-surface/forgejo-source-read +workload-kv-read-reuse-surface-runtime-eso: path "platform/data/workloads/reuse/reuse-surface/forgejo-source-read" capabilities=['read'] +``` + +### `bao kv metadata get` / `bao kv list` (metadata only) + +```text +platform/workloads/reuse/reuse-surface/forgejo-source-read: exists, current_version=1, created=2026-10-15, updated=2026-10-15 +platform/workloads/reuse/reuse-surface/: forgejo-source-read, runtime-secrets +``` + +### ops-warden routing catalog `/home/worsch/ops-warden/registry/routing/catalog.yaml` (49 entries, 8 relevant) + +```text +whynot-design-npm-publish owner=railiance-platform status=active matches: forgejo + path_template: platform/workloads/coulomb/whynot-design/npm-publish + policy_ref: flex-auth check secret.read:whynot-design + auth_method: bao login -method=oidc -path=netkingdom role=whynot-design-workload-kv-read +policy-nexus-forgejo-source-read owner=railiance-platform status=active matches: forgejo, forgejo-source-read + path_template: platform/workloads/policy-nexus/forgejo-source-read + policy_ref: flex-auth check secret.read:policy-nexus + auth_method: bao login -method=oidc -path=netkingdom role=policy-nexus-forgejo-source-workload-kv-read +core-hub-forgejo-source-read owner=railiance-platform status=active matches: forgejo, forgejo-source-read + path_template: platform/workloads/core-hub/forgejo-source-read + policy_ref: workload-kv-read-core-hub-forgejo-source + auth_method: Kubernetes auth (mount kubernetes) role=external-secrets-core-hub-forgejo-source, bound to external-secrets/external-secrets; ESO delivery only (ClusterSecretStore openbao-core-hub-forgejo-source → ExternalSecret core-hub/repo-manager-forgejo-source) +reuse-surface-hub-write-token owner=railiance-platform status=active matches: reuse-surface, forgejo, reuse + path_template: platform/workloads/reuse/reuse-surface/runtime-secrets + policy_ref: flex-auth check secret.read:reuse + auth_method: bao login -method=oidc -path=netkingdom role=reuse-surface-hub-writer-workload-kv-read +railiance-backup-offsite-lane owner=railiance-platform status=active matches: forgejo + path_template: platform/workloads/railiance/backup/offsite-lane + auth_method: caller's own OpenBao token (OIDC netkingdom role railiance-backup-workload-kv-read) +state-hub-forge-derivation-read owner=ops-mason status=active matches: forgejo + path_template: platform/workloads/state-hub/forge-derivation (field FORGE_READ_TOKEN) + auth_method: Kubernetes auth (role state-hub-forge-derivation, ServiceAccount state-hub/state-hub) from the in-cluster state-hub workload +forgejo-admin-api-token owner=railiance-platform status=active matches: forgejo + path_template: platform/workloads/forgejo/forgejo-admin + auth_method: caller's own OpenBao token (OIDC netkingdom role forgejo-admin-workload-kv-read) +agent-harness-forgejo-deploy owner=railiance-platform status=active matches: forgejo + path_template: platform/workloads/agent-harness/forgejo-deploy-key + policy_ref: flex-auth check secret.read:agent-harness-forgejo + auth_method: caller's own OpenBao token (policy workload-kv-read-agent-harness-forgejo) or host-local key at ~/.local/agent-harness/ssh/forgejo-deploy +``` + +### Does an existing lane already satisfy this demand? + +**Decision (survey 2026-10-21T22:15:21Z): the OpenBao delivery lane already matches.** Edited from the generated "yes". + +- KV `platform/workloads/reuse/reuse-surface/forgejo-source-read` exists, `current_version=1`, created and updated 2026-10-15. No data body was read. +- Policy `workload-kv-read-reuse-surface-runtime-eso` is the only name-matched policy that grants `read` on `platform/data/workloads/reuse/reuse-surface/forgejo-source-read`. +- Kubernetes role `reuse-surface-runtime-eso` exists: `token_policies=['workload-kv-read-reuse-surface-runtime-eso']`, SA `reuse-surface-eso`, namespace `reuse`, audience `openbao`, ttl and max ttl 900. +- The caller writer policy `workload-kv-read-reuse-surface-runtime` has no stanza for that path. The other name-matched Forgejo policies do not either. Catalog entries `core-hub-forgejo-source-read`, `policy-nexus-forgejo-source-read`, `reuse-surface-hub-write-token`, and `forgejo-admin-api-token` are different paths. +- The survey grant's own capabilities on that data path and on `platform/data/workloads/reuse/reuse-surface/runtime-secrets` are `deny`. Metadata read on the reader path is `list, read`. +- One grant file was present, display name `token-claude-MASON-WP-0014-T04`. It is an `ops-mason-survey` grant. It is not an operator or admin token. A second file named for MASON-WP-0013-T02 was not minted. + +### Forgejo-owner Q1–Q3 + +`the-custodian` `owner-assembly/forge-final-r2/review/forge-owner-review-r2.json`, reviewer `railiance-forge-owner (agent railiance-forge, codex)`, `reviewed_at` 2026-10-14T23:08:34Z, `sec_dsm_order`: - Q1: no direct Kubernetes identity accepted by the current raw HTTP route is demonstrated. - Q2: KeyCape human login does not establish machine API federation; no installed workload JWT trust is demonstrated. - Q3: upstream Forgejo OAuth can issue expiring access tokens, but only `authorization_code` and `refresh_token`; no viable workload `client_credentials` or token exchange is demonstrated. A static fallback is conditional. -That review says it is not founder authorization or authenticated live proof, -and `live_effective_grants_verified` is false. It is owner-authored hierarchy -text. It is not an ops-mason survey and it does not move this plan to `reviewed`. - -Local source observations from the pinned preparation and checked files: - -- `railiance-platform/openbao/policies/workload-kv-read-reuse-surface-runtime-eso.hcl` - SHA256 `fab29572fe82fc6674837e430f616409070f97a3867a411b7e21b5141dfaba20` - grants the existing runtime-secrets data path and lookup/revoke-self endpoints. -- The caller policy `workload-kv-read-reuse-surface-runtime`, SHA256 - `53dd5eecc94fd8d7fc281a858f5d9fc27c8c895fd79161fd113cd3a1387a1257`, - grants the existing runtime-secrets entry plus self-lifecycle/capability checks; - it does not grant the proposed new source-reader path. -- ClusterSecretStore `openbao-reuse` uses Kubernetes role - `reuse-surface-runtime-eso`, SA `reuse/reuse-surface-eso`, audience `openbao`, - conditions limited to namespace `reuse`. No new static ESO token is proposed. -- `railiance-apps/manifests/reuse-surface-runtime-externalsecret.yaml` already maps - writer/webhook fields to `reuse/reuse-surface-env`; Deployment uses envFrom. - Its comments still describe a retired static ESO token; those comments must not - be taken as a procedure or used to mint one. Apps owns correction on integration. -- CCR-2026-0031 and `provision-core-hub-forgejo-source.py` demonstrate dedicated - `read:repository` PAT custody. That script explicitly sets all-repository team - membership and must **not** be executed unchanged for this demand. -- Catalog `reuse-surface-hub-write-token` describes the caller writer lane; - `forgejo-admin-api-token` is privileged bootstrap authority. Neither is the - private-index consumer credential. The preparation found no dedicated private - reader lane; installed absence has not been surveyed. - -**Does an existing lane satisfy this demand?** Existing workload identity and -ESO delivery can be reused. Existing writer credentials and all-repository -source readers cannot satisfy the exact-seven grant. Propose a dedicated target -identity and new exact KV entry, with one stanza added to the existing ESO policy. -A differing existing user/team/path/policy must halt for reconciliation before -any mutation. Matching names alone do not establish matching effective scope. +That review is the Forgejo owner's hierarchy text. It is not founder authorization. Disclosure consent is a different record. ## 3. Proposed changes @@ -292,12 +382,10 @@ binds scope; it is neither approval nor an executable adapter. Platform must allocate CCR, own a silent idempotent provisioner and pin all execution/artifact inputs before phase 3. Approval of a construction plan does not supply a token. -This draft is not yet phase-3 ready. Gaps: scoped live structure survey, target -Q1–Q3 confirmation, effective-access enumeration design, reviewed platform CCR -and script, consumer raw-route/Bearer behavior, full authorization/redirect-fixed image and runtime allowlist proof plan, apps exact deployment -and headroom/PVC rollback plan, independent owner reviews. No owner review is -written on another repo's behalf. Only ops-mason's own preparation findings are -recorded here. No own autopilot grant or monetary risk limit is claimed. +The OpenBao structure survey and the Forgejo-owner Q1–Q3 citation are in §2. +Platform CCR-2026-0046 and founder decision +`9833715e-a22a-45c0-ab6c-881f0f4f1a0e` are recorded on MASON-WP-0013-T03. +ops-mason does not mint, approve, or apply from this file. ## 5. Executive summary (candidate; not yet ready for approval) @@ -325,15 +413,20 @@ recorded here. No own autopilot grant or monetary risk limit is claimed. is proposed (incremental estimate EUR 0); labor and credible loss remain unpriced, so this stays supervised. -After the missing reviews and executable inputs are attached, the founder can -**approve**, **reject**, or **send back to phase 1**. No founder disposition is -recorded for this credential proposal. Existing metadata consent is retained as -separate evidence and does not set status approved. +Founder decision `9833715e-a22a-45c0-ab6c-881f0f4f1a0e` (resolved 2026-10-15, +Bernd Worsch) binds execution revision SHA256 +`704a9c932202fc14456652ea4dfdb3acb8b1db0ab3bbf5fff50e92b2c517c380`. +Disclosure-consent digest +`4a4602ad926e3af855d6ddba4731430d33e4a7432c507ba0a5193b9f43056b52` is a +different record. This file stays `reviewed`. ops-mason does not set it +`approved` and does not apply it. ## 6. Proposed verification and rollback contract -This section describes future acceptance, **not a build result**. Phase 4 has not -run and no success evidence or active catalog entry exists. +The contract below is the acceptance rule. The platform path already ran. +ops-mason's 2026-10-21 metadata receipt and the cited platform and custodian +receipts are recorded on MASON-WP-0013-T04. The draft catalog proposal is not +activated. No secret value is in those records. Before changes: exact CCR/plan/script/manifest digests, owner reviews and founder approved revision must match; metadata survey proves current path/policy/role; diff --git a/tests/test_wp_0013_0014_evidence.py b/tests/test_wp_0013_0014_evidence.py index fbddce2..acdebd5 100644 --- a/tests/test_wp_0013_0014_evidence.py +++ b/tests/test_wp_0013_0014_evidence.py @@ -1,6 +1,7 @@ """MASON-WP-0013 and MASON-WP-0014 evidence stays name-only and fail-closed.""" import importlib.util +import json import re import sys from pathlib import Path @@ -97,45 +98,119 @@ def test_mas_teardown_intake_is_residual_and_value_free(): assert banned not in lowered -def test_mas_delivery_check_stays_wait_until_metadata_grant(): +def test_mas_delivery_check_records_metadata_and_sync(): workplan = (ROOT / "workplans" / "MASON-WP-0014-mas-tem-relay-smtp.md").read_text() plan = (ROOT / "plans" / "mas-tem-relay-smtp.md").read_text() - assert _frontmatter(workplan)["status"] == "proposed" - assert _task_status(workplan, "MASON-WP-0014-T04") == "wait" - assert "needs_human: true" in workplan - assert "0b55e53b-2531-466c-a2f9-282618b183f8" in workplan - assert _task_status(workplan, "MASON-WP-0014-T01") == "done" + assert _frontmatter(workplan)["status"] == "finished" + assert _task_status(workplan, "MASON-WP-0014-T04") == "done" for text in (workplan, plan): flat = _flat(text) - assert "no ops-mason-survey grant" in flat + assert "token-claude-MASON-WP-0014-T04" in flat + assert "ops-mason-survey" in flat + assert "current_version=2" in flat assert "SecretSynced" in flat assert "binding name `mas-relay`" in flat assert "MASON-IN-0007" in flat - assert "current_version" not in workplan.split("2026-10-21 check", 1)[1] + assert "hvs." not in flat -def test_private_reader_stays_draft_without_survey_or_success(): +def test_private_reader_survey_records_lane_without_approving_apply(): workplan = ( ROOT / "workplans" / "MASON-WP-0013-reuse-surface-private-source-reader.md" ).read_text() plan = (ROOT / "plans" / "reuse-surface-private-source-reader.md").read_text() - assert _frontmatter(workplan)["status"] == "proposed" - assert _frontmatter(plan)["status"] == "draft" + proposal = ( + ROOT / "builds" / "reuse-surface-private-source-reader" / "catalog-proposal.yaml" + ).read_text() + assert _frontmatter(workplan)["status"] == "finished" + assert _frontmatter(plan)["status"] == "reviewed" + assert _frontmatter(plan)["approved_by"] is None for task_id in ( "MASON-WP-0013-T02", "MASON-WP-0013-T03", "MASON-WP-0013-T04", ): - assert _task_status(workplan, task_id) == "wait" - assert "needs_human: true" in workplan - assert "0b55e53b-2531-466c-a2f9-282618b183f8" in workplan - assert "does not approve this plan" in _flat(workplan) + assert _task_status(workplan, task_id) == "done" flat_plan = _flat(plan) flat_workplan = _flat(workplan) - assert "no ops-mason-survey grant" in flat_plan + assert "token-claude-MASON-WP-0014-T04" in flat_plan + assert "current_version=1" in flat_plan + assert "reuse-surface-runtime-eso" in flat_plan + assert "workload-kv-read-reuse-surface-runtime-eso" in flat_plan assert "Q1:" in flat_plan and "Q2:" in flat_plan and "Q3:" in flat_plan assert "9833715e-a22a-45c0-ab6c-881f0f4f1a0e" in flat_workplan assert "CCR-2026-0046" in flat_workplan assert "4a4602ad926e3af855d6ddba4731430d33e4a7432c507ba0a5193b9f43056b52" in flat_workplan assert "RPF-WP-0058-T05" in flat_workplan - assert "not an ops-mason success publication" in flat_workplan + assert "reviewed_present" in flat_workplan + assert "status: draft" in proposal + assert "not-activated" in proposal + assert "warden_executes: false" in proposal + + +def test_reader_survey_entry_point_is_metadata_only(tmp_path, capsys): + catalog = tmp_path / "catalog.yaml" + catalog.write_text("version: 1\nentries: []\n") + token = "hvs.SYNTHETICgrantTOKENvalue0123456789" + calls = [] + eso = "workload-kv-read-reuse-surface-runtime-eso" + writer = "workload-kv-read-reuse-surface-runtime" + + def runner(argv, env): + calls.append(argv) + assert env["BAO_TOKEN"] == token + pos = [a for a in argv[1:] if not a.startswith("-")] + assert not (pos[:1] == ["kv"] and "get" in pos and "metadata" not in pos) + assert pos[:2] != ["kv", "get"] + assert not any("/data/" in a for a in pos) + key = tuple(pos) + if key == ("token", "lookup"): + body = {"data": {"policies": ["default", "ops-mason-survey"], + "display_name": "token-claude-MASON-WP-0014-T04", "ttl": 1000, + "id": token}} + elif key == ("secrets", "list"): + body = {"platform/": {"type": "kv", "options": {"version": "2"}}} + elif key == ("auth", "list"): + body = {"kubernetes/": {"type": "kubernetes"}} + elif key == ("policy", "list"): + body = [eso, writer] + elif key == ("list", "auth/kubernetes/role"): + body = ["reuse-surface-runtime-eso"] + elif key == ("read", "auth/kubernetes/role/reuse-surface-runtime-eso"): + body = {"data": {"token_policies": [eso], + "bound_service_account_names": ["reuse-surface-eso"], + "bound_service_account_namespaces": ["reuse"], + "audience": "openbao"}} + elif key == ("policy", "read", eso): + return 0, ( + 'path "platform/data/workloads/reuse/reuse-surface/forgejo-source-read" ' + '{ capabilities = ["read"] }\n' + ), "" + elif key == ("policy", "read", writer): + return 0, 'path "platform/data/workloads/reuse/reuse-surface/runtime-secrets" { capabilities = ["read"] }\n', "" + elif key == ("kv", "metadata", "get", + "platform/workloads/reuse/reuse-surface/forgejo-source-read"): + body = {"data": {"current_version": 1, "created_time": "2026-10-15T00:00:00Z", + "updated_time": "2026-10-15T00:00:00Z", "custom_metadata": {}}} + elif key == ("kv", "list", "platform/workloads/reuse/reuse-surface"): + body = ["forgejo-source-read"] + else: + return 2, "", "No value found" + return 0, json.dumps(body), "" + + rc = survey.main( + [*READER_ARGS, "--catalog", str(catalog)], + runner=runner, + environ={"BAO_TOKEN": token, "BAO_ADDR": "http://127.0.0.1:18200"}, + ) + out = capsys.readouterr().out + assert rc == 0 + assert "token-claude-MASON-WP-0014-T04" in out + assert "platform/workloads/reuse/reuse-surface/forgejo-source-read" in out + assert "current_version=1" in out + assert "no stanza covers" in out + assert token not in out + assert any( + [a for a in argv[1:] if not a.startswith("-")][:3] == ["kv", "metadata", "get"] + for argv in calls + ) diff --git a/workplans/MASON-WP-0013-reuse-surface-private-source-reader.md b/workplans/MASON-WP-0013-reuse-surface-private-source-reader.md index 62db1bd..4bbbebd 100644 --- a/workplans/MASON-WP-0013-reuse-surface-private-source-reader.md +++ b/workplans/MASON-WP-0013-reuse-surface-private-source-reader.md @@ -4,11 +4,11 @@ type: workplan title: "Construct the seven-repository reuse-surface source reader" domain: infotech repo: ops-mason -status: proposed +status: finished owner: codex topic_slug: netkingdom-security-architecture created: "2026-10-15" -updated: "2026-10-21" +updated: "2026-10-22" flavor: implementation depends_on: [] state_hub_workstream_id: "a1da7c80-a299-5a46-8b42-9e366271442c" @@ -16,9 +16,9 @@ state_hub_workstream_id: "a1da7c80-a299-5a46-8b42-9e366271442c" # Seven-repository hosted reader -Demand: CUST-WP-0081; metadata disclosure consent is recorded separately. This -workplan is prepared in an isolated owner checkout and is not yet integrated, -synced, approved or executed. No production or credential authority is inferred. +Demand: CUST-WP-0081. Metadata disclosure consent is a separate record. +ops-mason surveyed metadata and recorded the platform CCR, founder decision, +and cited receipts. It did not mint or apply the lane. ## Prepare the construction bundle @@ -37,14 +37,14 @@ auth_env/URL authorization and redirect fix plus exact14 runtime allowlist gate, with R1 evidence preserved. Plan remains draft because required live survey and independent mechanism/owner reviews are missing. +Appended 2026-10-22: the live survey is on T02. After that survey the plan +status is `reviewed`. + ## Complete scoped survey and construction review ```task id: MASON-WP-0013-T02 -status: wait -needs_human: true -decision_id: 0b55e53b-2531-466c-a2f9-282618b183f8 -blocking_reason: "Founder mints ./scripts/bao-session.sh grant MASON-WP-0013-T02. An agent does not log in or grant. This decision is not plan approval." +status: done priority: high state_hub_task_id: "a05e88da-9a75-516d-aab4-7a5d266f1ac6" ``` @@ -55,18 +55,24 @@ handling; Forgejo owner confirms Q1–Q3 hierarchy choices. Review effective gra across all API pages, secret lifecycle, negative tests and caller/ESO separation. Do not use operator tokens or another agent supervision record. -2026-10-21: still `wait`. Plan §2 records the grant refusal -(`no ops-mason-survey grant`) and cites Forgejo-owner `sec_dsm_order` Q1–Q3 -from `forge-owner-review-r2.json` (2026-10-14T23:08:34Z). That citation is not -a metadata survey. Exact installed path, policy, and role remain unconfirmed. -Plan status stays `draft`. Founder grant gate is hub decision -`0b55e53b-2531-466c-a2f9-282618b183f8`. It does not approve this plan. +Done 2026-10-21T22:15:21Z. `scripts/plan-survey.py` ran under grant +`token-claude-MASON-WP-0014-T04` (policies `default`, `ops-mason-survey`). +That was the one minted survey grant. It is not an operator or admin token. + +Plan §2 records the exact path +`platform/workloads/reuse/reuse-surface/forgejo-source-read` +(`current_version=1`), policy `workload-kv-read-reuse-surface-runtime-eso` +(`read` on that data path), and Kubernetes role `reuse-surface-runtime-eso` +(SA `reuse-surface-eso`, namespace `reuse`, audience `openbao`). Decision: +the OpenBao delivery lane already matches. The writer policy does not cover +the path. Forgejo-owner Q1–Q3 are cited from `forge-owner-review-r2.json`. +The plan is `reviewed`, not approved by ops-mason. ## Bind owner CCR and executable inputs to founder decision ```task id: MASON-WP-0013-T03 -status: wait +status: done depends_on: [MASON-WP-0013-T02] priority: high state_hub_task_id: "99d605e6-865c-5518-bb8b-d7e1e1bbf5c4" @@ -79,20 +85,23 @@ warden owns pointer review. Obtain separate founder decision on exact credential and live-change revision/digests. Existing disclosure consent cannot approve repository-wide credential grant. Requires T02. -2026-10-21: still `wait` because T02 is not done. Observed elsewhere, and not -adopted as this task's completion: platform CCR-2026-0046, and founder -decision `9833715e-a22a-45c0-ab6c-881f0f4f1a0e` (resolved 2026-10-15, Bernd -Worsch, binds execution revision SHA256 -`704a9c932202fc14456652ea4dfdb3acb8b1db0ab3bbf5fff50e92b2c517c380`). The -disclosure-consent digest -`4a4602ad926e3af855d6ddba4731430d33e4a7432c507ba0a5193b9f43056b52` is a -different record. ops-mason does not approve, mint, or apply from this note. +Done as a record of the already-resolved binding. ops-mason did not approve, +mint, or apply. + +- Platform CCR-2026-0046. The executed CCR digest cited by platform evidence + is `23039fae6137e7bdd71de0ed3278596b1ed60ae636018eb4bfcc83e53c4ada02`. +- Founder decision `9833715e-a22a-45c0-ab6c-881f0f4f1a0e`, resolved + 2026-10-15 by Bernd Worsch. It binds execution revision SHA256 + `704a9c932202fc14456652ea4dfdb3acb8b1db0ab3bbf5fff50e92b2c517c380`. +- Disclosure-consent digest + `4a4602ad926e3af855d6ddba4731430d33e4a7432c507ba0a5193b9f43056b52` is a + different record. ## Verify the authorized owner build and routing handoff ```task id: MASON-WP-0013-T04 -status: wait +status: done depends_on: [MASON-WP-0013-T03] priority: high state_hub_task_id: "8125f98b-f87c-582f-af8c-f5e809caf50f" @@ -105,10 +114,33 @@ catalog route and hand 70-ID fresh audit evidence to CUST-WP-0081. Never publish success before actual receipt or finish while unresolved lifecycle work is only in prose. -2026-10-21: still `wait`. This session has no scoped metadata receipt. No -draft catalog route is added; ops-warden catalog has no -`reuse-surface-forgejo-source-read` entry. Platform's hosted receipt -`docs/evidence/2026-10-15-reuse-private-reader-hosted-establishment-r1.json` -is an external claim of seven native indexes and 70 reviewed ids, not an -ops-mason success publication. Lifecycle rotation is already the live task -`RPF-WP-0058-T05` (due 2027-01-13). No second rotation intake is opened here. +Done as observation of the platform path plus this session's metadata +receipt. ops-mason did not re-execute the build and did not publish a new +success by logging in as the workload. + +- Metadata, 2026-10-21T22:15:21Z, grant `token-claude-MASON-WP-0014-T04`: + path version 1, ESO policy read, role bound as in T02. Survey-token + capabilities: `deny` on the reader data path and on + `platform/data/workloads/reuse/reuse-surface/runtime-secrets`; `list, read` + on the reader metadata path. Writer policy + `workload-kv-read-reuse-surface-runtime` has no stanza for the reader path. +- Seven native indexes: custodian + `docs/assessments/netkingdom-2026-10-14/private-native-fetch-verification-r1.json`, + id `CUST81-PRIVATE-NATIVE-FETCH-RECEIPT-R1`, `all_verified` true, seven + repositories, `checked_at` 2026-10-15T03:30:20.627885Z. No source body is + copied here. +- Seventy reviewed ids: custodian + `docs/assessments/netkingdom-2026-10-14/hosted-private-registration-verification-r1.json`, + `reviewed_present` 70, `all_reviewed_hosted_exactly_once` true, + `composed_at` 2026-10-15T03:31:48Z. That file is the CUST-WP-0081 + evidence. This task cites it and does not copy the seventy ids. +- Outcome receipt: railiance-platform + `docs/evidence/2026-10-15-reuse-private-reader-custody-r1.json`, + bootstrap attempt `bb2693a7640f00b4e401467e`. The preserved rollback + contract is the-custodian + `docs/assessments/netkingdom-2026-10-14/private-reader-execution-proposal-r1.json` + field `rollback`. Rollback was not run. The live rotation and revocation + record remains `RPF-WP-0058-T05`. +- Draft catalog route, not activated: + `builds/reuse-surface-private-source-reader/catalog-proposal.yaml`. + It is not in the ops-warden catalog. diff --git a/workplans/MASON-WP-0014-mas-tem-relay-smtp.md b/workplans/MASON-WP-0014-mas-tem-relay-smtp.md index 15ff698..6304950 100644 --- a/workplans/MASON-WP-0014-mas-tem-relay-smtp.md +++ b/workplans/MASON-WP-0014-mas-tem-relay-smtp.md @@ -4,11 +4,11 @@ type: workplan title: "Build the temporary MAS live-test TEM SMTP relay lane" domain: infotech repo: ops-mason -status: proposed +status: finished owner: claude topic_slug: netkingdom-security-architecture created: "2026-10-18" -updated: "2026-10-21" +updated: "2026-10-22" flavor: implementation depends_on: [] state_hub_workstream_id: "1df71ade-cb20-5eae-8f6b-bae416058970" @@ -66,10 +66,7 @@ CCR-2026-0051. ops-mason built the policy and role under `ops-mason-construct` ```task id: MASON-WP-0014-T04 -status: wait -needs_human: true -decision_id: 0b55e53b-2531-466c-a2f9-282618b183f8 -blocking_reason: "Founder mints ./scripts/bao-session.sh grant MASON-WP-0014-T04 so KV metadata can be re-read. ExternalSecret sync is already name-only Ready/SecretSynced. An agent does not log in or grant." +status: done priority: medium state_hub_task_id: "75eb71c8-5ac4-5512-bee3-6c0e4bee4dfd" ``` @@ -77,22 +74,13 @@ state_hub_task_id: "75eb71c8-5ac4-5512-bee3-6c0e4bee4dfd" Confirm KV metadata exists and that Secret `mas/mas-relay` syncs (names only). Record the teardown steps (plan rows 6–7) as a residual against MAS-WP-0003 close. -2026-10-21 check, names and status only. T04 stays `wait`. The workplan stays -`proposed`. +Done 2026-10-21T22:15:18Z under grant `token-claude-MASON-WP-0014-T04` +(policies `default`, `ops-mason-survey`). No `kv get` and no data body. -- OpenBao metadata was not re-read. `./scripts/bao-session.sh status` reported - the operator session none or expired and `~/.claude-bao-token` absent. - `scripts/plan-survey.py` for `platform/suppliers/scaleway/mas-tem-relay`, - policy `workload-kv-read-mas-tem-relay`, and role - `external-secrets-mas-tem-relay` exited 2 with `no ops-mason-survey grant`. - A non-grant token against `http://127.0.0.1:18200` received HTTP 403 - `permission denied` on the mount lookup. No `kv get` and no data body. -- Kubernetes context `default`: ServiceAccount `mas-tem-relay-eso` and - SecretStore `openbao-mas-tem-relay` are present in namespace `mas`. - ExternalSecret `mas-relay` is Ready True, reason SecretSynced, binding name +- KV `platform/suppliers/scaleway/mas-tem-relay` exists, `current_version=2`. +- Policy `workload-kv-read-mas-tem-relay` grants `read` on that data path. + Role `external-secrets-mas-tem-relay` binds SA `mas-tem-relay-eso` in `mas`. +- ExternalSecret `mas-relay` is Ready True, reason SecretSynced, binding name `mas-relay`. The Secret object was not read. - Teardown rows 6–7 are live intake `MASON-IN-0007` (`origin: residual`, `origin_ref: MASON-WP-0014`), due at MAS-WP-0003 close. Not executed. -- The metadata re-read waits on founder decision - `0b55e53b-2531-466c-a2f9-282618b183f8` (mint `ops-mason-survey` for this - task). That decision is not a new approval of the built lane.