rapp-tenant-engine applied by the founder: store Ready, ExternalSecret SecretSynced. NK type oidc-browser-relying-party acknowledged (decision e418263e resolved), so rendering from a case can start. 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
154 lines
6.4 KiB
Markdown
154 lines
6.4 KiB
Markdown
---
|
|
id: MASON-WP-0010
|
|
type: workplan
|
|
title: "Materialize SecurityCases from their type, with acceptance as the only gate"
|
|
domain: infotech
|
|
repo: ops-mason
|
|
status: active
|
|
flavor: implementation
|
|
owner: claude-code
|
|
topic_slug: netkingdom
|
|
created: "2026-10-08"
|
|
updated: "2026-10-08"
|
|
depends_on: []
|
|
related_repos:
|
|
- net-kingdom
|
|
- ops-warden
|
|
- railiance-platform
|
|
state_hub_workstream_id: "eabf2c39-94bd-5a11-8f2e-76d7a95d1583"
|
|
---
|
|
|
|
# MASON-WP-0010 — Materialize SecurityCases from their type, with acceptance as the only gate
|
|
|
|
## Why
|
|
|
|
NetKingdom is introducing SecurityCaseTypes (net-kingdom `NK-WP-0048`, canon
|
|
`security-case-types_v0.1`, proposed). A type is designed once, with
|
|
documentation, tests and an informed-decision. Each case of an implemented type
|
|
is then light: it is accepted, ops-mason arranges it, and ops-warden follows
|
|
through.
|
|
|
|
ops-mason's four phases (construction plan, review, executive summary, build)
|
|
stay exactly as they are for **new types and for structure that no type
|
|
covers**. For a **KnownSecurityCase**, the construction plan is rendered from
|
|
the type's materialization templates, and the executive-summary gate collapses
|
|
to the case acceptance, because the shape was decided when the type was
|
|
acknowledged.
|
|
|
|
MASON-WP-0009 (a hand-built placement of a key-cape client secret) is the kind
|
|
of work this replaces. It becomes a reference instance for the first type.
|
|
|
|
## Tasks
|
|
|
|
```task
|
|
id: MASON-WP-0010-T01
|
|
status: done
|
|
depends_on: [NK-WP-0048-T03]
|
|
priority: high
|
|
state_hub_task_id: "3382ea7b-65ca-59a9-97ae-273455af44c2"
|
|
```
|
|
|
|
### T01 — Define the type's materialization section
|
|
|
|
Propose the `materialization` part of the SecurityCaseType schema together with
|
|
net-kingdom: policy, role, KV path structure and catalog-entry templates over
|
|
case parameters, with naming rules. These must respect ops-mason's existing
|
|
"respect, extend or compact before adding" review, so that a type cannot
|
|
template sprawl. Write it for the first type, `oidc-browser-relying-party`, from
|
|
MASON-WP-0009 and the existing key-cape client custody paths.
|
|
|
|
**Review (2026-10-08) of net-kingdom `security-case-types/oidc-browser-relying-party/type.yaml` 1.0.**
|
|
The structure (four items, all but the catalog entry conditional on
|
|
`confidential`) is right. The names add three new families where existing ones
|
|
cover the need, so they fail "respect, extend or compact before adding".
|
|
Requested refinements, each from the live CCR-2026-0033 placement
|
|
(`plans/keycape-secrets-engine-openbao-client-custody.md`):
|
|
|
|
1. **Fix the path in the type.** `secret_ref` should not be case-settable; a
|
|
free pattern under `platform/workloads/` lets every case pick its own layout.
|
|
Derive it: `platform/workloads/keycape/{client_id}` (field `CLIENT_SECRET`),
|
|
as for `secrets-engine-openbao`.
|
|
2. **Reuse the policy family.** Existing readers are
|
|
`workload-kv-read-keycape-<client>-<reader>`. Rename
|
|
`keycape-client-{client_id}-read` to `workload-kv-read-keycape-{client_id}-eso`
|
|
(KeyCape reads its client secret only through ESO), and
|
|
`{consuming_service}-oidc-client-{client_id}-read` to
|
|
`workload-kv-read-keycape-{client_id}-{consuming_service}`. Update
|
|
verification `custody-allowed-to-consumer` and rollback to match.
|
|
3. **Template the policy body, not just its name.** An `openbao_policy` item
|
|
needs its rules (`read` on `platform/data/workloads/keycape/{client_id}`,
|
|
nothing else: no metadata, list, parent or sibling), or the review cannot
|
|
check invariant (ii) and a rendered plan is not buildable.
|
|
4. **Add the missing ESO role.** `deliver-secret` needs a Kubernetes-auth role
|
|
`external-secrets-keycape-{client_id}` (kind `openbao_role`, bound to the
|
|
ESO service account, policy from item 2, 15m TTL, no default policy), as
|
|
the reference placement has.
|
|
5. **Catalog naming.** The one existing entry is `rapp-qonto-keycape-client`;
|
|
prefer `{consuming_service}-keycape-client` over `oidc-client-{client_id}`.
|
|
6. **Rollback order.** `mint-secret` "destroy" and `client-secret-path`
|
|
"remove" act on the same KV path; collapse to one step (metadata delete
|
|
after the ExternalSecret is gone) so rollback cannot fail on a missing path.
|
|
|
|
With 1-4 applied, the section is acceptable to ops-mason for NK-WP-0048-T05.
|
|
|
|
2026-10-08: net-kingdom folded in all six (net-kingdom `074b3a0`, message
|
|
`508e2a12`); its schema/validator now require a body on policy and role items.
|
|
NK-WP-0048-T05 still waits on WARDEN-WP-0044-T01 and a founder answer.
|
|
|
|
2026-10-09: the founder accepted memo r4; hub decision `e418263e` resolved and
|
|
the type is `acknowledged` (net-kingdom `0e86f95`). T02 is unblocked.
|
|
|
|
```task
|
|
id: MASON-WP-0010-T02
|
|
status: todo
|
|
depends_on: [MASON-WP-0010-T01, NK-WP-0048-T05]
|
|
priority: high
|
|
state_hub_task_id: "fd385537-7378-5539-8a6e-f45851296f42"
|
|
```
|
|
|
|
### T02 — Render a construction plan from a case
|
|
|
|
`mason plan --case <case.yaml>` validates the case against its `implemented`
|
|
type, renders the construction plan from the type's templates, and runs the
|
|
existing consistency review against current OpenBao structure (read-only, no
|
|
values). The output is the usual plan, marked `derived-from-type`, plus the
|
|
case-acceptance reference in place of a fresh executive summary.
|
|
|
|
Tests: render the reference case; refuse a case whose type is not
|
|
`implemented`; refuse parameter values outside the type's validation; flag a
|
|
collision with existing structure.
|
|
|
|
```task
|
|
id: MASON-WP-0010-T03
|
|
status: wait
|
|
depends_on: [MASON-WP-0010-T02]
|
|
blocking_reason: "Building from an accepted case follows the rendering."
|
|
priority: high
|
|
state_hub_task_id: "56cea6be-c613-586c-80cd-125340b374da"
|
|
```
|
|
|
|
### T03 — Build from an accepted case
|
|
|
|
`mason build --case <case.yaml>` builds a rendered plan when the case's
|
|
acceptance record is present, with no separate executive-summary approval. Its
|
|
audit trail names the case, the type version and the acceptance. It proposes the
|
|
pointer-only ops-warden catalog entries the type defines, as today. Rollback
|
|
removes exactly what this case created.
|
|
|
|
Acceptance: the Forgejo reference case (NK-WP-0048-T06) materializes through this
|
|
path.
|
|
|
|
```task
|
|
id: MASON-WP-0010-T04
|
|
status: wait
|
|
depends_on: [MASON-WP-0010-T03]
|
|
blocking_reason: "Adoption follows a working light path."
|
|
priority: medium
|
|
state_hub_task_id: "f6ad0d3c-8f47-5fdf-8115-6ca9d8a1fead"
|
|
```
|
|
|
|
### T04 — Adopt MASON-WP-0009 as a case
|
|
|
|
Once `oidc-browser-relying-party` (or the confidential service client type) is
|
|
implemented, express MASON-WP-0009's placement as a case of that type without
|
|
changing the live structure, and close the hand-built path.
|