docs: reconcile delivered scope with intent

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a0291a-1e87-7151-9934-fcbfe3f65eb1
This commit is contained in:
tegwick 2026-08-23 10:42:12 +02:00
parent d6e74a55f6
commit 5ce5117506
2 changed files with 189 additions and 130 deletions

212
SCOPE.md
View file

@ -1,159 +1,111 @@
# SCOPE
> What this repository is about, when it is relevant, and when it is not.
> The argument for its existence is `INTENT.md`; the checkable gates and the
> What this repository can do, when it is relevant, and when it is not.
> The argument for its existence is `INTENT.md`; the completed gates and the
> retirement condition are `GOAL.md`.
---
## One-liner
Authority for security zones — the bands of enforcement rigidity that scope
*where* a control bites, and the lifecycle of time-boxed exceptions that relax
them during deep refactors without leaving a permanent hole.
`zone-engine` is the model-owner and reference-conformance repository for
NetKingdom security-zone identity, membership, admission, and time-boxed
exception semantics. It does **not** run an engine or make policy decisions.
---
## Current lifecycle
## Why this exists
The repository's only workplan, `ZONE-WP-0001`, is finished and has `DoD-Ok`.
All seven tasks are done. The standard is published in `net-kingdom`, two
workload owners have adopted it, a third repository has read the declarations,
ops-warden's global policy switch is retired, and the no-runtime decision is
recorded.
Enforcement controls in this estate have been repo-wide booleans. ops-warden's
flex-auth pre-sign gate (`policy.enabled` with `fail_closed: true`) was the
first to become flippable, and flipping it would have made flex-auth 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.
Those facts satisfy `GOAL.md`'s success gates and retirement condition. This
repository is therefore **complete and an archive candidate**, not an active
service backlog. Keeping it writable is useful only while the estate wants a
reference implementation and the evidence history here; canon remains the
published source for consumers.
Across an estate under continuous deep refactor, uniform enforcement hardens
exactly the access needed to perform the refactor. The flip was deferred under
ops-warden's `ADR-0006`*enforcement is zone-scoped, never a global flag*
and this repo is what that ADR defers to.
## Capability actually present
---
This repository contains:
## In scope
- the source model and local draft of `security-zones_v0.1`, including the five
zone ids, workload authority boundary, admission semantics, and the initial
owner-qualified control profile;
- the decision record for time-boxed exceptions, including grant authority,
maximum duration, decision-time expiry, durable-authority bounds, and audit
requirements;
- estate-partition and adoption evidence showing the model against the real
inventory and its use by `ops-warden` and `flex-auth`;
- an offline reference resolver, `tools/resolve_zones.py`, which reads one or
more local `tenancy.yaml`-shaped YAML documents, including single-service and
`services:` forms;
- validation of direct workload identity bindings, required membership fields,
review dates, maturity/context floors, and continuity evidence;
- deterministic `satisfied`, `unsatisfied`, or `unknown` admission results,
with no membership inference; and
- a resolved zone, declaration-content digest, and reference projection of the
initial control profile, covered by eight unit tests.
- **Zone identity and admission standards.** What zones exist, and the standard
a **workload** must meet to be admitted to one. Security policy is about the
running workload and whoever answers for it — the repo providing the software
only *suggests*. A zone is a floor a workload qualifies against, not a label
applied to it, and it is the `tenancy-posture` Decision 8.2 tier-minimum
mechanism rather than a new one.
- **Time-boxed exception lifecycle.** A relaxation with an expiry enforced by
something rather than intended, plus the record of who widened what, when,
and until when. **This is the task that decides whether this repo needs a
runtime at all.**
- **The membership declaration**, carried in each repo's `tenancy.yaml` under
the reserved top-level `zones:` key, with `tenancy-posture_v0.1` §6 carried
over verbatim: *accuracy, not altitude*.
- **Drafting the canon standard**, offered to `net-kingdom` for publication in
the family of `tenancy-posture_v0.1` and the `*-engine` boundary contracts.
- **Naming stance vocabulary**`enforced` / `advisory` / `exempt` — as
something owners express, not as something this repo evaluates.
The resolver is a **reference and adoption-proof tool**, not a complete
production compiler. In particular, it accepts already-located declarations;
it does not discover the estate or resolve Repo Manager's cross-repository
`(rapp_id, workload_identity.name, deployable?)` references. Its control rows
are a snapshot of the accepted v0.1 profile, not an authority that can override
the versioned policy and PEP configuration owned by `flex-auth` and
`ops-warden`.
## Out of scope
## Authority boundary
- **Authorization decisions.** `flex-auth` is the PDP and stays the only one.
- **Stance for controls flex-auth decides.** Settled on review: for the
pre-sign gate, stance lives in a flex-auth **policy package**, not in
compiled membership. flex-auth's decision envelope stamps
`matched_policy_version` and `policy_package`, and registry content appears
nowhere in that provenance — stance in the registry would let two decisions
with the same policy version and the same request differ, with nothing in the
audit trail explaining why. **Membership is ours; stance is theirs.**
- **The fail-open / fail-closed axis.** Also settled on review: a PDP returns
an effect. Fail-open describes what a *policy enforcement point* does when
the PDP is unreachable — no decision is rendered, so no compiled data and no
policy rule can reach it. The failure-mode axis is modelled PEP-side, by the
repo that owns the control.
- **`organization_posture`.** Ruled out of the declaration by canon: a
fleet-wide, time-varying scalar describing the estate is not a property of a
declaring service, and a per-repo copy of a global goes stale in as many
places as there are repos. It is an **input** to stance selection, read by
the model, never absorbed into it.
- **Network segmentation.** "Zone" is overloaded; the routing sense is someone
else's word.
- **Substrate placement.** Reefs are `repo-manager`'s. That
`reef-railiance` is single-node and therefore *caps availability* for
everything bound to it is a canon composition defect (`NK-WP-0027`), not a
zone problem — and zone-engine is explicitly not blocked on it.
- **Identity, secrets, tenancy**`key-cape`, OpenBao / `secrets-engine`,
`tenant-engine`.
- **Implementing anyone's controls.** Owners keep them; this model says where
they bite.
- **Publishing canon.** `net-kingdom` owns canon; `policy-nexus` publishes.
---
## Settled by review (2026-08-19)
`ZONE-WP-0001` was reviewed by both affected owners before any modelling began.
Their answers are binding on this repo and are recorded in the workplan.
| Question | Answer | Ruled by |
| Concern | Authority | This repository's role |
| --- | --- | --- |
| A new standard, or a seventh axis of `tenancy-posture_v0.1`? | **Separate standard.** The six axes are ladders where higher is stronger and desirable; enforcement stance is not monotone — `ADR-0006` *is* the finding that the top rung is wrong for the SSH lane. And an accurately declared `exempt` as an axis would be conformant *and* exempt: a conformance rule handing out its own exemption. | net-kingdom, Decision 5.6 |
| Then where is membership declared? | **`tenancy.yaml`, reserved top-level `zones:` key.** One declaration surface, one review cadence, one validator; two standards, because they have different owners and different conformance semantics. | net-kingdom, Decision 5.6 |
| Does membership need a flex-auth schema change? | **No.** Resource `metadata` / `labels` / `attributes` are already flattened into the Rego input, so a compiler emitting a zone field is readable today. | flex-auth |
| Is "never synchronously in a decision path" the right invariant? | **No** — that is a latency guarantee, not an authority one. Replaced: identity and membership here, effect in a flex-auth policy package. | flex-auth |
| Are reefs ours to reconcile? | **No**, and the attempt surfaced a canon defect instead (`NK-WP-0027`). | net-kingdom |
| Workload identity and requested membership | Workload's responsible repo | Defines and reference-validates the contract |
| Zone ids and admission standard | zone-engine model, published by net-kingdom | Maintains the source model and conformance evidence |
| Canon publication | net-kingdom | Offers source material; does not publish canon |
| Control stance | Owner of the control | Records the vocabulary and an owner-qualified reference profile |
| Failure behavior | Owner of the policy enforcement point | Records semantics only |
| Authorization effect | Existing PDP or control owner | Makes no decision |
| Exception grant and expiry | Control owner's designated authority and enforcement point | Standardizes the lifecycle; stores or evaluates no grant |
### Two constraints inherited from that review
The invariant remains: **membership is ours; stance is theirs; the decision
point is neither.** `flex-auth` remains the only PDP for decisions it renders.
- **`trust_zone` already exists inside the PDP, and is dead.**
`ops-warden/scripts/build_flex_auth_registry.py` hardcodes
`"trust_zone": "platform"` on every ssh-cert resource; it reaches the Rego
input and **no policy rule reads it**. This repo's own warning about "zone"
being overloaded named network segmentation as the hazard; the live collision
is a dormant, plausibly-named field sitting exactly where membership would go.
The compiler must resolve it — reuse or rename, deliberately.
- **flex-auth has no reload path.** Registry and policy are loaded once at
process start from a digest-pinned image. An exception compiled as inert
registry data therefore expires only when a human redeploys — expiry by
*intention*, which is precisely what the exception lifecycle must not be. An
exception carrying `not_after`, evaluated against decision time in policy,
does expire on its own: granting costs a redeploy, lapsing is automatic.
## Deliberately absent
---
There is no:
## Relationship to what already exists
- API, daemon, database, controller, scheduler, watch loop, or reload path;
- synchronous zone lookup in an authorization or enforcement path;
- central exception store, grant workflow, clock, or expiry evaluator;
- live policy evaluation or implementation of another repository's control;
- fleet discovery, Repo Manager reference resolution, or registry publication;
- network segmentation, reef placement, tenancy, identity, or secrets service;
or
- authority to publish canon or select a consumer's stance and failure mode.
| Mechanism | Owner | Relationship |
| --- | --- | --- |
| `tenancy-posture_v0.1` | net-kingdom canon | Sibling standard and **carrier file**. Structural model: graduated levels, per-repo declaration with evidence and review dates, accuracy over altitude |
| Environment posture + workload maturity `M0``M3` | ops-warden (WP-0015) | Candidate membership inputs |
| `organization_posture: build` | ops-warden (WP-0029) | An **input** to stance selection. Explicitly not part of the declaration |
| Reefs / `bound_reefs` | repo-manager | Separate axis. Their interaction with availability is `NK-WP-0027`, not ours |
| Compiled registry snapshot | flex-auth | How membership reaches the PDP — no schema change needed, one name collision to resolve |
| Policy package | flex-auth | Where **stance** lives for controls flex-auth decides |
| `warden plan` verdicts + `reasons` | ops-warden (WP-0029) | Existing verdict machinery to extend, not parallel |
---
## Current state (2026-08-22)
`ZONE-WP-0001` is finished. T01T05 established the model: ownership is
confirmed, the estate is partitioned, stance and failure mode are modelled, the
exception lifecycle requires **no zone-engine runtime**, and the
declaration/compiler contract is drafted. The integrated owner draft is
`docs/security-zones_v0.1.md`.
Net-kingdom Decisions 5.6.1 and 5.6.2 settle the workload boundary. Operational
execution units declare authoritative workload identity directly in
`tenancy.yaml`; absence resolves to `unknown`, never inference. The standard is
published in net-kingdom canon, and T07 proves adoption in ops-warden and
flex-auth with zone-engine compiling both declarations. No API, storage, or
synchronous lookup has been shipped because the exception lifecycle showed
that none is needed.
---
Exception expiry is enforced at decision or enforcement time by each owning
control. Adding a central runtime without new evidence would cross the decided
authority boundary and introduce an unnecessary availability dependency.
## Relevant when
- A control is about to be enabled and "enforced *where*?" has no answer
- A deep refactor needs relaxed rigidity in a band of the estate, with an expiry
- A repo is filling in the `zones:` key of its `tenancy.yaml`
- Evolving the zone identities, admission rules, or exception-lifecycle
contract before offering a corresponding canon change to `net-kingdom`.
- Checking a direct `tenancy.yaml` declaration against the v0.1 reference
admission rules.
- Reproducing the adoption evidence or using the fixtures as a starting point
for an owner-side implementation.
- Auditing why the estate chose no zone-engine runtime.
## Not relevant when
- Asking whether a specific request is allowed → `flex-auth`
- Placing a workload on a substrate → `repo-manager` reefs
- Anything about network reachability
- Determining the authoritative published rule: read `net-kingdom` canon.
- Asking whether a specific request is allowed: use `flex-auth` or the owning
control.
- Resolving a managed deployable across repositories: use the Repo Manager
workload-reference contract and an owning consumer/compiler.
- Granting, applying, or expiring an exception: use the control owner's
versioned policy or PEP configuration.
- Placing a workload on a substrate: use Repo Manager reefs.
- Making a network-routing, identity, tenancy, or secrets decision.