From 4b21f7bdeec0cc3aa97354d311d4a1efa546f40e Mon Sep 17 00:00:00 2001 From: tegwick Date: Thu, 8 Oct 2026 22:17:03 +0200 Subject: [PATCH] Propose SecurityCaseTypes canon and add NK-WP-0048 security-case-types_v0.1 (proposed): types designed once with docs, tests and an informed-decision; known cases light (accept, ops-mason materializes, ops-warden follows through). Founder direction 2026-10-08. Co-Authored-By: Claude Opus 5.5 Assistant: claude-code Assistant-Model: opus Assistant-Process: 5457@bnt-lap001 Assistant-Session: 792bf84a-3783-4f5d-a811-cded61dd2012 --- canon/standards/security-case-types_v0.1.md | 173 ++++++++++++++++++ workplans/NK-WP-0048-security-case-types.md | 184 ++++++++++++++++++++ 2 files changed, 357 insertions(+) create mode 100644 canon/standards/security-case-types_v0.1.md create mode 100644 workplans/NK-WP-0048-security-case-types.md diff --git a/canon/standards/security-case-types_v0.1.md b/canon/standards/security-case-types_v0.1.md new file mode 100644 index 0000000..45ac004 --- /dev/null +++ b/canon/standards/security-case-types_v0.1.md @@ -0,0 +1,173 @@ +--- +id: netkingdom-security-case-types-v0.1 +type: standard +title: "NetKingdom Security Case Types v0.1" +domain: netkingdom +status: proposed +version: "0.1" +owner: net-kingdom +created: "2026-10-08" +updated: "2026-10-08" +last_reviewed: "2026-10-08" +review_interval: 3m +scope: meta-orchestration +related: + - canon/standards/playbook-capability-contract_v0.2.md + - canon/standards/security-scenario-composition_v0.1.md + - canon/standards/credential-management_v0.2.md + - docs/security-bootstrap-use-cases.md +--- + +# NetKingdom Security Case Types v0.1 + +## 1. Purpose + +Most security work in the ecosystem repeats a small number of shapes: a browser +service that signs users in through NetKingdom, a service that authenticates +with its own credential, a workload that reads one KV path, an agent that needs +a short-lived SSH certificate. Until now each occurrence was built by hand: a +new helper script, a new custody path, a new founder checklist. That is slow, +and every hand-built instance can drift from the last one. + +This standard separates **designing a shape** from **using it**: + +- A **SecurityCaseType** is designed once, with ample documentation and tests, + and acknowledged as an informed-decision, because its shape is part of the + security architecture as a whole. +- A **SecurityCase** of an implemented type is light: the requester fills in the + type's parameters, the case is accepted, ops-mason arranges it, and ops-warden + carries it out on the authentication path the type provides. + +Making a new type is deliberately harder than making a new case. + +## 2. Terms + +| Term | Meaning | +| --- | --- | +| **SecurityCaseType** | A reusable, versioned security pattern for one kind of use case. Defines parameters, composition, materialization, execution route, verification, rollback and threats. | +| **SecurityCase** | One instance of a type, with concrete parameter values, an owner and an acceptance record. | +| **KnownSecurityCase** | A SecurityCase whose type is `implemented` (section 5). Only known cases take the light path. | +| **Type acknowledgment** | The informed-decision that admits a type, or a new major version of a type. | +| **Case acceptance** | The record that the case's owner, and where the type requires it the founder, accepted this instance. | +| **Materialization** | ops-mason building the structure a case needs: OpenBao policies, roles and KV path structure (never values), and catalog entries. | +| **Follow-through** | ops-warden executing the case's declared entry points on the type's authentication path, and verifying it. | + +A SecurityCaseType is not a new orchestration engine. It is a NetKingdom-owned +**composition** of playbook capabilities that their owning repos declare under +the Playbook Capability Contract, plus the guarantees in section 3. Execution +stays with the declared entry points (ADR-0007, ADR-0012). + +## 3. What a SecurityCaseType must define + +A type is a directory `security-case-types//` in net-kingdom containing: + +1. **`type.yaml`** (machine-readable, schema `canon/schemas/security-case-type_v0.1.schema.json`): + - `id`, `version`, `status` (section 5), `title`, `purpose` + - `parameters`: each with type, validation, allowed range and whether a case + may set it. Secret values are never parameters, only custody references. + - `composition`: required playbook capability ids with exact provider pins, + in the security-scenario-composition form (fail-closed ordering, explicit + initial trust, owner attribution) + - `materialization`: the OpenBao structure ops-mason creates per case, as + templates over the parameters: policy, role, KV path, catalog entry + - `follow_through`: the ops-warden route for each step, `warden_executes`, + the auth method and the entry point; which steps need an attended human + login, if any, and why + - `verification`: the checks that prove a case is live (positive and + negative), runnable without reading a secret value + - `rollback`: the exact inverse of each step + - `acceptance`: who accepts a case (owner only, or owner and founder) and + what risk class this type carries +2. **`README.md`**: the threat model, what the type protects and from whom, + design alternatives considered, and known limits. +3. **Tests**: validation of `type.yaml`, a rendered example case, and the + composer's output for that case. A type with no runnable tests cannot be + acknowledged. +4. **Reference instances**: existing hand-built instances this type replaces + or adopts, so that the type is grounded in practice. + +## 4. What a SecurityCase must define + +A case is a file `security-cases/.yaml`, in the requesting owner's +repository or in net-kingdom when it has no other owner: + +- `type`: `@`, which must be `implemented` +- `parameters`: values for the type's parameters +- `owner`: the repository and person accountable for the case +- `acceptance`: who accepted it, when, and where (State Hub decision, or a + record in the owner's repository) +- `status`: `proposed` → `accepted` → `materialized` → `live` → `retired` + +Nothing else. Everything a case needs beyond its parameters belongs in its type. +If a case cannot be expressed in its type's parameters, it is not a case of that +type: either change the case or propose a new type version (section 6). + +## 5. Type lifecycle + +| Status | Meaning | Who moves it | +| --- | --- | --- | +| `draft` | being written; not usable | type author | +| `proposed` | complete per section 3, tests green, Decision Memo prepared | type author | +| `acknowledged` | admitted by informed-decision | the founder, through informed-decision | +| `implemented` | ops-mason can materialize it and ops-warden can follow through; one reference case is live and verified | net-kingdom, with ops-mason and ops-warden | +| `deprecated` | no new cases; existing cases keep running | net-kingdom | +| `retired` | no cases remain | net-kingdom | + +Only `implemented` types accept new cases. + +## 6. Changing a type + +- **Patch** (documentation, tests, a stricter validation): a normal reviewed + change; no decision. +- **Minor** (a new optional parameter, an extra verification step): a + reviewed change, recorded in the type's history; no new acknowledgment unless + the risk class changes. +- **Major** (a changed authentication path, materialization or trust + transition; a looser validation; a higher risk class): a new informed-decision, + as for a new type. Existing cases stay on their version until migrated. + +## 7. The light path for known cases + +For a case of an `implemented` type: + +1. The requester writes the case file and validates it against the type. +2. The accepter records acceptance (section 4). This is the only human step + unless the type's `acceptance` requires an attended login for a specific + step, which the type must justify. +3. ops-mason materializes it from the type's templates. Its executive-summary + gate collapses to the case acceptance, because the shape was decided when the + type was acknowledged. +4. ops-warden follows through on the type's route and runs the type's + verification. +5. The case moves to `live` with the verification receipt. + +No case-specific helper script is written. If one seems necessary, the type is +incomplete. + +## 8. Roles + +| Party | Responsibility | +| --- | --- | +| net-kingdom | owns this standard, the type directory, the schema and the composer; admits and retires types | +| ops-mason | materializes OpenBao structure for cases from type templates; proposes the type's materialization section | +| ops-warden | follows through on cases; owns the routing catalog entries a type defines; proposes the type's follow-through section | +| owning repositories (key-cape, railiance-platform, ...) | declare the playbook capabilities that types compose; own execution | +| informed-decision | presents the type's Decision Memo to the founder and records acknowledgment | +| requesters | write cases, own them, retire them | + +## 9. Boundaries + +- No secret value in a type, a case, a test or a receipt. +- This standard does not grant execution authority. Each step runs under its + owner's declared entry point and its own authentication. +- Existing hand-built instances keep working. They are adopted as cases when + their type is implemented, not rewritten in place. + +## 10. Open questions for v0.1 review + +- Where should case files live by default: with the requester, or centrally in + net-kingdom? +- Is the informed-decision Decision Memo for a type rendered from `type.yaml` + and `README.md`, or written separately? +- Which steps of the first types genuinely need an attended human login (for + example key-cape's live client configuration), and how is that minimised? diff --git a/workplans/NK-WP-0048-security-case-types.md b/workplans/NK-WP-0048-security-case-types.md new file mode 100644 index 0000000..61899c1 --- /dev/null +++ b/workplans/NK-WP-0048-security-case-types.md @@ -0,0 +1,184 @@ +--- +id: NK-WP-0048 +type: workplan +title: "Establish SecurityCaseTypes so that known security cases are light" +domain: infotech +repo: net-kingdom +status: ready +flavor: implementation +owner: claude-code +topic_slug: netkingdom +created: "2026-10-08" +updated: "2026-10-08" +depends_on: [] +related_repos: + - ops-mason + - ops-warden + - key-cape + - railiance-platform + - informed-decision +--- + +# NK-WP-0048 - Establish SecurityCaseTypes so that known security cases are light + +## Why + +The founder's direction (2026-10-08): setting up a security integration of a +kind that has been done before should be easy, meaning accept the case, then +ops-mason arranges it and ops-warden follows through. Setting up a new kind +needs ample documentation and tests and an informed-decision, because its shape +is part of the security architecture. + +Today every integration is hand-built: per-client helper scripts, per-lane +custody, founder checklists. The trigger was KEY-WP-0038 (Forgejo as an OIDC +client), whose next step was going to be yet another hand-written rollout +script. + +This plan continues the pattern work of NK-WP-0008 (pattern infospace), +NK-WP-0009 (tutorials) and NK-WP-0030 (scenario composition). It turns patterns +into **SecurityCaseTypes** that ops-mason and ops-warden can execute. Canon: +`canon/standards/security-case-types_v0.1.md` (proposed). + +Companion plans: ops-mason `MASON-WP-0010` (materialization) and ops-warden +`WARDEN-WP-0044` (follow-through). + +## Tasks + +```task +id: NK-WP-0048-T01 +status: wait +needs_human: true +blocking_reason: "The founder reviews and accepts the security-case-types_v0.1 canon proposal." +priority: high +``` + +### T01 — Accept the terminology and the canon + +Founder review of `canon/standards/security-case-types_v0.1.md`, including its +section 10 open questions. On acceptance the canon status goes from `proposed` +to `accepted`. + +```task +id: NK-WP-0048-T02 +status: todo +priority: high +``` + +### T02 — Inventory the de-facto types already built by hand + +Read-only. List every security integration built so far and group them by shape. +Known starting points: + +- browser OIDC relying parties on key-cape: informed-decision-approver, + coulomb-social, user-engine portal, openbao-admin, and Forgejo (pending) +- confidential service clients with `client_credentials`: secrets-engine + approval, requester and openbao clients, approval-engine operator +- workload KV read lanes on OpenBao: the railiance-platform credential lane + designs and CCRs, for example `railiance-backup-offsite-lane` +- short-lived SSH certificates through ops-warden (`warden sign`) +- tunnelled operator access (ops-bridge) + +For each: the repositories involved, the hand-built steps, attended human steps, +custody paths, verification evidence, and rollback (if any). Output +`docs/security-case-type-inventory.md`, ranking candidate types by how often the +shape recurs and how much manual work each instance costs today. + +```task +id: NK-WP-0048-T03 +status: wait +depends_on: [NK-WP-0048-T01] +blocking_reason: "The schema and template follow the accepted canon." +priority: high +``` + +### T03 — Schema, template and validator + +- `canon/schemas/security-case-type_v0.1.schema.json` and + `security-case_v0.1.schema.json` +- `security-case-types/_template/` with `type.yaml`, `README.md` and tests to copy +- a validator, extending `tools/security-scenario-composer/`, that checks a type, + checks a case against its type, and renders the case into the composer's + deterministic plan (still `execution.permitted: false`) + +Acceptance: the validator rejects missing sections, secret-shaped parameter +values, unpinned providers and cases against non-`implemented` types, with tests +for each. + +```task +id: NK-WP-0048-T04 +status: wait +depends_on: [NK-WP-0048-T02, NK-WP-0048-T03, MASON-WP-0010-T01, WARDEN-WP-0044-T01] +blocking_reason: "The first type needs the inventory, the template, and ops-mason/ops-warden's sections." +priority: high +``` + +### T04 — Define the first type: browser OIDC relying party + +`security-case-types/oidc-browser-relying-party/`, version 1.0: + +- parameters: client id, display name, exact redirect URIs, scopes, client type + (confidential or public), MFA pin, the groups the consuming service maps, + custody path for the secret (confidential only), consuming service and its + owner +- composition: key-cape client registration (key-cape declares it as a playbook + capability), secret minting into custody (railiance-platform), LLDAP group + existence and membership (net-kingdom identity-provisioner), handover to the + consuming service +- materialization (ops-mason) and follow-through (ops-warden) sections +- verification: discovery lists the redirect URI; a test sign-in returns the + expected claims for one human; anonymous access to the custody path is denied +- rollback: remove exactly this client and its custody path +- README: threat model, MFA rationale, why redirect URIs are exact, which steps + still need an attended login and how that is minimised +- reference instances: informed-decision-approver, coulomb-social, user-engine + portal, openbao-admin + +Acceptance: complete per canon section 3, tests green, status `proposed`. + +```task +id: NK-WP-0048-T05 +status: wait +depends_on: [NK-WP-0048-T04] +needs_human: true +blocking_reason: "A new SecurityCaseType is acknowledged as an informed-decision by the founder." +priority: high +``` + +### T05 — Acknowledge the type through informed-decision + +Prepare the Decision Memo from the type's README and `type.yaml` and submit it +through informed-decision's production intake. On acknowledgment the type +moves to `acknowledged`. + +```task +id: NK-WP-0048-T06 +status: wait +depends_on: [NK-WP-0048-T05, MASON-WP-0010-T03, WARDEN-WP-0044-T03] +blocking_reason: "Implementation needs the acknowledged type and both executors' light paths." +priority: high +``` + +### T06 — First KnownSecurityCase: Forgejo + +Write `security-cases/forgejo-netkingdom-oidc.yaml` from the parameters the +founder accepted in KEY-WP-0038-T01 (`key-cape/docs/forgejo-oidc-client-request.yaml`), +so that acceptance carries over as the case acceptance. ops-mason materializes it; +ops-warden follows through and verifies it. The type becomes `implemented` once +this reference case is live. + +This replaces the hand-built path proposed for KEY-WP-0038-T02. + +```task +id: NK-WP-0048-T07 +status: wait +depends_on: [NK-WP-0048-T06] +blocking_reason: "The next types follow once the first one is proven end to end." +priority: medium +``` + +### T07 — Queue the next types + +From the T02 ranking, open the next type drafts (likely the confidential service +client and the workload KV read lane), each to be acknowledged on its own. +Record which existing hand-built instances get adopted as cases, without +rewriting them in place.