zone-engine/INTENT.md
tegwick a34bc194dc docs: declare Engine/PIP under security-layer-model v0.7
Assent to ZONE-IN-0001 in this repository's own voice: layer Engine, role
PIP, offline reference remaining the catalogued surface. Align INTENT,
SCOPE, and GOAL with accepted statute v0.7 and companion v0.2. Record the
scope-against-intent review and open ZONE-WP-0003 for the mechanical
remainder. Do not reopen the no-runtime decision.

Assistant: grok
Assistant-Session: 01a04ceb-0745-7ae1-9e26-0d10e5d52b8b
2026-08-29 11:57:25 +02:00

256 lines
13 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
layer: Engine
role: PIP
standard: netkingdom-security-layer-model
standard_version: "0.7"
companion: net-kingdom/SECURITY-COMPANION.md
---
# INTENT
> Why `zone-engine` exists and where it is going.
> What is true today is `SCOPE.md`. Checkable gates and the retirement
> condition are `GOAL.md`. This file is the argument, not the checklist.
> **Layer: Engine. Role: PIP.** This is the declaration required by NetKingdom
> Security Layer Model v0.7 §11 and working companion v0.2. It is this
> repository's own voice. A catalog row, a review note, or the 2026-08-28
> gate-house insert that used to sit here is not a declaration.
>
> The statute is
> `net-kingdom/canon/standards/security-layer-model_v0.7.md` (accepted
> 2026-08-29). The operative form is `net-kingdom/SECURITY-COMPANION.md` v0.2.
> On disagreement the statute governs, and a disagreement is a finding for
> `gate-house`.
>
> We produce a deterministic result for one modeled concept: zone identity and
> membership. Same authoritative inputs, same result. That is the Engine test.
> The PIP role means those facts reach a decision as **claims**, not as a
> verdict. We do not render, cache, or compile an authorization decision.
>
> The §4 catalog records the 2026-08-23 disposition rather than changing it:
> the current PIP surface is **offline reference conformance**, not a live API.
> Determinism does not require a network. A live Engine API, a decision
> surface, or stance compiled into membership would each be a layer change,
> and a layer change needs the six artifacts in statute §10, including a
> permission freeze. The 2026-08-23 cut already happened; it does not reopen
> by practice.
>
> **`access-engine` is the only PDP.** It is the ruled name for the repository
> currently called `flex-auth`. This file's original §5 — *"flex-auth is the
> policy decision point. It stays the only one."* — is the ruling the layer
> model generalizes as statute §6. The §7 falsifier — a second decision point
> arriving as a small convenience — is estate doctrine. Zone stance enters a
> decision as a claim on the request or a rule in a versioned policy package,
> never as compiled registry content (statute §18).
>
> We are not PEP-shaped: this repository causes no protected side effect and
> publishes no unreachable-engine stance map. We hold no Tooling-layer client.
> Staff never touches Tooling directly; we are not Staff, and we still do not
> hold a Tooling client, because a PIP that reaches into OpenBao would be
> deciding with someone else's state.
---
## Current disposition — 2026-08-23, confirmed 2026-08-29
The argument below is retained as design history. Its desired sentence is now
sayable: the zone standard is in net-kingdom canon, ops-warden and flex-auth
have adopted it, the repo-wide switch is retired, and exception expiry is
enforced at each owning decision or enforcement point.
The runtime hypothesis was falsified. That was a layer change in practice
(statute §10 cites this case). zone-engine is retained as an Engine/PIP whose
surface is offline reference conformance while `security-zones_v0.1` remains
proposed. It is not a PDP, not a PEP, not an exception service, and not a
consumer policy owner. Current capability is `SCOPE.md`. Retain and archive
triggers are in `GOAL.md`.
The security-layer-model being accepted does not reverse that cut. It names
the cut: we are the PIP for zone identity and membership, in the form already
shipped.
## 1. The sentence this repo exists to make sayable
> *"This control is enforced **there**, advisory **here**, and relaxed **in this
> band until Friday** — and all three of those are written down, reviewable, and
> expire on their own."*
At inception NetKingdom could not say that. It could say how exposed a workload
was (environment posture), how ready it is (`M0``M3`), and what state the
organization is in (`organization_posture`). Every one of those **describes**.
None of them **decides**. So every enforcement control in the estate was a
boolean over a whole repo.
## 2. Where that bit
ops-warden built a pre-sign authorization gate, flex-auth enforced its side, and
the gate verified clean. It was deliberately not switched on until the zone
model replaced its global scope.
`policy.enabled` is one boolean over the entire repo. With `fail_closed: true`
it makes the PDP a hard dependency of *every* `warden sign` — including the
SSH certificates the ops-bridge tunnels depend on, one of which carries the
policy call itself. Turning it on would have been correct for a settled
production lane and wrong for an estate in the middle of decommissioning one
host and moving a service off it.
That is not a story about a flag. **Security that stops the work stops being
security and becomes an outage with good intentions** — and the reason it would
have was structural: there was nowhere to say *where* it applies. The decision
is ops-warden's `ADR-0006`; this repo is what it defers to.
## 3. What policy is about, and who decides
**Security policy is always about the actual workload.** Not the repository, not
the credential, not the lane — the running thing, and whoever answers for it.
That splits authority three ways, and the split is the model:
| Role | Who | Authority |
| --- | --- | --- |
| **Suggests** | The repo providing the software | Recommends a posture for running its software. It does not know where it will run, so it cannot determine |
| **Declares** | The workload and its responsible party | Sets the scrutiny actually applied. **The policy subject** |
| **Requires** | The zone | The standard a workload must meet to be admitted. A floor, not a label |
A workload is not *labelled* with a zone. It **qualifies** to run in one.
This is not a new prescription mechanism. `tenancy-posture_v0.1` Decision 8.2
already splits authority this way — the consuming repo owns its workload
requirements, a tier minimum is owned separately, and the two are **joined by
machine**, because *"a machine-checkable constraint must not depend on somebody
remembering to collect a signature."* Decision 5.6 then ruled that stance
*"behaves like a tier minimum under Decision 8.2."* The zone model's job is to
**be** that tier minimum, not to invent a second way of requiring things.
## 4. What a zone has to be, to be worth having
A classification that changes nothing is a label. A zone earns its keep only if
it decides something, so the model must carry:
- **Identity and membership** — an authoritative workload binding and its
responsible party's declared zone. Lanes, actors, paths and repositories are
inputs or caller context, never substitute policy subjects. **This is the PIP
fact this repository owns.**
- **Admission** — a mechanical reconciliation of that declaration against the
zone floor and the workload posture. Missing identity, membership or evidence
remains `unknown`; it is never inferred into a permissive zone. Same
authoritative inputs, same result.
- **Stance per control** — enforced, advisory, or exempt. **Not ours.** The
effect of a zone on a decision belongs in a versioned `access-engine` policy
package, or as a claim on the request (statute §18).
- **Failure mode** — what happens when the control cannot run. This is where
the bite is; `fail_closed` is what turns a dead tunnel into an outage. **The
PEP owner's**, declared ahead of time per statute §9.3.
- **Exceptions that expire without anyone remembering them.**
The last was the runtime hypothesis. A standing classification needs no live
engine — canon plus a declaration file covers it, which is exactly how tenancy
posture works. The implementation proved that exception state can remain with
the control owner when `not_after` is evaluated where the effect occurs. That
gives it an owner, audit trail, and enforced deadline without a central service.
## 5. The line this repo must not cross
`access-engine` (currently `flex-auth`) is the policy decision point. It stays
the only one.
zone-engine is authority over zone **identity and membership**. The **effect**
of a zone on a decision `access-engine` renders belongs in an `access-engine`
policy package, because the decision envelope stamps `matched_policy_version`
and `policy_package` — and registry content appears nowhere in that provenance.
Put stance in the registry and two decisions with the same policy version and
the same request can differ, with nothing in the audit trail explaining why.
That boundary was drawn by flex-auth on review, against a first draft of ours
that got it wrong in an instructive way: the original invariant forbade sitting
*synchronously* in a decision path, which is a latency guarantee wearing an
authority guarantee's clothes. Compiled data that determines an outcome is still
deciding; it just decided earlier. Statute §6.1 is that sentence, generalized.
**Held to, in one line: membership is ours, stance is theirs, and the decision
point is neither.**
A new engine is a PIP unless the statute is amended. We are already that PIP.
We will not become a second PDP by growing a convenient live lookup, a cached
verdict, or a profile that changes a live effect.
## 6. What success looks like from outside
These conditions are met for the adopted v0.1 path:
Someone who has never read this repo should be able to:
- open a service's `tenancy.yaml`, read its `zones:` key, and know which
controls bite it;
- ask "why was this relaxed?" and get a justification, an author and an expiry,
not a shrug;
- watch a relaxation lapse **without a human remembering it**;
- and find the rule published in NetKingdom canon rather than in this repo's
prose.
If a reader has to come here to understand their own posture, the model has
failed at being a standard and has succeeded only at being a service.
Under the layer model, the same reader should also be able to say: zone
*facts* come from this PIP; zone *effect* lives in `access-engine` policy;
unreachable-engine *behaviour* is the PEP's declared stance. Three owners,
one reconstructable decision.
## 7. What would make this repo wrong
Stated up front, because a repo created on a recommendation should say what
would falsify it:
- **The exception lifecycle turns out not to need a runtime.** This falsifier
triggered. Reviewed owner records plus decision-time expiry are sufficient.
The honest outcome is canon plus offline conformance tooling, not a live
engine. Retention is bounded to the proposed-standard reference need in
`GOAL.md`.
- **The zones do not partition the real estate.** If the model needs a residue
of special cases to cover today's 27 routing lanes and actor inventory, it is
describing an aspiration, not a structure.
- **Nobody but the author declares one.** Two repos declaring and a third
reading is the minimum evidence of a model rather than a preference.
- **It becomes a second decision point.** The failure would not announce itself;
it would arrive as a small convenience — a stance compiled into membership
"just for now", a live lookup "just for this consumer", a profile change that
alters a live effect with no policy-package revision. Statute §6 is this
falsifier, estate-wide.
## 8. What this repo deliberately will not become
Not a PDP. Not a PEP. Not network segmentation — "zone" is overloaded and the
routing sense is someone else's word. Not a placement model: reefs answer
*where a thing runs* and are Railiance's, and the fact that `reef-railiance`
caps availability for everything bound to it is a canon composition problem
(statute §20.3, originally `NK-WP-0027`), not ours. Not an owner of anyone's
controls — the controls stay with the repos that enforce them; this model only
says where they bite.
Not a live Engine API unless a later layer-change decision carries the six
§10 artifacts and obtains assent from the repositories whose boundaries move.
The catalogued offline form is the current Engine, not a temporary embarrassment.
Not an inventor of the estate request-claim schema. Statute §17 assigns that
artifact to Taxonomy. Until it exists, this PIP's resolver output is
reference-shaped membership, not a competing claim dialect.
## 9. Direction
Model first, from the real estate. Canon standard drafted here and published by
`net-kingdom`, in the family of `tenancy-posture_v0.1`. Membership declared in
the `zones:` key that canon has already reserved. Two consumers before it is
called adopted, the first being ops-warden retiring `policy.enabled`.
A runtime only if `ZONE-WP-0001-T04` proves the exception lifecycle needs one —
and the cheaper answer is a legitimate result, not a disappointment.
That direction is delivered. `ZONE-WP-0002` hardened the offline contracts and
made canon lineage, owner provenance, revision/delta evidence, and exception
fixtures executable without reopening the runtime decision.
What remains is to live inside the layer the estate has now named: declare the
PIP in a machine-readable form, keep the permission freeze, and evolve the
reference surface so zone facts can be consumed as claims when Taxonomy
publishes the schema — without growing a second decision point to get there.