diff --git a/plans/state-hub-forge-derivation-read.md b/plans/state-hub-forge-derivation-read.md index 1f1b3fa..795f37a 100644 --- a/plans/state-hub-forge-derivation-read.md +++ b/plans/state-hub-forge-derivation-read.md @@ -3,7 +3,7 @@ id: state-hub-forge-derivation-read demand_source: ops-mason/workplans/MASON-WP-0003 consumer_repo: state-hub credential_type: openbao-approle-kv -status: approved +status: built approved_by: "Bernd Worsch" approved_at: "2026-08-26" breadth: organisation-wide-read @@ -208,3 +208,65 @@ the OpenBao policy, the AppRole, the KV path structure, and the pointer-only ops-warden catalog entry. It does not authorise ops-mason to mint or handle the token value — the forge owner mints it with organisation-wide repository read and no other scope, and `paste_once_provision` delivers it. + +## 7. Build result (phase 4) + +Built 2026-08-27 against a live `platform-root` session. Recorded in +`audit/build-log.jsonl`. + +| # | Object | State | +|---|---|---| +| 1 | KV path `platform/workloads/state-hub/forge-derivation` | **not yet created** — comes into existence when `paste_once_provision` writes the value; the policy grants read on it regardless | +| 2 | Policy `workload-kv-read-state-hub-forge-derivation` | created, read on the data and metadata paths only | +| 3 | Kubernetes auth role `state-hub-forge-derivation` | created, bound to ServiceAccount `state-hub/state-hub`, `token_ttl=15m`, `token_max_ttl=30m` | +| 4 | Token value | **not handled by ops-mason** — forge owner mints, `paste_once_provision` delivers | +| 5 | ops-warden catalog entry | drafted on branch `mason/state-hub-forge-derivation-read`, `status: draft` | + +### Deviation from the approved plan: Kubernetes auth, not AppRole + +§2's survey was written from disk with no OpenBao session, and did not know that +`kubernetes/` auth is enabled on this same cluster (`https://10.43.0.1:443`) +with four `external-secrets-*` roles already using it. The plan's own phase-4 +instruction — re-verify against live state before applying — is what surfaced it. + +Ruled by the founder at phase 4 on 2026-08-27: **Kubernetes auth**. The pod +authenticates with its own projected ServiceAccount token, so no `role_id` +/`secret_id` pair exists to deliver into the cluster, store, or rotate. That +directly satisfies `STATE-WP-0084-T02`'s constraints — nothing baked into the +image, rotation without a redeploy — and removes a static credential of exactly +the kind whose custody gap cost a full session on the LLDAP side the previous +day. + +### Verification + +Positive and negative checked with `bao token capabilities` through a 2-minute +test token, revoked immediately after: + +```text +platform/data/workloads/state-hub/forge-derivation read +platform/data/workloads/forgejo/forgejo-admin deny +platform/data/workloads/activity-core/llm-connect/...provider-secrets deny +platform/metadata/workloads/state-hub deny +``` + +The negative on `forgejo-admin` is the one that matters: not being able to do +what the admin lane can is the entire argument for building this lane rather +than reusing it. + +### Reuse re-checked against live state + +`bao policy list` shows one Forgejo-adjacent workload policy that §2 could not +see: `workload-kv-read-agent-harness-forgejo`. Read, and confirmed not +reusable — it grants a single agent-harness **deploy key** for one repository, +not organisation-wide read for a different consumer. §2's conclusion stands. + +### Prerequisites before the lane carries traffic + +1. ServiceAccount `state-hub` in namespace `state-hub` — the deployment + currently runs as `default`, and the role deliberately does not bind to + `default`, which would grant the lane to every pod in the namespace. + `STATE-WP-0084-T02`. +2. The Forgejo token, minted at organisation-wide repository read and delivered + to the KV path via `paste_once_provision`. + +Until both are done the lane is correctly scoped and inert. diff --git a/workplans/MASON-WP-0003-state-hub-forge-read-lane.md b/workplans/MASON-WP-0003-state-hub-forge-read-lane.md index 9d65021..a78d28c 100644 --- a/workplans/MASON-WP-0003-state-hub-forge-read-lane.md +++ b/workplans/MASON-WP-0003-state-hub-forge-read-lane.md @@ -119,7 +119,7 @@ ruled on; build-phase posture stands as proposed. Reasoning in ```task id: MASON-WP-0003-T02 -status: todo +status: done priority: high state_hub_task_id: "68a1c8e4-c12b-550e-962c-06a90ab8c1c2" ``` @@ -140,6 +140,22 @@ delivered a working token into it, confirmed by the consumer rather than by reading the value here. Recorded in `audit/build-log.jsonl` against the approved plan. +**Done (2026-08-27).** Policy `workload-kv-read-state-hub-forge-derivation` and +Kubernetes auth role `state-hub-forge-derivation` created and verified; see +`plans/state-hub-forge-derivation-read.md` §7 and `audit/build-log.jsonl`. + +**Kubernetes auth replaces the approved AppRole**, ruled at phase 4 after the +live survey found `kubernetes/` auth enabled on this cluster — something §2's +disk-only survey could not see. No static `role_id`/`secret_id` is created, so +there is nothing to deliver or rotate. + +ops-mason handled no secret value. The KV path does not exist yet and will not +until `paste_once_provision` writes the token; the policy grants read on it +either way. Two prerequisites remain before the lane carries traffic, both +outside this repo: ServiceAccount `state-hub/state-hub` +(`STATE-WP-0084-T02` — the role deliberately does not bind to `default`), and +the minted token. + ## Register the lane in the routing catalog ```task