From 11af8095ae1a252a4da14841f8007ab700993d25 Mon Sep 17 00:00:00 2001 From: tegwick Date: Sat, 22 Aug 2026 13:01:14 +0200 Subject: [PATCH] Activate ZONE-WP-0001 and decide exception lifecycle Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a0291a-1e87-7151-9934-fcbfe3f65eb1 --- SCOPE.md | 17 +-- WORK-RECORDS.md | 8 +- docs/exception-lifecycle-2026-08-22.md | 121 ++++++++++++++++++ workplans/ZONE-WP-0001-security-zone-model.md | 45 ++++++- 4 files changed, 174 insertions(+), 17 deletions(-) create mode 100644 docs/exception-lifecycle-2026-08-22.md diff --git a/SCOPE.md b/SCOPE.md index 3df20c2..d549ef5 100644 --- a/SCOPE.md +++ b/SCOPE.md @@ -128,16 +128,17 @@ Their answers are binding on this repo and are recorded in the workplan. --- -## Current state (2026-08-19) +## Current state (2026-08-22) -Seeded and reviewed. **No model, no schema, no runtime** — deliberately: an -engine that ships a wire format before it has partitioned the real estate -defines the model by accident. +`ZONE-WP-0001` is active. T01 confirmed ownership, T02 partitioned the estate, +and T04 selected reviewed declarations with enforcement-time expiry: **no +zone-engine runtime is warranted**. The exception lifecycle is recorded in +`docs/exception-lifecycle-2026-08-22.md`. -`ZONE-WP-0001` carries the work. T01 is answered by both owners; T02–T07 are -open. Whether a runtime is warranted is an *output* of T04, and the "no runtime" -answer is a legitimate result that would retire this repo rather than embarrass -it (`GOAL.md` gate 5). +T03 is waiting on a declaration-boundary ruling from `repo-manager` and +`net-kingdom`. The current evidence has nine declared rapp workloads, but only +one of ops-warden's 27 lanes can be joined to one; unknown membership is kept +unknown rather than inferred. No API, storage, or wire schema has been shipped. --- diff --git a/WORK-RECORDS.md b/WORK-RECORDS.md index 5577bfc..f09ce9b 100644 --- a/WORK-RECORDS.md +++ b/WORK-RECORDS.md @@ -8,11 +8,11 @@ | Kind | ID | Status | Lane | Source | | --- | --- | --- | --- | --- | -| workplan | ZONE-WP-0001 | proposed | — | workplans/ZONE-WP-0001-security-zone-model.md | -| task | ZONE-WP-0001-T01 | todo | — | workplans/ZONE-WP-0001-security-zone-model.md | +| workplan | ZONE-WP-0001 | active | — | workplans/ZONE-WP-0001-security-zone-model.md | +| task | ZONE-WP-0001-T01 | done | — | workplans/ZONE-WP-0001-security-zone-model.md | | task | ZONE-WP-0001-T02 | done | — | workplans/ZONE-WP-0001-security-zone-model.md | -| task | ZONE-WP-0001-T03 | todo | — | workplans/ZONE-WP-0001-security-zone-model.md | -| task | ZONE-WP-0001-T04 | todo | — | workplans/ZONE-WP-0001-security-zone-model.md | +| task | ZONE-WP-0001-T03 | wait | — | workplans/ZONE-WP-0001-security-zone-model.md | +| task | ZONE-WP-0001-T04 | done | — | workplans/ZONE-WP-0001-security-zone-model.md | | task | ZONE-WP-0001-T05 | todo | — | workplans/ZONE-WP-0001-security-zone-model.md | | task | ZONE-WP-0001-T06 | todo | — | workplans/ZONE-WP-0001-security-zone-model.md | | task | ZONE-WP-0001-T07 | todo | — | workplans/ZONE-WP-0001-security-zone-model.md | diff --git a/docs/exception-lifecycle-2026-08-22.md b/docs/exception-lifecycle-2026-08-22.md new file mode 100644 index 0000000..aaaa6d7 --- /dev/null +++ b/docs/exception-lifecycle-2026-08-22.md @@ -0,0 +1,121 @@ +# Time-boxed security-zone exceptions — ZONE-WP-0001-T04 + +**Decision date:** 2026-08-22 +**Decision:** the exception lifecycle does not require a zone-engine runtime. + +An exception is a temporary relaxation of one control for workloads already +admitted to a named security zone. It does not change membership, lower an +admission floor, or create a temporary-sounding zone. Membership remains a +declared workload fact. The control owner remains the authority for the effect. + +## 1. Grant authority + +The workload's responsible party may request an exception. Only the authority +designated by the **control owner** may grant it, because that owner owns the +base stance and the enforcement point that must apply the relaxation. For a +failure-mode relaxation, the grant authority is the owner of the policy +enforcement point (PEP), never the PDP. + +One person may currently perform both roles in this founder-operated estate, +but the record still names `requested_by` and `granted_by` separately. A +declarer cannot grant itself an exemption merely by changing its zone +membership. + +Each control declares a `maximum_exception_duration`. If it declares no +maximum, it permits no exceptions. A grant beyond the declared maximum is +invalid rather than silently shortened. + +## 2. Minimum record + +This is a conceptual record for the canon draft, not an API or storage schema. +Every implementation must preserve these facts in machine-readable form: + +| Fact | Rule | +| --- | --- | +| `exception_id` | Stable and unique; renewed grants get new ids | +| `security_zone` | The admitted zone whose normal rule is being relaxed | +| `control` | Stable owner-qualified control id | +| `workloads` | Authoritative workload ids; an empty or unresolved subject is invalid | +| `base` | The stance and, where relevant, PEP failure mode that auto-restores | +| `relaxation` | Explicit `advisory` or `exempt` stance and/or PEP-side failure mode | +| `justification` | The bounded work that requires the relaxation | +| `requested_by` / `granted_by` | Auditable responsible parties | +| `issued_at` / `not_before` / `not_after` | UTC instants; `not_after` is exclusive | +| `maximum_duration_policy` | Versioned rule against which duration was checked | +| `change_ref` | Reviewed source change that introduced the grant | + +A grant may only relax a named control. Promotion to a stricter stance is an +ordinary policy change, not an exception. Wildcard workload scope is forbidden: +the work that needs relief must be named, and unknown membership never inherits +a permissive zone or exception. + +## 3. Enforced expiry + +At every decision or enforcement attempt, an exception applies only when all of +the following are true: + +1. its record is valid and was granted by the control's designated authority; +2. the current authoritative workload and zone match its scope; +3. `not_before <= now < not_after`; and +4. its duration does not exceed the referenced maximum. + +Missing, malformed, unresolved, or unevaluable facts make the exception +**inactive**. The enforcement point applies the base stance and failure mode. +Clock failure must never preserve the relaxation. + +Expiry is an automatic return to the base rule. It does not block waiting for a +renewal, and it does not require a commit, image rebuild, rollout, scheduler, or +human reminder. Renewal is a new reviewed grant with a new id; the expired +record remains in history. + +No authority created under an exception may outlive it. A certificate, token, +lease, session, or other durable result must have an expiry no later than the +exception's `not_after`, or the enforcement point must re-evaluate the exception +before each use. Otherwise the timestamp would expire while its effect remained +live. + +## 4. Placement by control + +| Control kind | Grant representation | Expiry evaluator | Required evidence | +| --- | --- | --- | --- | +| flex-auth decision | Versioned flex-auth policy package | Rego decision time (`time.now_ns()`) | Decision envelope includes policy package/version and active exception id/expiry | +| ops-warden CLI decision | Versioned ops-warden control data | CLI at each invocation | Verdict `reasons` includes active exception id/expiry | +| PEP failure mode | Versioned consumer configuration | PEP when the PDP/control is unreachable | PEP audit record includes exception id/expiry and fallback taken | + +This placement preserves the authority boundary: zone-engine standardizes the +lifecycle, while each control owner represents and evaluates the effect where +that control already runs. In particular, fail-open cannot be implemented by +flex-auth because no PDP decision exists when flex-auth is unreachable. + +The current flex-auth deployment loads registry and policy once at process +start. Granting therefore costs rebuild and rollout, but a timestamp evaluated +at decision time still lapses without either. An inert registry flag would not; +it is prohibited for exceptions. + +## 5. Visibility + +Someone who did not grant an exception must be able to discover it in two +places: + +- the reviewed, versioned source record owned with the control, including + expired records in history; and +- the machine-readable decision or verdict whenever the exception changes an + outcome, including `exception_id` and `not_after`. + +Control builds must also produce a machine-readable inventory of active and +future grants and reject overlaps that would make the selected relaxation +ambiguous. Near-expiry reporting is useful operationally but is not the expiry +mechanism. + +## 6. Runtime decision + +A central zone-engine service would not enforce expiry more reliably. It could +not alter flex-auth's digest-pinned, load-once artifacts at the deadline, and a +synchronous lookup would add a new availability dependency while crossing the +PDP authority boundary. The enforcement points already have the clocks and the +decision context needed to make a compiled `not_after` self-expiring. + +Therefore T04 selects reviewed declarations plus enforcement-time timestamp +evaluation. `zone-engine` needs a canon contract and conformance fixtures, not a +runtime. This decision can be reopened only if a real adopting control cannot +evaluate time at the point where the relaxation takes effect. diff --git a/workplans/ZONE-WP-0001-security-zone-model.md b/workplans/ZONE-WP-0001-security-zone-model.md index e9710c6..d974da4 100644 --- a/workplans/ZONE-WP-0001-security-zone-model.md +++ b/workplans/ZONE-WP-0001-security-zone-model.md @@ -4,12 +4,12 @@ type: workplan title: "The security zone model — derive it from the estate, draft it as canon" domain: infotech repo: zone-engine -status: proposed +status: active owner: zone-engine topic_slug: netkingdom planning_priority: P1 created: "2026-08-19" -updated: "2026-08-19" +updated: "2026-08-22" state_hub_workstream_id: "a75c8c9c-c108-4831-8d72-4343cce49879" --- @@ -76,7 +76,7 @@ machinery; it does not grow a second vocabulary beside it. ```task id: ZONE-WP-0001-T01 -status: todo +status: done priority: high state_hub_task_id: "ea74316e-b711-4888-9b38-553ebc9ad856" ``` @@ -91,6 +91,12 @@ the only PDP and consumes compiled membership. If either disagrees, the model moves and this repo is archived rather than kept for its own sake. Record the outcome either way. +**Done 2026-08-22.** Both required owners answered on the record below. Their +binding decisions have been carried into `GOAL.md` and `SCOPE.md`: zone-engine +owns identity, membership, and the exception lifecycle; net-kingdom publishes +the canon standard; flex-auth remains the only PDP; membership is compiled data +and stance is owned by the policy or enforcement point that renders the effect. + **flex-auth answered 2026-08-19 (amended by flex-auth).** Confirmed: zone-engine owns zone identity, membership and exception lifecycle; flex-auth stays the only PDP. But the invariant as written in `GOAL.md` guards the wrong property. *"Never @@ -263,7 +269,7 @@ those lanes are graded. ```task id: ZONE-WP-0001-T03 -status: todo +status: wait priority: high state_hub_task_id: "7f47b750-1ae4-467d-b3c4-064f4ec07dbd" ``` @@ -277,6 +283,19 @@ Controls in scope at minimum: the flex-auth pre-sign gate (`policy.enabled`, `fail_closed`), the agent read-boundary on `risk: high` lanes (ops-warden `ADR-0004`), and the `warden plan` escalation verdicts. +**Waiting on owner rulings, 2026-08-22.** Re-running +`ops-warden/scripts/report_workload_join.py` finds **nine** declared rapp +workloads, but still only **one of 27 lanes** joins to a workload; 13 name an +undeclared candidate and 13 have no workload-shaped path. The exact residue was +sent to `repo-manager` (declaration ownership/surface) and `net-kingdom` +(whether operational control-plane consumers must acquire workload identities, +and whether unknown is a required result). This is the consultation required by +the 2026-08-20 finding below; stance modelling will not reopen the policy subject +merely to make the corpus fit. In the interim, `RISK-N-0004`'s consumer +requirements are accepted: the resolved view is workload-addressable, +authoritative, machine-readable, exposes guarantees as well as membership, and +returns unknown without inference. + **Operator direction 2026-08-19 — defaults derive from maturity, not from nothing.** An ungraded lane must not inherit the safest-for-the-tool default; it should inherit the default its *maturity context* implies. Early or experimental @@ -473,7 +492,7 @@ not, and a model that implies otherwise will be built and then not work. ```task id: ZONE-WP-0001-T04 -status: todo +status: done priority: high state_hub_task_id: "1c542ca5-2b82-4778-a3e4-c76e932423c9" ``` @@ -491,6 +510,22 @@ happens at expiry — auto-revert, or block until renewed. If T04 concludes the lifecycle can live as reviewed declarations in git, say so plainly and drop the runtime. That is a valid and cheaper outcome. +**Done 2026-08-22.** The lifecycle and runtime decision are recorded in +`docs/exception-lifecycle-2026-08-22.md`. A grant is a reviewed, +machine-readable relaxation for named workloads, one zone, and one control; +only the control owner's designated authority may grant it, within that +control's declared maximum duration. The enforcement point applies it only for +`not_before <= now < not_after`, falls back to the base rule on any invalid or +unevaluable fact, stamps the active exception into its decision/verdict, and +caps any durable credential or session so no granted authority outlives the +exception. Expiry auto-restores the base rule; renewal is a new grant. + +**No runtime is warranted.** flex-auth policy evaluates time in Rego; CLI and +PEP controls evaluate it on invocation. A central service could neither reload +flex-auth's digest-pinned artifacts nor improve deadline enforcement without +adding a synchronous availability and authority boundary. Git review plus +enforcement-time evaluation is the cheaper and stronger result. + **Hard constraint from flex-auth 2026-08-19 — the PDP has no reload path.** `cmd/flex-auth/main.go:447` calls `registry.LoadFile` once at process start. There is no watcher, no SIGHUP, no reload endpoint. Both the registry snapshot