--- id: WARDEN-WP-0032 type: workplan title: "Security zones — bands of enforcement rigidity, and where they live" domain: infotech repo: ops-warden status: proposed owner: ops-warden topic_slug: netkingdom planning_priority: P1 depends_on_workplans: - WARDEN-WP-0015 - WARDEN-WP-0029 - WARDEN-WP-0031 created: "2026-08-19" updated: "2026-08-19" --- # WARDEN-WP-0032 — Security zones `ADR-0006` defers `policy.enabled: true` until enforcement can be scoped to a zone. This workplan builds the model it defers to, and — first — settles who owns it. ## The problem, precisely ops-warden can express *how exposed* something is and *how mature* it is. It cannot express *how rigidly this band of the estate is governed right now*. | Axis | Shipped | Answers | | --- | --- | --- | | Environment posture (`dev`/`test`/`prod`) | WP-0015 | Where does this run? | | Workload maturity (`M0`–`M3`) | WP-0015 | How ready is this workload? | | `organization_posture: build` | WP-0029 | What state is the org in? | | **Enforcement stance** | **missing** | **Is this control enforced here, and what happens when it fails?** | Because the fourth is missing, every enforcement control ops-warden ships is a repo-wide boolean. `policy.enabled` is the first to become flippable, and flipping it would make flex-auth a hard dependency of every `warden sign` — including the certificates the ops-bridge tunnels depend on, one of which carries the policy call itself. Across an estate mid-refactor that hardens exactly the access needed to perform the refactor. The three existing axes *describe*. Nothing *decides*. A zone is the object that decides. ## What already exists — do not reinvent these Four estate mechanisms are adjacent, and getting the relationships right is most of the design work. **`net-kingdom/canon/standards/tenancy-posture_v0.1.md`** — the closest structural analogue and the model to follow: six orthogonal axes, graduated levels, a per-repo declaration file (`tenancy.yaml`) carrying current / implemented / target vectors with evidence and a review date, and §6 "conformance is accuracy, not altitude". Its §14 adoption stance is *"structure, not tooling"* — a direct precedent about sequencing, and one this workplan should not quietly break. **Reefs** (`repo-manager/docs/RailianceAppDeploymentGuide.md`) — `reef-railiance`, `reef-storage`, named in a rapp's `bound_reefs`. These are **substrate** placement zones with real risk statements attached (`reef-railiance` carries a single-node/shared-control-plane residual risk requiring explicit acceptance). A security zone is *not* a reef — reef answers *where does it run*, zone answers *how rigidly is it governed* — but they are correlated, and a taxonomy that ignores reefs will fight them. Also note repo-manager's own ADR-0006: *topology is not readiness*. The same caution applies here: **placement is not posture.** **flex-auth** — the PDP, `service_class: latency-critical`, which already consumes a *compiled registry snapshot* (`registry/flex-auth/production_registry_snapshot.json`, built by `scripts/build_flex_auth_registry.py`). This matters enormously for T03: zone membership can reach the decision point by compilation, with no runtime lookup and no new service in the request path. **`warden plan`** (WP-0029) — already classifies a need as `autonomous` / `founder_required` / `unroutable` from properties of the thing, returning the `reasons` that produced the verdict. Zone-aware enforcement should extend this verdict machinery rather than grow a parallel one. ## The question that changes everything else: who owns this? Three placements are defensible. **T01 settles it before any modelling**, because the answer changes who writes T02–T05 and in which repo they live. **(a) NetKingdom canon + per-repo declaration.** A `security-zones_v0.1.md` standard beside `tenancy-posture_v0.1.md`; each repo declares its lanes' zones in a `zones.yaml` the way it already declares `tenancy.yaml`; flex-auth enforces from the compiled registry. ops-warden drafts and offers, exactly as it did for the WP-0015 maturity model. *Strongest fit to precedent; no new runtime dependency; matches "structure, not tooling".* **(b) A new `zone-engine` repo.** A runtime authority owning zone identity, membership, and lifecycle, in the family of `tenant-engine` / `user-engine` / `secrets-engine` — each of which has a boundary contract in canon. *Justified if and only if zone membership needs minting, an API other components query, or — the real candidate — **time-boxed exceptions with expiry and an audit trail of who widened what**. A standing classification does not need an engine; a relaxation that must expire probably does.* **(c) flex-auth policy data.** Zones as attributes in the policy package, no new artefact anywhere. *Cheapest, and wrong if zones must govern controls flex-auth does not evaluate — the agent read-boundary (ADR-0004) and `warden desk` escalation are ops-warden-side and would fall outside.* **Recommendation to be tested in T01, not assumed:** start at (a), and name (b) as an explicit promotion with a written trigger, rather than seeding an engine before the model exists. An empty `zone-engine` would end up defining zones by accident — through whatever its first schema happened to be — which is the failure `ADR-0001` names in a different register. The counter-argument deserves a fair hearing: if time-boxed refactor exceptions are in scope from day one, (b) may be right immediately, because an expiring grant is state and state wants an owner. Under `ADR-0005` ops-warden does not absorb an estate-wide model on its own authority. A zone model only ops-warden honours is worth much less than one flex-auth enforces and secrets-engine reads. ## Tasks ```task id: WARDEN-WP-0032-T01 status: todo priority: high ``` **Settle ownership and placement.** Take the three options above to `net-kingdom` (canon) and `flex-auth` (the PDP that would enforce), with the time-boxed-exception question stated explicitly since it is what decides between (a) and (b). Record the outcome as a decision with its reasoning — if it lands outside ops-warden, this workplan's remaining tasks move to the owning repo and ops-warden keeps only its consumer-side tasks. Deliverable: a decision record, and coordination messages sent. Do not model anything before this closes. ```task id: WARDEN-WP-0032-T02 status: todo priority: high ``` **Derive the zones from the real estate, not from first principles.** Walk the 27 catalog lanes, the actor inventory (`adm`/`agt`/`atm`), and the workloads carrying posture descriptors, and find the bands that actually exist. The test of the model is that it partitions today's estate without a residue of exceptions; the exceptions found are the most informative output. Must answer explicitly: - Is a zone a property of the **actor**, the **lane**, the **workload**, or the **moment**? The CoulombCore decommission shows the last one is real and is the hardest to model — a time-boxed relaxation is a different object from a standing zone, and conflating them produces a permanent hole with a temporary-sounding name. - Do zones **compose with or fold in** the three existing axes? A fourth independent axis multiplies states; absorbing `organization_posture` may be the honest move. - How do zones relate to **reefs**? Correlated, not identical. Say so in the model rather than leaving readers to assume either. ```task id: WARDEN-WP-0032-T03 status: todo priority: high ``` **Model stance and failure mode per zone per control.** For each control: enforced / advisory / exempt, *and* fail-closed or fail-open. The failure mode is the part with teeth — `fail_closed` is what turns a dead tunnel into an outage, and it is the reason `policy.enabled` was deferred. Controls in scope at minimum: the flex-auth pre-sign gate (`policy.enabled`, `fail_closed`), the agent read-boundary on `risk: high` lanes (`ADR-0004`), and the `warden plan` escalation verdicts (WP-0029). Prefer **compilation over runtime lookup** for anything flex-auth evaluates: it is latency-critical and already consumes a built registry snapshot. Adding a synchronous zone lookup to the decision path would be a regression dressed as an architecture. ```task id: WARDEN-WP-0032-T04 status: todo priority: high ``` **Declaration format and conformance rule.** Follow `tenancy.yaml`: a per-repo declaration, with evidence, a `reviewed` date and a `review_due`, and the §6 rule carried over — **accuracy, not altitude**. A repo declaring a stricter zone than it can evidence is the failure mode to design against, because it is the one that looks like progress. Include how a zone assignment is *changed*, and how that change is observed. A zone that can be quietly widened is not a boundary. If time-boxed exceptions exist, their expiry must be enforced by something, not by an intention. ```task id: WARDEN-WP-0032-T05 status: todo priority: medium ``` **Make `policy.enabled` zone-aware and retire the global boolean.** The successor control reads the zone of the actor being signed for and that zone's failure mode. Ship deprecation and migration in the same change — leaving both is the second-source-of-truth failure `ADR-0001` exists to prevent. This closes `WARDEN-WP-0031-T05`, cancelled under `ADR-0006`. Re-run `scripts/check_policy_caller_identity.py` first: the WP-0031 evidence (`decision:f3f7c88f9585582a`, 2026-08-19) will be stale, and re-establishing it is cheap precisely so this is a re-check rather than a re-do. ```task id: WARDEN-WP-0032-T06 status: todo priority: medium ``` **Close out honestly.** Update `SCOPE.md`, `wiki/WorkloadSecurityPosture.md`, and `wiki/PolicyGatedSigning.md`. If the model landed in canon or in another repo, `ADR-0006` gains a successor or an amendment recording where enforcement scoping now lives — ops-warden follows it rather than owning it, and the ADR must say which. ## Deliberately out of scope - **Network segmentation.** "Zone" is an overloaded word; this model is about *enforcement rigidity*, not routing or NetworkPolicy. Say so wherever the term first appears, or the two will be conflated within a quarter. - **Re-litigating the three existing axes.** They stay as they are unless T02 finds a fold-in. - **Zones for anything ops-warden does not consume**, unless T01 hands the model to an owner who needs the wider scope.