--- id: WARDEN-WP-0032 type: workplan title: "Security zones — scope enforcement to bands of differing rigidity" 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. This workplan builds the thing it defers to. ## The problem in one paragraph ops-warden has three posture axes already: environment (`dev`/`test`/`prod`, WP-0015), workload maturity (`M0`–`M3`, WP-0015), and organization posture (`build`, WP-0029). What it does not have is a way to say *"this band of the estate is enforced, that one is advisory"* — so every enforcement control it ships is a repo-wide boolean. `policy.enabled` is the first one to actually become flippable, and flipping it would harden the access needed to perform the refactors currently underway. The axes describe posture; nothing acts on them. ## What a zone has to answer A zone is only useful if it decides something. Minimum: - **Membership** — what puts a lane, actor, or workload in this zone? Derived from the existing axes where possible rather than a fourth hand-maintained list. - **Enforcement stance per control** — for each gate (pre-sign policy, agent read-boundary, high-risk refusal): enforced, advisory, or exempt. - **Failure mode** — fail-closed or fail-open, per control per zone. This is the actual bite: `fail_closed` is what makes a dead tunnel an outage. - **Who may change it, and how it is observed** — a zone that can be quietly widened is not a boundary. ## Open questions to settle before designing - Is a zone a property of the **actor** (`adm`/`agt`/`atm`), the **lane** (catalog entry), the **workload**, or the **moment** (an active refactor)? The CoulombCore decommission suggests the last one matters and is the hardest to model — a time-boxed relaxation is a different object than a standing zone. - Do zones compose with the three existing axes, or replace one? A fourth independent axis multiplies states; folding `organization_posture` in may be the honest move. - Is this ops-warden's model to own at all, or NetKingdom canon that ops-warden consumes? ADR-0005 says implement narrowly and route broadly. A security zone model that only ops-warden honours is worth much less than one flex-auth, secrets-engine, and tenant-engine also read — but ops-warden should not absorb an estate-wide model on its own authority either. **Settle this first**; it changes who writes the rest. ## Tasks ```task id: WARDEN-WP-0032-T01 status: todo priority: high ``` **Decide ownership before designing.** Take the third open question to net-kingdom (canon) and flex-auth (the PDP that would enforce it). If it is canon, ops-warden drafts and offers, as it did for the WP-0015 maturity model, and consumes the result. If it is ops-warden's, say so explicitly and record why. Do not build a model whose owner is unsettled. ```task id: WARDEN-WP-0032-T02 status: todo priority: high ``` **Name the zones against reality, not in the abstract.** Walk the current estate — the 27 catalog lanes, the actor inventory, the workloads with posture descriptors — and see what bands actually exist. A zone model that does not partition today's lanes cleanly is wrong, and the exceptions are the interesting part. Include the refactor case explicitly: what zone is a lane in while the component it fronts is being rebuilt? ```task id: WARDEN-WP-0032-T03 status: todo priority: high ``` **Model enforcement stance and failure mode per zone per control,** covering 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). Each must be expressible as enforced / advisory / exempt with an explicit failure mode. ```task id: WARDEN-WP-0032-T04 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. Ship the migration in the same change as the deprecation — leaving both is exactly the second-source-of-truth failure ADR-0001 exists to prevent. ```task id: WARDEN-WP-0032-T05 status: todo priority: medium ``` **Close WARDEN-WP-0031 T05 through this model** — enable the pre-sign gate for whichever zone the SSH signing lane lands in, with that zone's failure mode. Re-run `scripts/check_policy_caller_identity.py` first; the WP-0031 evidence will be stale by then and re-establishing it is cheap by design.