--- id: WARDEN-WP-0032 type: workplan title: "Adopt security zones as a consumer — retire the global policy.enabled" domain: infotech repo: ops-warden status: proposed owner: ops-warden topic_slug: netkingdom planning_priority: P1 depends_on_workplans: - WARDEN-WP-0031 created: "2026-08-19" updated: "2026-08-19" --- # WARDEN-WP-0032 — Adopt security zones as a consumer `ADR-0006` defers `policy.enabled: true` until enforcement can be scoped to a zone. **The zone model itself is no longer ops-warden's work.** It moved to `zone-engine` as `ZONE-WP-0001` on 2026-08-19, where it belongs under `ADR-0005` — ops-warden implements one lane narrowly and routes the rest, and an estate-wide enforcement model is not a lane it should absorb. What stays here is the consumer side: ops-warden was the repo whose deferred flip exposed the gap, it holds the controls the model must be able to express, and it is the first consumer the model has to satisfy. ## What ops-warden owes zone-engine Inputs, not designs. `ZONE-WP-0001-T02` derives the model from the real estate, and most of that estate is ops-warden's: - **27 routing catalog lanes** (`registry/routing/catalog.yaml`) with `risk`, `status`, and `delegation` already on each — the likeliest membership inputs. - **The actor inventory** (`adm` / `agt` / `atm`) and its TTL policy. - **The three posture axes already shipped** — environment and maturity (WP-0015), `organization_posture` (WP-0029) — including the honest answer to whether `organization_posture` should be folded into zones rather than run beside them. - **Three controls the model must be able to express**: 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. - **The compiled-registry path** (`scripts/build_flex_auth_registry.py`) — how membership can reach flex-auth without a lookup in a latency-critical decision path. ## Tasks ```task id: WARDEN-WP-0032-T01 status: todo priority: high ``` **Hand the estate inputs to `ZONE-WP-0001-T02`.** Not a design proposal — the lanes, actors, axes, and controls above, with the exceptions ops-warden already knows do not fit cleanly (the interim delegation lanes from WP-0030 are the obvious candidates: a lane covered on someone else's behalf may not sit in the same zone as one ops-warden owns outright). Include the `organization_posture` fold-in question honestly, including the case against keeping it. ```task id: WARDEN-WP-0032-T02 status: wait priority: high ``` **Replace `policy.enabled` with a zone-aware control.** Waits on `ZONE-WP-0001-T03` and `T05`. 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. Re-run `scripts/check_policy_caller_identity.py` before enabling anything: 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. This closes `WARDEN-WP-0031-T05`. ```task id: WARDEN-WP-0032-T03 status: wait priority: medium ``` **Declare ops-warden's zones** in whatever format `ZONE-WP-0001-T05` settles, alongside the existing posture descriptors. Carry the conformance rule: *accuracy, not altitude*. Declaring a stricter zone than can be evidenced is the failure mode that looks like progress. ```task id: WARDEN-WP-0032-T04 status: wait priority: medium ``` **Amend `ADR-0006`.** Once zones exist and enforcement scoping is owned by `zone-engine`, ADR-0006 must say that ops-warden *follows* the model rather than owning it — a superseding record, never an in-place edit. Update `SCOPE.md`, `wiki/WorkloadSecurityPosture.md`, and `wiki/PolicyGatedSigning.md` with it. ## Related - `zone-engine` `ZONE-WP-0001` — the model, and where this work is led from - `ADR-0006` — enforcement is zone-scoped, never a global flag - `WARDEN-WP-0031` — the deferred flip and its readiness evidence