From 66dc491dc02ce6b211d6ea98891aba15a53dd2d6 Mon Sep 17 00:00:00 2001 From: tegwick Date: Sat, 29 Aug 2026 11:28:49 +0200 Subject: [PATCH] Accept the security layer model; companion v0.2 to the repository root MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The standard is accepted at v0.7 on the owner's decision. §14 keeps two things apart, as ops-warden asked: boundary assent, given by four repositories at the version named in each record and undisturbed since; and revision review, where all four reviewed v0.6 and every change in v0.7 is the adopted remedy of a finding they raised. What is not claimed: nobody has reviewed v0.7 as text. Accepting a standard nobody has re-read is deliberate. The estate will learn more from using it than from another round of prose, and the v0.7 changes were requested rather than invented. Findings against the accepted text stay welcome — that is §12's normal business, not an exception. The companion moves from canon/standards to the repository root as SECURITY-COMPANION.md and becomes v0.2, so onboarding starts at the front door rather than three directories down. One copy, not two: a second copy of a fact is how the estate gets two sources for it. v0.2 closes the gap access-engine found in v0.1 — it said publish your stance map without saying where, and omitted the inventory obligation, so a repository could satisfy it faithfully and no register would learn of its stance. It also carries what v0.7 added: the corrected PEP obligations, the evidence threat decomposition with its stated residual, cadence as MUST for load-bearing sources with heartbeat for rare ones, the four agent rules and the glas-harness seam, and the Railiance axes with their unsettled mapping. It points readers at ops-warden for how to get things done. The companion says what the rules are; ops-warden stewards the paths through them. Co-Authored-By: Claude Opus 5 Assistant: claude-code Assistant-Model: opus Assistant-Process: 2564823@bnt-lap001 Assistant-Session: 2a7ed827-4928-4b9f-8613-9135c9cadfe9 --- README.md | 12 +- SECURITY-COMPANION.md | 219 ++++++++++++++++++ .../security-layer-model-companion_v0.1.md | 196 ---------------- canon/standards/security-layer-model_v0.7.md | 33 ++- 4 files changed, 246 insertions(+), 214 deletions(-) create mode 100644 SECURITY-COMPANION.md delete mode 100644 canon/standards/security-layer-model-companion_v0.1.md diff --git a/README.md b/README.md index 3235040..8d4b21e 100644 --- a/README.md +++ b/README.md @@ -12,12 +12,12 @@ The dynamic, self-optimizing security platform is the long-term direction in ## Orientation - [SCOPE.md](SCOPE.md) — what this repo owns, current state, and when it is relevant -- [Security layer model](canon/standards/security-layer-model_v0.7.md) — how the - security estate is layered (Taxonomy / Tooling / Engines / Staff) and what each - layer may own -- [Agent companion](canon/standards/security-layer-model-companion_v0.1.md) — the - operative two-page form of that standard: what to declare, what binds you, what - you may never claim +- **[SECURITY-COMPANION.md](SECURITY-COMPANION.md) — start here.** The working + form of the security layer model: what to declare, what binds you, what you may + never claim about evidence, and the two things the estate cannot do yet +- [Security layer model](canon/standards/security-layer-model_v0.7.md) — the + statute the companion serves (accepted 2026-08-29): how the security estate is + layered (Taxonomy / Tooling / Engines / Staff) and what each layer may own - [Security scenario composition](canon/standards/security-scenario-composition_v0.1.md) — deterministic, plan-only capability and trust composition - [Posture feedback](canon/standards/posture-feedback_v0.1.md) — deterministic, diff --git a/SECURITY-COMPANION.md b/SECURITY-COMPANION.md new file mode 100644 index 0000000..da470f4 --- /dev/null +++ b/SECURITY-COMPANION.md @@ -0,0 +1,219 @@ +--- +id: netkingdom-security-companion-v0.2 +type: standard-companion +title: "NetKingdom Security — Working Companion v0.2" +domain: netkingdom +status: accepted +version: "0.2" +companion_to: canon/standards/security-layer-model_v0.7.md +owner: gate-house +publication_owner: net-kingdom +created: "2026-08-29" +updated: "2026-08-29" +review_interval: 3m +standard_token: security-companion_v0.2 +--- + +# NetKingdom Security — Working Companion + +**Start here.** This is the operative form of +[`canon/standards/security-layer-model_v0.7.md`](canon/standards/security-layer-model_v0.7.md) +(accepted): the same rules, without the change log or the review history. + +The statute governs where the two disagree. **A disagreement is a finding** — +report it to `gate-house` rather than working around it. + +For *how to get something done* in NetKingdom — which lane, which credential, +which route — ask `ops-warden`. This document says what the rules are; +`ops-warden` stewards the paths through them. + +--- + +## 1. The four layers + +| Layer | You are this if you produce | Deterministic | +| --- | --- | --- | +| **Taxonomy** | terms, semantic contracts, standards | n/a | +| **Tooling** | state and persistence | yes | +| **Engine** | a deterministic API for one modeled concept | yes | +| **Staff** | specifications, decisions, workplans, tasks | **no** | + +One test decides it: **given the same authoritative inputs, do you always return +the same result?** If your core function is inference or judgment you are Staff, +however much of your work happens at runtime. + +Engines carry a role — **PDP** (decides; `access-engine` only), **PIP** +(supplies facts as claims), **Evidence** (`audit-core`), **Lifecycle** (an API +over Tooling it owns). A new engine is a PIP unless the statute is amended. + +## 2. Declare your layer + +In your `INTENT.md` frontmatter, plus prose in your own voice in the body. A +layer someone else stated about you is not a declaration. + +```yaml +layer: Staff # Taxonomy | Tooling | Engine | Staff +role: null # Engines only: PDP | PIP | Evidence | Lifecycle +``` + +Working references, both offered estate-wide: `ops-warden`'s `layer.yaml`, +`scripts/check_layer_conformance.py`, `tests/test_layer_conformance.py`; +`kings-guard`'s adaptation of the same for a repository with no Tooling +contacts at all. + +**Contest the proposed layer if it is wrong.** Three repositories have returned +corrections that changed the standard; one talked us out of an exception we had +offered. A correction is worth more than a label. + +## 3. The rules that bind everyone + +1. **One decision point.** `access-engine` renders authorization decisions. No + other repository, in any layer, renders or caches one. +2. **Compiled data that determines an outcome is still deciding.** A registry, + cache, or schema that resolves a result before the engine runs decided early. +3. **Doctrine arrives as a claim.** Anything changing an outcome — authority + ceiling, zone stance, posture, maturity level — reaches the decision as a + request claim or a versioned policy rule. Never a side channel. +4. **Adaptive systems may only tighten.** Reduce, step up, request containment; + never manufacture authority. +5. **Staff never touches Tooling directly.** Act through Engine APIs. See §4. +6. **Every allow has a lifetime** — a TTL, or a binding to a session or + obligation that ends. + +## 4. If you touch Tooling + +"Tooling" means a system catalogued as Tooling in statute §4 — today `key-cape` +and `OpenBao`. Uncatalogued infrastructure (State Hub, `llm-connect`) is outside +the rule, but **list it anyway** so your conformance check is total. That +carve-out sunsets: an uncatalogued store another layer *reads* must, within two +review intervals, be catalogued or declared a gap. + +| Shape | When | You must | +| --- | --- | --- | +| **Read-only diagnostic** | no engine exposes the read | declare it; no writes; it is a gap to close | +| **Conduit** | you run the *owner's* tool under the *caller's* identity | present no credential of your own, widen nothing, stay reconstructable as the caller | +| **Declared gap** | you must contact Tooling and no engine exposes it | declare `capability`, `intended_owner`, `blocked_on`, `review` — machine-readably | + +A conduit presenting its own token is not a conduit. A declared gap is **tracked +non-conformance** — but declaring beats hiding, and it is never scored below +silence. + +There is deliberately **no "operator of third-party Tooling" shape**. Someone +must run OpenBao, and that stays a declared gap whose review keeps returning, +because a clean operator shape would turn a tracked gap into a permanent +allowance. + +## 5. If you cause side effects (you are PEP-shaped) + +Being PEP-shaped does not change your layer. `ops-warden` issuing a certificate +and `ops-mason` opening a route are both Staff and both PEP-shaped. + +1. **No side effect without a decision record** naming the request it was + rendered for — **or** your declared stance permits proceeding and **you record + the application of that stance in its place.** A fail-open result is metadata, + never silence. +2. **Do not replay a verdict outside its own binding and lifetime.** Within them + it is the decision being used as issued. The test is mechanical: replay is + permitted iff the canonical request digest matches and the lifetime holds. + Caching a DENY is permitted where the refusal is recorded against the request + refused and the cache lifetime is declared. +3. **Publish your unreachable-engine stance map** — total, per zone or + equivalent, no implicit default, no per-call discretion. **Publish it at a + path named in your layer declaration, and register it in statute §13.1** — a + map only you can read is not published. The published map MUST equal shipped + behaviour; assert that with a test. Reference: `ops-warden` + `ADR-0009` + `pep-stance.yaml`. +4. **Stay reconstructable**, within the bound in §6. + +If `access-engine` is reachable but degraded, the fallback is the engine's. If it +is unreachable, the behaviour is necessarily yours — which is why it is declared +in advance rather than decided in the moment. + +## 6. What you may never claim about evidence + +An append-only archive with a verified chain proves records were **not altered or +truncated after arrival**. It proves nothing about an event never sent. + +- ✗ "the audit record proves it happened" +- ✗ "there is no record, so it did not happen" +- ✓ "the archive proves the records it holds were not altered or truncated after arrival" + +Which control covers which threat: + +| Threat | Covered by | +| --- | --- | +| Accidental omission (crash between mutation and emit) | atomic emission via a **local** outbox — **prevented** | +| Adversarial omission (a compromised source suppresses) | cadence and reconciliation — **detected after the fact** | +| Adversarial omission at a compromised source | **nothing prevents it.** Known residual | + +If a control's soundness depends on an event being present, that evidence is +**load-bearing**: emission must be atomic with the state change, queued locally, +and you **MUST** declare an expected cadence. For rare load-bearing events — +revocations, denials, containment — rate monitoring cannot work, so the required +form is **reconciliation or a heartbeat**: a positive claim that can itself go +missing. + +Otherwise evidence is **attributive**: seek atomicity, and if you trade it away +deliberately, declare the trade and never describe the trail as complete. + +## 7. If you are an agent + +Same layer as your human colleagues, different blast radius: + +1. **No standing credential.** Authority is per task, time-bounded, attributable + to the principal you act for. +2. **Tool use is a conduit or an Engine API.** There is no third route. **Tool + availability is not permission** — a callable tool means the operation exists, + not that you may invoke it. +3. **Your memory is not a state plane.** Memory, tool-call traces, and prompt + caches must not become state another layer depends on unless catalogued. +4. **Every action is reconstructable as the caller's action.** + +Session semantics — session loops, tool policy, harness routing, model selection +— are `glas-harness`'s, not this standard's. Rule 2 is the seam between them, and +neither side is sufficient alone. + +## 8. Conformance: four states + +| State | Meaning | +| --- | --- | +| **Conforming** | no Tooling contact, or only declared diagnostic/conduit shapes | +| **Blocked-clean** | the capability does not exist because no engine exposes it, and you make no Tooling contact | +| **Declared gap** | a declared Tooling contact — tracked non-conformance | +| **Undeclared violation** | anything else | + +**Blocked-clean is not worse than conforming.** Declining a shortcut and leaving +a capability at zero is compliance at cost, and will never be ranked below a +repository that quietly opened a client and said nothing. + +## 9. If you operate workloads (Railiance) + +Operations belong to **Railiance** (`railiance-master`), not to NetKingdom. A +workload is a managed running deployable, operated through four axes: +`railiance-*` ownership, `rail-*` execution contract, `rapp-*` managed package, +`reef-*` substrate. `rein-*` is **not** a fifth axis — reins are `glas-harness` +agent-harness backends. + +What holds for any Railiance consumer of NetKingdom security: decisions come from +`access-engine` and nowhere else; approvals are objects in `approval-engine` +consumed as claims; credentials come from `secrets-engine` **after** a decision; +evidence goes to `audit-core` under §6's bound; anything causing a protected side +effect is PEP-shaped and owes §5. + +**How the axes map onto the layer model is not settled** — see statute §20.3. Do +not assume a mapping; raising the question is welcome. + +## 10. Two things the estate cannot do yet + +Stated so nobody plans around a capability that does not exist: + +- **Nothing is observed in production.** `kings-guard` has reported it has never + seen a real event. Do not cite "observed in operation" as evidence. +- **Nothing can be contained automatically.** There is no actuation surface — no + API to reduce authority, require step-up, or isolate a workload. The capability + is at zero, not degraded, and it is nobody's gap to close alone. + +--- + +**Statute:** [`canon/standards/security-layer-model_v0.7.md`](canon/standards/security-layer-model_v0.7.md) — accepted 2026-08-29. +**Owner:** `gate-house`. **Guidance on getting things done:** `ops-warden`. diff --git a/canon/standards/security-layer-model-companion_v0.1.md b/canon/standards/security-layer-model-companion_v0.1.md deleted file mode 100644 index 5b5d8fe..0000000 --- a/canon/standards/security-layer-model-companion_v0.1.md +++ /dev/null @@ -1,196 +0,0 @@ ---- -id: netkingdom-security-layer-model-companion-v0.1 -type: standard-companion -title: "NetKingdom Security Layer Model — Agent Companion v0.1" -domain: netkingdom -status: proposed -version: "0.1" -companion_to: canon/standards/security-layer-model_v0.7.md -owner: gate-house -publication_owner: net-kingdom -created: "2026-08-29" -updated: "2026-08-29" -review_interval: 3m -standard_token: security-layer-model-companion_v0.1 ---- - -# Security Layer Model — Agent Companion - -**This is the operative form of `security-layer-model_v0.7.md`.** Same rules, no -change log, no review history. The statute governs where the two disagree; if you -find a disagreement, report it — that is a finding, not a formatting problem. - -Read this if you are an agent or an operator working in a NetKingdom repository, -or if your repository has been asked to declare its layer. - ---- - -## 1. The four layers - -| Layer | You are this if you produce | Deterministic | -| --- | --- | --- | -| **Taxonomy** | terms, semantic contracts, standards | n/a | -| **Tooling** | state and persistence | yes | -| **Engine** | a deterministic API for one modeled concept | yes | -| **Staff** | specifications, decisions, workplans, tasks | **no** | - -One test decides it: **given the same authoritative inputs, do you always return -the same result?** If your core function is inference or judgment, you are Staff -— however much of your work happens at runtime. - -Engines carry a role: **PDP** (decides — `access-engine` only), **PIP** -(supplies facts as claims), **Evidence** (`audit-core`), **Lifecycle** (an API -over Tooling it owns). A new engine is a PIP unless the statute says otherwise. - -## 2. Declare your layer - -Put this in your `INTENT.md` frontmatter. A layer someone else stated about you -is not a declaration. - -```yaml -layer: Staff # Taxonomy | Tooling | Engine | Staff -role: null # Engines only: PDP | PIP | Evidence | Lifecycle -``` - -Then state it in prose, in your own voice, in the body. Contest the proposed -layer if it is wrong — a correction is worth more than a label. - -Reference implementation of the machine-readable form: `ops-warden`'s -`layer.yaml`, `scripts/check_layer_conformance.py`, and -`tests/test_layer_conformance.py`. - -## 3. The rules that bind everyone - -1. **One decision point.** `access-engine` renders authorization decisions. No - other repository, in any layer, renders or caches one. -2. **Compiled data that determines an outcome is still deciding.** A registry, - cache, or schema that resolves a result before the engine runs has decided - early. -3. **Doctrine arrives as a claim.** Anything that changes an outcome — an - authority ceiling, a zone stance, a posture, a maturity level — reaches the - decision as a request claim or a versioned policy rule, never by a side - channel. -4. **Adaptive systems may only tighten.** Reduce authority, require step-up, - request containment — never manufacture authority. -5. **Staff never touches Tooling directly.** It acts through Engine APIs. See §4. -6. **Every allow has a lifetime.** A TTL, or a binding to a session or - obligation that ends. - -## 4. If you touch Tooling - -"Tooling" means a system catalogued as Tooling in the statute's §4 — today -`key-cape` and `OpenBao`. Uncatalogued infrastructure (the State Hub, -`llm-connect`) is outside this rule, but list it anyway so your check is total. - -Three sanctioned shapes. Anything else is a violation: - -| Shape | When | You must | -| --- | --- | --- | -| **Read-only diagnostic** | no engine exposes the read | declare it; no writes; treat it as a gap to close | -| **Conduit** | you run the *owner's* tool under the *caller's* identity | present no credential of your own, widen nothing, stay reconstructable as the caller | -| **Declared gap** | you must contact Tooling and no engine exposes it | declare `capability`, `intended_owner`, `blocked_on`, `review` — machine-readably | - -A conduit that presents its own token is not a conduit. A declared gap is -**tracked non-conformance**, not conformance — but declaring it is always better -than hiding it, and it will never be scored below silence. - -## 5. If you cause side effects (you are PEP-shaped) - -Being PEP-shaped does not change your layer. `ops-warden` issuing a certificate -and `ops-mason` opening a route are both Staff and both PEP-shaped. - -1. **No side effect without a decision record** naming the request it was - rendered for. -2. **Never cache the verdict.** Caching an input claim under its own freshness - rule is fine; caching the answer is a second decision point. -3. **Publish your unreachable-engine stance** — total, per zone or equivalent, - no implicit default, no per-call discretion. Reference shape: `ops-warden` - `ADR-0009`. -4. **Stay reconstructable**, within the bound in §6. - -If `access-engine` is reachable but degraded, the fallback is the engine's. If it -is unreachable, the behaviour is necessarily yours — which is why it must be -declared in advance rather than decided in the moment. - -## 6. What you may never claim about evidence - -An append-only archive with a verified chain proves records were **not altered -or truncated after arrival**. It proves nothing about an event never sent. - -- ✗ "the audit record proves it happened" -- ✗ "there is no record, so it did not happen" -- ✓ "the archive proves the records it holds were not altered or truncated after arrival" - -The event an adversary most wants missing is the negative one — a revocation, a -denial, a containment action. If a control's soundness depends on an event being -present, that evidence is **load-bearing** and its emission must be atomic with -the state change, queued locally. Otherwise it is **attributive**: seek -atomicity, and if you trade it away deliberately, declare the trade and never -describe the trail as complete. - -If you emit adaptive-relevant events, publish an expected cadence. A drop below -it is a finding. Silence is a signal. - -## 7. If you are an agent - -Same layer as your human colleagues, different blast radius: - -1. **No standing credential.** Authority is per task, time-bounded, attributable. -2. **Tool use is a conduit or an Engine API.** There is no third route. -3. **Your memory is not a state plane.** Memory, tool-call traces, and prompt - caches must not become state another layer depends on unless catalogued. -4. **Every action is reconstructable as the caller's action.** - -Tool availability is not permission. A tool being callable says the operation -exists, not that you may invoke it. - -## 8. Conformance: four states - -| State | Meaning | -| --- | --- | -| **Conforming** | no Tooling contact, or only declared diagnostic/conduit shapes | -| **Blocked-clean** | the capability does not exist because no engine exposes it, and you make no Tooling contact | -| **Declared gap** | a declared §5.3 contact — tracked non-conformance | -| **Undeclared violation** | anything else | - -**Blocked-clean is not worse than conforming.** Declining a shortcut and leaving -a capability at zero is compliance at cost. It will never be ranked below a -repository that quietly opened a client and said nothing. - -## 9. Consuming NetKingdom security from outside - -Operations is **HelixForge's** responsibility — its reef, rail, rapp, and rein -concepts — and NetKingdom provides the security and approval framework those -operations consume. - -**That interface is not specified yet.** What holds today is only what holds for -any consumer: authorization decisions come from `access-engine`, approvals are -objects in `approval-engine` consumed as claims, credentials are materialized by -`secrets-engine` after a decision, and evidence goes to `audit-core` under the -bound in §6. A HelixForge component that causes a protected side effect is -PEP-shaped and §5 applies to it. - -What is **not** settled: how a reef, rail, rapp, or rein maps onto the layer -model — whether they are subjects a decision is rendered about, principals that -request, PEP-shaped consumers, or none of these. Until that is written, do not -assume a mapping. Raising it is welcome. - -## 10. Two things the estate cannot do yet - -Stated so nobody plans around a capability that does not exist: - -- **Nothing is observed in production.** `kings-guard` has reported that it has - never seen a real event. Do not cite "observed in operation" as evidence. -- **Nothing can be contained automatically.** There is no actuation surface — - no API to reduce authority, require step-up, or isolate a workload. The - capability is at zero, not degraded. - ---- - -**Statute:** `canon/standards/security-layer-model_v0.7.md`. -**Known gap in this version:** §5.3 says publish your stance map but not *where*, -and omits the statute's §6.4 inventory obligation — a repository could satisfy -this document and no register would learn of its stance. Fixed in v0.2; until -then read statute §6.4 and §13.1. -**Owner:** gate-house. **Report a disagreement between this and the statute as a -finding.** diff --git a/canon/standards/security-layer-model_v0.7.md b/canon/standards/security-layer-model_v0.7.md index e4e162c..fdc231e 100644 --- a/canon/standards/security-layer-model_v0.7.md +++ b/canon/standards/security-layer-model_v0.7.md @@ -3,7 +3,7 @@ id: netkingdom-security-layer-model-v0.7 type: standard title: "NetKingdom Security Layer Model v0.7" domain: netkingdom -status: proposed +status: accepted version: "0.7" supersedes: canon/standards/security-layer-model_v0.6.md owner: gate-house @@ -986,9 +986,21 @@ do while the register is nearly empty. ## 14. Adoption -Status is **proposed** — the frontmatter is authoritative, and v0.2 was the last -version to reach `accepted`. Four repositories have assented, each with a record, -and all four returned findings on the versions since: +Status is **accepted**, on the owner's decision of 2026-08-29. + +Two things that acceptance does and does not mean, kept apart because +`ops-warden` asked for the distinction: + +| | | +| --- | --- | +| **Boundary assent** | given by the four repositories below, at the version named in each record, and undisturbed since | +| **Revision review** | each of the four reviewed v0.6 and returned findings; **every change in v0.7 is the adopted remedy of a finding they raised** | +| **Not claimed** | no repository has reviewed v0.7 *as text*. The first revision review will confirm or correct it | + +Accepting a standard nobody has re-read is a deliberate call: the estate learns +more from using it than from another round of prose refinement, and the changes +in v0.7 were requested rather than invented. Findings against the accepted text +remain welcome and are §12's normal business, not an exception. | Repository | Record | Outcome | | --- | --- | --- | @@ -1218,14 +1230,11 @@ v0.3 → v0.4: text it grades. Raised by `access-engine`. Its two substantive points remain live: observation in production is unstaffed (§12) and actuation has no surface (§9.2). -- The **agent companion** (`security-layer-model-companion_v0.1.md`) is the - operative form of this statute. The statute governs on disagreement, and a - disagreement is a finding. Its §5.3 omits where a stance map is published and - omits the §6.4 inventory obligation entirely — a repository could satisfy the - companion faithfully, publish into its own repo, believe itself conforming, and - no register would learn of it. Raised by `access-engine` in answer to the - question of what would show the companion insufficient. To be fixed in - companion v0.2. +- The **working companion** (`net-kingdom/SECURITY-COMPANION.md`, v0.2, root of + the repository for onboarding) is the operative form of this statute. The statute governs on disagreement, and a + disagreement is a finding. The v0.1 gap `access-engine` found — publish + your stance map, but nowhere saying where, and no inventory obligation — is + fixed in v0.2 §5.3. - How the Railiance operational axes meet this model beyond §20's first statement, which is deliberately minimal.