net-kingdom/workplans/NK-WP-0048-security-case-types.md

201 lines
7.6 KiB
Markdown
Raw Normal View History

---
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
state_hub_workstream_id: "e31f3f9d-0748-5137-b0a3-7b3ca46a66eb"
---
# 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
state_hub_task_id: "930ac3e9-20ec-5473-98cd-3fe8fddb730f"
```
### 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: done
priority: high
state_hub_task_id: "19c25d96-a55c-58f0-9168-3fdbc4955fc2"
```
### 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.
2026-10-08: done, `docs/security-case-type-inventory.md`. 36 of 37 CCRs are
already `request_type: workload-kv-read`, a de-facto type reviewed each time as
if it were new. Browser clients: 5 hand-built plus Forgejo, each with its own
rollout script. Confidential service clients need a registration plus two or
three KV-read CCRs each. A forge read identity is needed in bulk by
ORGREF-WP-0002-T06. Recommendation: oidc-browser-relying-party first (unblocks
the forge), workload-kv-read second (largest payoff), then forge-read-identity.
```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
state_hub_task_id: "e487975b-73b1-516c-971d-da4cbbb93063"
```
### 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
state_hub_task_id: "2fffe112-7d55-5680-9952-78d74f44f87f"
```
### 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
state_hub_task_id: "3d987d3d-0797-538b-86e4-51185a327ae2"
```
### 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
state_hub_task_id: "d9b26bcf-a7c6-59a2-92a0-f913d76a203c"
```
### 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
state_hub_task_id: "c3c9c3ae-4f23-5ba7-9e6f-e63bcf29b9f7"
```
### 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.