Expands the placeholder into a real plan, grounded in what the estate already has rather than first principles: - tenancy-posture_v0.1 is the structural model to follow (canon standard + per-repo declaration + "accuracy, not altitude"), and its §14 adoption stance is "structure, not tooling" — a precedent about sequencing. - Reefs are substrate placement zones with real risk statements. A security zone is not a reef; repo-manager's own "topology is not readiness" applies here as "placement is not posture". - flex-auth is latency-critical and already consumes a compiled registry snapshot, so zone membership should reach the PDP by compilation rather than a synchronous lookup in the decision path. - warden plan already returns verdicts with reasons; zone-aware enforcement extends that machinery instead of growing a parallel one. T01 settles ownership before any modelling, because it decides which repo the rest lives in: canon standard, a zone-engine runtime authority, or flex-auth policy data. The recommendation is canon-first with zone-engine named as an explicit promotion — but the time-boxed refactor exception is the case that could justify an engine immediately, since an expiring grant is state and state wants an owner. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
234 lines
10 KiB
Markdown
234 lines
10 KiB
Markdown
---
|
||
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.
|