Bundle validates; ESO policy identical to applied CCR-2026-0041. Four fluid-telegram entries drafted from the approved plan; email-connect asked for its new path. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 327203@bnt-lap001 Assistant-Session: 55028ae3-4914-4bd1-8f5c-815f3527aef0
232 lines
11 KiB
Markdown
232 lines
11 KiB
Markdown
---
|
||
id: MASON-WP-0004
|
||
type: workplan
|
||
title: "Describe every stored credential so the store is navigable"
|
||
domain: infotech
|
||
repo: ops-mason
|
||
status: blocked
|
||
flavor: planning
|
||
owner: codex
|
||
topic_slug: custodian
|
||
created: "2026-08-28"
|
||
updated: "2026-10-03"
|
||
related:
|
||
- MASON-WP-0003
|
||
- NK-WP-0033
|
||
state_hub_workstream_id: "e5656747-a974-581a-a3d4-4e6bb7262f4c"
|
||
---
|
||
|
||
# Describe every stored credential so the store is navigable
|
||
|
||
## Goal
|
||
|
||
Give all 21 credential paths in `operators/` and `platform/workloads/` the five
|
||
`custom_metadata` fields the custody standard requires, so an operator can find
|
||
out what a credential is without reading it.
|
||
|
||
## Why this exists
|
||
|
||
`custody-inventory.py` reported 21 paths on 2026-08-28. Four carry descriptions
|
||
— the ones `MASON-WP-0003` touched. **Seventeen carry none.**
|
||
|
||
An undescribed credential is one nobody can identify without reading it, which
|
||
means orientation requires the very access the store exists to control. It also
|
||
means the two failure modes of the previous week stay available: no `used_by`
|
||
list, so a rotation misses a consumer the way privacyIDEA's resolver was missed
|
||
for four days; and no `on_loss` line, so recovery gets improvised under pressure
|
||
the way the LLDAP predecessor's did.
|
||
|
||
This is not urgent the way a broken login is urgent. It is the difference
|
||
between a secret store and a drawer of unmarked keys.
|
||
|
||
## What "described" means
|
||
|
||
Five fields, per `net-kingdom/docs/platform-root-custody.md`: `description`,
|
||
`owner`, `used_by`, `rotation`, `on_loss`. Metadata only — no path's value is
|
||
read, and `ops-mason-build` cannot read one.
|
||
|
||
## Establish owners before writing anything
|
||
|
||
```task
|
||
id: MASON-WP-0004-T01
|
||
status: done
|
||
decision_id: e9f44beb-ad15-4285-8996-1e66d312fe59
|
||
priority: medium
|
||
state_hub_task_id: "5bda75f2-f780-579e-9d44-cc4011662b9a"
|
||
```
|
||
|
||
Most of the seventeen predate this repository and ops-mason cannot invent what
|
||
they are for. Group them by mount prefix, propose an owning repo for each from
|
||
the ops-warden catalog and the paths themselves, and take the founder's ruling
|
||
on the ones that are genuinely unclear.
|
||
|
||
Guessing is the failure mode to avoid: a confidently wrong `used_by` is worse
|
||
than an empty one, because a rotation will trust it.
|
||
|
||
Acceptance: every one of the seventeen has a named owner, or is explicitly
|
||
listed as unknown with the question that would settle it.
|
||
|
||
2026-10-03: human gate routed to hub decision e9f44beb-ad15-4285-8996-1e66d312fe59 (D8: ops-mason plan approvals: unclear metadata paths and the live-survey plan) by CUST-WP-0075; resolving that decision raises C-40 here.
|
||
|
||
2026-10-09: live inventory under grant `claude-MASON-WP-0004-T01` (revoked
|
||
after): 49 paths, 45 undescribed (was 21/17 on 2026-08-28). Owner proposals in
|
||
`docs/credential-owner-proposals-2026-10-09.md`: 38 documented (owner from
|
||
catalog or CCR), 3 genuinely unclear (`activity-core/default/llm-connect-provider-secrets`,
|
||
`forgejo/forgejo-mailer`, `target-revenue/runtime-secrets`), and 4 undocumented
|
||
fluid-telegram entries under tenant `infotech` that conflict with the approved
|
||
MASON-WP-0005 plan (`coulomb`). Waiting on the founder's ruling for A and B.
|
||
|
||
2026-10-09 done: founder ruled. A: `coulomb` as approved, the four values move
|
||
there (MASON-WP-0005). B1: retire the duplicate `activity-core/default/...`
|
||
entry (founder-run delete via railiance-platform after a live no-grant check).
|
||
B2: `forgejo/forgejo-mailer` belongs to the new `rapp-forgejo` repo. B3:
|
||
`target-revenue/runtime-secrets` deferred as outdated. Every path now has a
|
||
proposed owner or an explicit reason, which is T01's acceptance.
|
||
|
||
## Describe the paths whose purpose is already documented
|
||
|
||
```task
|
||
id: MASON-WP-0004-T02
|
||
status: done
|
||
decision_id: 62aa95e4-3ccc-4867-8806-5e3db005b483
|
||
priority: medium
|
||
state_hub_task_id: "a6a944d7-21c5-5043-a78d-b3809de0ee64"
|
||
```
|
||
|
||
Several are covered by an existing ops-warden catalog entry, playbook, or
|
||
construction plan in `plans/` — `railiance/backup/*`, `rapp-qonto/*`,
|
||
`user-engine/runtime`, `reuse-surface/runtime-secrets` among them. For those the
|
||
five fields can be written from documents that already exist, with `rotation`
|
||
pointing at the real procedure rather than paraphrasing it.
|
||
|
||
Acceptance: `custody-inventory.py` reports these paths without a `!`, and each
|
||
`rotation` field names a document that exists.
|
||
|
||
2026-10-03: human gate routed to hub decision 62aa95e4-3ccc-4867-8806-5e3db005b483 (D1: Attended OpenBao provisioning window: one session clears the pending credential lanes) by CUST-WP-0075; resolving that decision raises C-40 here.
|
||
|
||
2026-10-09: drafted. `scripts/custody-describe.py draft` builds
|
||
`manifests/custody-descriptions.yaml` from the railiance-platform CCRs
|
||
(`target.purpose`, `delivery.target`, `lifecycle.rotate`), the ops-warden
|
||
catalog and the owner proposals, never from OpenBao; four ops-mason-sourced
|
||
entries were filled by hand from `plans/`. 29 of 38 have all five fields; 9
|
||
have gaps left empty on purpose (nextcloud x2, keycape-factor-issuer,
|
||
grafana-admin, smtp, and four `used_by`). Every entry is `review: draft`.
|
||
`apply` writes custom_metadata only, for `review: accepted` entries, silently
|
||
(`tests/test_custody_describe.py`, suite 157 passed). Founder run, after
|
||
review: `warden access openbao-platform-admin-login --exec -- sh -c 'python3
|
||
/home/worsch/ops-mason/scripts/custody-describe.py apply
|
||
/home/worsch/ops-mason/manifests/custody-descriptions.yaml >/dev/null 2>&1'`,
|
||
then read `~/.local/state/railiance/receipts/custody-describe.json`.
|
||
(First attempt 2026-10-09 refused by the wrapper because apply printed status
|
||
lines; nothing written, all entries were still drafts. apply is now silent.)
|
||
|
||
2026-10-09 founder runs 3-4: the wrapper has a temporary HOME and the admin
|
||
policy has no `patch` capability, so apply now writes its receipt under the
|
||
real home and falls back to metadata get + merged put. Run 4 receipt: 27 of 29
|
||
accepted entries `merged` (existing custom_metadata kept), 2 `failed put
|
||
http=400` (`core-hub/forgejo-source-read`, `secrets-engine/approval-client`):
|
||
`used_by` was 514 bytes, clipped by characters. Clipping is now by bytes; those
|
||
two need one more run.
|
||
|
||
2026-10-09 founder run 5: exit 0, receipt 29/29 accepted entries `merged`, 9
|
||
drafts `skipped`. Remaining for T02 acceptance: re-run custody-inventory under
|
||
a survey grant to confirm the 29 report without `!`. The 9 gaps go to owners
|
||
in T03.
|
||
|
||
2026-10-09 done: custody-inventory under grant `claude-MASON-WP-0004-T02`
|
||
(revoked after): 49 paths, 16 undescribed (from 45); none of the 29 accepted
|
||
paths is flagged, and the keycape entry kept its CCR-2026-0033 keys next to the
|
||
five new ones. Each `rotation` names an existing CCR file or document. The 16
|
||
left: the 9 drafts with gaps (T03), the four `infotech` fluid-telegram entries
|
||
(moving, MASON-WP-0005-T04), the retiring `activity-core/default` duplicate,
|
||
`forgejo/forgejo-mailer` (rapp-forgejo) and the deferred
|
||
`target-revenue/runtime-secrets`.
|
||
|
||
## Resolve the rest with their owners
|
||
|
||
```task
|
||
id: MASON-WP-0004-T03
|
||
status: wait
|
||
depends_on: [MASON-WP-0004-T01]
|
||
blocked_on: owners
|
||
blocking_reason: "Owners fill the gaps in manifests/custody-descriptions.yaml for the 9 draft entries (asked 2026-10-09)."
|
||
priority: low
|
||
state_hub_task_id: "fff26914-d854-5854-b350-d7241812fb04"
|
||
```
|
||
|
||
Blocked on T01. What remains after T02 are paths whose purpose is not written
|
||
down anywhere. Each needs its owner to answer three questions: what is this, what
|
||
breaks when it changes, and what do you do when it is lost.
|
||
|
||
A path whose owner cannot answer the third question is a finding in its own
|
||
right — it is a credential with no recovery story, and that is worth knowing
|
||
before it is lost rather than after.
|
||
|
||
Acceptance: `custody-inventory.py` exits 0 across both mounts, or the remainder
|
||
is a short list with a recorded reason each.
|
||
|
||
2026-10-09: asked railiance-platform (nextcloud x2, telemetry smtp,
|
||
grafana-admin, agent-harness deploy key, whynot-design npm-publish),
|
||
net-kingdom (keycape-factor-issuer) and key-cape (rapp-qonto keycape-client).
|
||
user-engine/runtime's `on_loss` is ops-mason's own to write from the
|
||
user-engine plan once its ESO rotation rehearsal is recorded.
|
||
|
||
2026-10-09: net-kingdom answered for `keycape-factor-issuer` (message
|
||
`75b48030`): four fields filled in the manifest; `rotation` stays empty because
|
||
no rotation document exists, a gap attributed to railiance-platform. The entry
|
||
stays a draft until that exists. railiance-platform retired the duplicate
|
||
`activity-core/default/llm-connect-provider-secrets` (message `af873813`), and
|
||
the four `infotech` fluid-telegram entries were moved to `coulomb`.
|
||
|
||
2026-10-10: answers filled into the manifest (still `review: draft`, awaiting
|
||
founder acceptance and an apply run): railiance-platform (message `3e490cd4`)
|
||
completed `operators/nextcloud/backup`, `railiance-telemetry/smtp`,
|
||
`telemetry/grafana-admin`, `agent-harness/forgejo-deploy-key` and
|
||
`whynot-design/npm-publish`; key-cape (message `40395cc2`) named the two readers
|
||
of `rapp-qonto/keycape-client` (the rapp-qonto runtime's transport is for
|
||
railiance-apps to name). Still open: `operators/nextcloud` (railiance-platform
|
||
is asking the founder what it holds), `keycape-factor-issuer` rotation
|
||
(railiance-platform gap) and `user-engine/runtime` on_loss (ops-mason, after
|
||
its rotation rehearsal).
|
||
|
||
2026-10-10: founder accepted the six and applied: 34 paths `merged`, 3 drafts
|
||
skipped. `operators/nextcloud/backup` failed with HTTP 403, under both the
|
||
admin wrapper and the founder's own session (`operator-custody`): metadata is
|
||
readable but neither patch nor put may write it. Asked railiance-platform
|
||
whether `operators/*` metadata is write-protected by design and who writes
|
||
descriptions there (message `6b08c40d`).
|
||
|
||
2026-10-10 inventory (same grant as WP-0009-T05): 49 paths, 11 undescribed.
|
||
New since the last run: the four fluid-telegram entries at the `coulomb` path
|
||
(moved, never described) and `email-connect/callers/user-engine`. Drafted the
|
||
fluid-telegram four from the approved plan (draft until fluid-telegram confirms,
|
||
message `da7e711c`); asked email-connect for its new path (message
|
||
`acb3ff22`).
|
||
|
||
## Make an undescribed path visible before it accumulates
|
||
|
||
```task
|
||
id: MASON-WP-0004-T04
|
||
status: wait
|
||
depends_on: [MASON-WP-0004-T03]
|
||
blocking_reason: "After T03. A scheduled --undescribed report needs an unattended metadata-read credential and a named reader; survey grants are human-minted and expire within an hour."
|
||
priority: low
|
||
state_hub_task_id: "9a0cea06-eb63-54ad-963d-db4ea79c7c66"
|
||
```
|
||
|
||
Blocked on T03. Seventeen accumulated because nothing ever looked. Wire
|
||
`custody-inventory.py --undescribed` into whatever already runs regularly
|
||
against this repo, so a new undescribed path is noticed in days rather than
|
||
discovered in a year.
|
||
|
||
The check must not fail a build for a path someone else owns; it reports, and
|
||
the report has a reader.
|
||
|
||
Acceptance: an undescribed path added today surfaces without anyone
|
||
remembering to look.
|
||
|
||
## Loose-end review — 2026-09-28
|
||
|
||
T01–T04 remain wait: no valid scoped metadata grant/current inventory or complete owner/recovery confirmations are available. Inventory failure handling and the private-tunnel defaults are fixed and tested; scheduled reporting still needs its reader and credential.
|
||
|
||
Evidence and precise resumption conditions: [review](../docs/evidence/2026-09-28-loose-end-review.md). Existing tasks retain all remaining obligations; no new task or workplan was opened.
|