From 58fbd46ff97ff07be388bffc547b6e852f6b4b37 Mon Sep 17 00:00:00 2001 From: tegwick Date: Tue, 1 Sep 2026 20:21:58 +0200 Subject: [PATCH] Finish FLEX-WP-0017 Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a05e2e-805b-7042-a750-71f473bceea2 --- SCOPE.md | 6 ++-- WORK-RECORDS.md | 6 ++-- docs/action-bound-authorization-contract.md | 35 ++++++++----------- ...017-action-bound-authorization-contract.md | 29 ++++++++++++--- 4 files changed, 46 insertions(+), 30 deletions(-) diff --git a/SCOPE.md b/SCOPE.md index 08a3c80..e6bb823 100644 --- a/SCOPE.md +++ b/SCOPE.md @@ -109,10 +109,10 @@ Standalone decisions include a structured `binding` containing the normalized subject, action, resource, context, and a full request digest. This makes the execute-time decision contract inspectable without parsing reason or diagnostic prose. Durable human approval lifecycle, supersession, and authenticated -multi-approver evidence remain State Hub responsibilities; the proposed +multi-approver evidence are `approval-engine` responsibilities; the proposed cross-system object is documented in -`schemas/action_authorization.schema.json` and is not yet a deployed State Hub -endpoint. +`schemas/action_authorization.schema.json` and is not yet a deployed +`approval-engine` endpoint. The **first shipped protected-system consumer is ops-warden**: its opt-in pre-sign gate calls `POST /v1/check` for `resource.type: ssh-certificate`, diff --git a/WORK-RECORDS.md b/WORK-RECORDS.md index ebc9ff6..c537d46 100644 --- a/WORK-RECORDS.md +++ b/WORK-RECORDS.md @@ -24,7 +24,7 @@ | workplan | FLEX-WP-0014 | finished | — | workplans/FLEX-WP-0014-tenant-guardrail-policy-actions.md | | workplan | FLEX-WP-0015 | finished | — | workplans/FLEX-WP-0015-tenancy-posture-conformance.md | | workplan | FLEX-WP-0016 | finished | — | workplans/FLEX-WP-0016-ops-warden-incluster-policy-pin.md | -| workplan | FLEX-WP-0017 | active | — | workplans/FLEX-WP-0017-action-bound-authorization-contract.md | +| workplan | FLEX-WP-0017 | finished | — | workplans/FLEX-WP-0017-action-bound-authorization-contract.md | | workplan | FLEX-WP-0018 | finished | — | workplans/FLEX-WP-0018-inbound-auth-corrections.md | | workplan | FLEX-WP-0019 | ready | — | workplans/FLEX-WP-0019-layer-model-conformance.md | | workplan | FLEX-WP-0020 | proposed | — | workplans/FLEX-WP-0020-repository-identity-migration.md | @@ -104,9 +104,9 @@ | task | FLEX-WP-0016-T03 | done | — | workplans/FLEX-WP-0016-ops-warden-incluster-policy-pin.md | | task | FLEX-WP-0017-T01 | done | — | workplans/FLEX-WP-0017-action-bound-authorization-contract.md | | task | FLEX-WP-0017-T02 | done | — | workplans/FLEX-WP-0017-action-bound-authorization-contract.md | -| task | FLEX-WP-0017-T03 | wait | — | workplans/FLEX-WP-0017-action-bound-authorization-contract.md | +| task | FLEX-WP-0017-T03 | cancel | — | workplans/FLEX-WP-0017-action-bound-authorization-contract.md | | task | FLEX-WP-0017-T04 | done | — | workplans/FLEX-WP-0017-action-bound-authorization-contract.md | -| task | FLEX-WP-0017-T05 | wait | — | workplans/FLEX-WP-0017-action-bound-authorization-contract.md | +| task | FLEX-WP-0017-T05 | cancel | — | workplans/FLEX-WP-0017-action-bound-authorization-contract.md | | task | FLEX-WP-0018-T01 | done | — | workplans/FLEX-WP-0018-inbound-auth-corrections.md | | task | FLEX-WP-0018-T02 | done | — | workplans/FLEX-WP-0018-inbound-auth-corrections.md | | task | FLEX-WP-0019-T01 | todo | — | workplans/FLEX-WP-0019-layer-model-conformance.md | diff --git a/docs/action-bound-authorization-contract.md b/docs/action-bound-authorization-contract.md index 163f3a8..1945569 100644 --- a/docs/action-bound-authorization-contract.md +++ b/docs/action-bound-authorization-contract.md @@ -1,7 +1,7 @@ # Action-bound authorization contract Status: implemented for execute-time request binding; durable approval storage -requires State Hub support. +and lifecycle require `approval-engine` support. Date: 2026-08-23 @@ -19,17 +19,11 @@ resource, context, and full SHA-256 request digest evaluated by the policy. Consumers must compare structured fields; `reason`, `diagnostics`, titles, and other prose are never an authorization contract. -State Hub owns durable organizational-decision identity, resolution, -supersession, and availability. Its current endpoint is: - -```text -GET /decisions/{uuid} -``` - -That object is not yet sufficient for privileged action execution. As of -2026-08-23 it has lifecycle fields and `superseded_by`, but action details live -only in prose and it records only one free-form `decided_by` value. Production -consumers must not infer action binding or dual control from it. +`approval-engine` owns the durable approval object, authenticated approval +evidence, storage, supersession, consumption, and availability. State Hub +decision records are coordination and provenance evidence; they are not the +runtime approval authority. Production consumers must not infer action binding +or dual control from State Hub prose or a free-form `decided_by` value. ## Durable object @@ -67,8 +61,8 @@ policy inputs and should be denied for destructive production actions. A production consumer may execute only when all of the following hold: -1. The durable object resolves from its canonical authority; an outage fails - the action closed. +1. The durable object resolves from `approval-engine`, its canonical authority; + an outage fails the action closed. 2. `status` is `approved`, `superseded_by` is absent, and the current time is inside the validity window. 3. The caller's proposed action exactly matches `request`, including resource @@ -83,7 +77,7 @@ decision id are provenance only. They cannot unlock a production action. ## Outage and supersession semantics -- State Hub or future authorization-object store unreachable: privileged live +- `approval-engine` unreachable: privileged live action denied; read-only inspection and dry-run may continue with a clear non-authoritative status. - flex-auth unavailable when a fresh decision is required: privileged live @@ -96,8 +90,9 @@ decision id are provenance only. They cannot unlock a production action. ## Remaining external work -State Hub needs a structured object/endpoint capable of storing this schema or -equivalent fields, authenticated approval entries, and atomic supersession. -Until that lands, secrets-engine is correct to keep live destructive actions -disabled. The standalone evaluator and the Topaz, relationship, rule, and -Keycloak delegated adapter boundaries now all populate the same binding. +`approval-engine` needs a structured object/endpoint capable of storing this +schema or equivalent fields, authenticated approval entries, atomic +supersession, and single-consumption semantics. Until that lands and the +consumer proof passes, secrets-engine is correct to keep live destructive +actions disabled. The standalone evaluator and the Topaz, relationship, rule, +and Keycloak delegated adapter boundaries now all populate the same binding. diff --git a/workplans/FLEX-WP-0017-action-bound-authorization-contract.md b/workplans/FLEX-WP-0017-action-bound-authorization-contract.md index 147373e..2a411ce 100644 --- a/workplans/FLEX-WP-0017-action-bound-authorization-contract.md +++ b/workplans/FLEX-WP-0017-action-bound-authorization-contract.md @@ -4,13 +4,13 @@ type: workplan title: "Action-bound authorization and durable approval contract" domain: infotech repo: flex-auth -status: active +status: finished owner: codex topic_slug: netkingdom planning_priority: P1 planning_order: 117 created: "2026-08-23" -updated: "2026-08-23" +updated: "2026-09-01" state_hub_workstream_id: "d75b7256-8b3d-5797-911c-96c3199b8baa" --- @@ -57,7 +57,7 @@ drift fails the suite. ```task id: FLEX-WP-0017-T03 -status: wait +status: cancel priority: high state_hub_task_id: "82d39961-8140-5a7f-9bd8-5164dd1742e5" ``` @@ -77,6 +77,12 @@ unowned: it is not gate-house's, because Staff holds no state another layer depends on at runtime (standard §3.4), and not flex-auth's, for the reason above. Raised to gate-house as an engine gap under §5. Task stays `wait`. +Final disposition 2026-09-01: cancelled in this workplan after the security +layer model assigned the durable approval object, authenticated approvals, +storage, and lifecycle to `approval-engine`. This is an ownership transfer, not +a claim that the external capability is implemented. flex-auth consumes the +result as an input claim and does not store or mutate it. + ## Propagate bindings through delegated evaluators ```task @@ -93,7 +99,7 @@ success and fail-closed responses using the shared canonical constructor. ```task id: FLEX-WP-0017-T05 -status: wait +status: cancel priority: high state_hub_task_id: "8c3fc0a2-0855-5ac9-afa5-d03b8b1f0bf9" ``` @@ -102,3 +108,18 @@ After T03, secrets-engine validates the canonical object before every privileged production action and proves wrong action/lane/stage/targets, expiry, supersession, outage, insufficient approvals, and duplicate approvers all fail before any OpenBao call. Live destroy stays disabled until that proof. + +Final disposition 2026-09-01: cancelled in this workplan because enforcement +and live destructive-action proof belong to the protected-system consumer, +`secrets-engine`. flex-auth's handoff is the canonical request binding, +published schema, and fail-closed contract delivered by T01, T02, and T04. This +disposition does not enable live destroy or waive the consumer proof. + +## Closeout + +Finished 2026-09-01. flex-auth delivered the execute-time binding, canonical +durable-object vocabulary, contract documentation, schema, adapter propagation, +and regression coverage. The two remaining tasks were cancelled here after the +accepted layer model placed durable approval lifecycle with `approval-engine` +and enforcement with `secrets-engine`; those external obligations remain +fail-closed prerequisites and are not represented as completed flex-auth work.