Finish FLEX-WP-0017
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s

Assistant: codex
Assistant-Model: gpt-5.6-sol
Assistant-Session: 01a05e2e-805b-7042-a750-71f473bceea2
This commit is contained in:
tegwick 2026-09-01 20:21:58 +02:00
parent c9a4c98907
commit 58fbd46ff9
4 changed files with 46 additions and 30 deletions

View file

@ -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 subject, action, resource, context, and a full request digest. This makes the
execute-time decision contract inspectable without parsing reason or diagnostic execute-time decision contract inspectable without parsing reason or diagnostic
prose. Durable human approval lifecycle, supersession, and authenticated 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 cross-system object is documented in
`schemas/action_authorization.schema.json` and is not yet a deployed State Hub `schemas/action_authorization.schema.json` and is not yet a deployed
endpoint. `approval-engine` endpoint.
The **first shipped protected-system consumer is ops-warden**: its opt-in The **first shipped protected-system consumer is ops-warden**: its opt-in
pre-sign gate calls `POST /v1/check` for `resource.type: ssh-certificate`, pre-sign gate calls `POST /v1/check` for `resource.type: ssh-certificate`,

View file

@ -24,7 +24,7 @@
| workplan | FLEX-WP-0014 | finished | — | workplans/FLEX-WP-0014-tenant-guardrail-policy-actions.md | | 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-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-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-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-0019 | ready | — | workplans/FLEX-WP-0019-layer-model-conformance.md |
| workplan | FLEX-WP-0020 | proposed | — | workplans/FLEX-WP-0020-repository-identity-migration.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-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-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-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-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-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-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 | | task | FLEX-WP-0019-T01 | todo | — | workplans/FLEX-WP-0019-layer-model-conformance.md |

View file

@ -1,7 +1,7 @@
# Action-bound authorization contract # Action-bound authorization contract
Status: implemented for execute-time request binding; durable approval storage Status: implemented for execute-time request binding; durable approval storage
requires State Hub support. and lifecycle require `approval-engine` support.
Date: 2026-08-23 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 Consumers must compare structured fields; `reason`, `diagnostics`, titles, and
other prose are never an authorization contract. other prose are never an authorization contract.
State Hub owns durable organizational-decision identity, resolution, `approval-engine` owns the durable approval object, authenticated approval
supersession, and availability. Its current endpoint is: evidence, storage, supersession, consumption, and availability. State Hub
decision records are coordination and provenance evidence; they are not the
```text runtime approval authority. Production consumers must not infer action binding
GET /decisions/{uuid} or dual control from State Hub prose or a free-form `decided_by` value.
```
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.
## Durable object ## 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: A production consumer may execute only when all of the following hold:
1. The durable object resolves from its canonical authority; an outage fails 1. The durable object resolves from `approval-engine`, its canonical authority;
the action closed. an outage fails the action closed.
2. `status` is `approved`, `superseded_by` is absent, and the current time is 2. `status` is `approved`, `superseded_by` is absent, and the current time is
inside the validity window. inside the validity window.
3. The caller's proposed action exactly matches `request`, including resource 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 ## 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 action denied; read-only inspection and dry-run may continue with a clear
non-authoritative status. non-authoritative status.
- flex-auth unavailable when a fresh decision is required: privileged live - 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 ## Remaining external work
State Hub needs a structured object/endpoint capable of storing this schema or `approval-engine` needs a structured object/endpoint capable of storing this
equivalent fields, authenticated approval entries, and atomic supersession. schema or equivalent fields, authenticated approval entries, atomic
Until that lands, secrets-engine is correct to keep live destructive actions supersession, and single-consumption semantics. Until that lands and the
disabled. The standalone evaluator and the Topaz, relationship, rule, and consumer proof passes, secrets-engine is correct to keep live destructive
Keycloak delegated adapter boundaries now all populate the same binding. actions disabled. The standalone evaluator and the Topaz, relationship, rule,
and Keycloak delegated adapter boundaries now all populate the same binding.

View file

@ -4,13 +4,13 @@ type: workplan
title: "Action-bound authorization and durable approval contract" title: "Action-bound authorization and durable approval contract"
domain: infotech domain: infotech
repo: flex-auth repo: flex-auth
status: active status: finished
owner: codex owner: codex
topic_slug: netkingdom topic_slug: netkingdom
planning_priority: P1 planning_priority: P1
planning_order: 117 planning_order: 117
created: "2026-08-23" created: "2026-08-23"
updated: "2026-08-23" updated: "2026-09-01"
state_hub_workstream_id: "d75b7256-8b3d-5797-911c-96c3199b8baa" state_hub_workstream_id: "d75b7256-8b3d-5797-911c-96c3199b8baa"
--- ---
@ -57,7 +57,7 @@ drift fails the suite.
```task ```task
id: FLEX-WP-0017-T03 id: FLEX-WP-0017-T03
status: wait status: cancel
priority: high priority: high
state_hub_task_id: "82d39961-8140-5a7f-9bd8-5164dd1742e5" 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 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`. 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 ## Propagate bindings through delegated evaluators
```task ```task
@ -93,7 +99,7 @@ success and fail-closed responses using the shared canonical constructor.
```task ```task
id: FLEX-WP-0017-T05 id: FLEX-WP-0017-T05
status: wait status: cancel
priority: high priority: high
state_hub_task_id: "8c3fc0a2-0855-5ac9-afa5-d03b8b1f0bf9" 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, privileged production action and proves wrong action/lane/stage/targets,
expiry, supersession, outage, insufficient approvals, and duplicate approvers expiry, supersession, outage, insufficient approvals, and duplicate approvers
all fail before any OpenBao call. Live destroy stays disabled until that proof. 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.