Confirm the approval-claim as the step-1 PEP artifact

approval-engine raised APPROVAL-IN-0002: secrets-engine's PEP validator
expects a flex-auth ActionAuthorization but fetches the approval-claim
endpoint that GH-DEC-2026-003 names as step 1. Two objects on one path.

GH-IN-0002 records the intake; GH-DEC-2026-005 resolves it. The claim is
the step-1 artifact and always was — ActionAuthorization is unratified,
has no valid_now field, and cannot be served from a step-1 call. The
addition beyond confirmation is doctrine: a PEP validates each artifact
against the layer that owns its data, and no PIP republishes the PDP's
decision. The provenance.authority == "state-hub" requirement is struck;
State Hub is a read model and holds no runtime approval authority.

docs/contracts/approval-consumption.md carries the amendment at the
sequence itself so implementers find it there.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WtJBr77gMFLrN93iEevqQJ

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 425128@bnt-lap001
Assistant-Session: f5944d8b-dac4-4e1a-87eb-8b3d8f314a63
This commit is contained in:
tegwick 2026-09-06 01:29:28 +02:00
parent 60e2e7de65
commit 1a920a5490
3 changed files with 115 additions and 3 deletions

View file

@ -488,3 +488,85 @@ decided_by: Bernd Worsch
created: '2026-09-05T23:28:23.931441Z'
updated: '2026-09-05T23:28:23.931441Z'
```
## Context
`GH-DEC-2026-003` settled the consumption sequence and named step 1 by endpoint and
by field: `GET /v1/approvals/{id}/claim``valid_now` (a fact, not permission).
`approval-engine` serves the approval-claim at that endpoint
(`approval-engine/docs/approval-claim.md`). `secrets-engine`'s PEP validator
(`validate_action_authorization`, `src/secrets_engine/authorization.py`) calls the
same endpoint but expects a flex-auth `ActionAuthorization`. Two different objects
were being assumed on one path, and the divergence would have surfaced at first live
consume rather than at deployment.
`ActionAuthorization` originates in `flex-auth/docs/action-bound-authorization-contract.md`
as a proposed shape for durable approval storage that the same document assigns to
`approval-engine`. It was never ratified, appears nowhere in this repository's
doctrine, and has no `valid_now` field. `GH-DEC-2026-003` was issued after it without
reference to it. There is therefore nothing to reconcile: the claim was the step-1
artifact all along, and this record says so where implementers will find it.
`approval-engine` raised the question rather than guessing, which is the behaviour
§12 asks for. The three substantive assertions in the request were checked here
independently before confirmation.
## Decision
**1. The approval-claim is the step-1 artifact on the `GH-DEC-2026-003` path.**
It carries the approval fact: binding digest, validity window, consumption state,
observation freshness, and issuer. Holding one with `valid_now: true` remains not
authority to act.
**2. `ActionAuthorization` is not required on that path.** `approval-engine` is not
expected to serve it and MUST NOT serve it from the claim endpoint. A step-1 response
cannot contain a step-2 decision; any composed post-decision artifact would be a new
artifact at a new endpoint. The proposal is shelved on this path, not withdrawn.
**3. A PEP validates across the two artifacts it already fetches.** The claim is
checked for the approval fact; the flex-auth `DecisionEnvelope` from step 2 is checked
for exact `CheckRequest` match and policy package/version pin. This is doctrine, not
merely an implementation convenience: **each artifact is validated against the layer
that owns its data.** A PIP republishing the PDP's decision would put a copy of the
authority decision in a repository that did not render it — the same shape of error
the re-cut removed from Gate House itself. No safety property is lost, because
`ActionAuthorization` is a bundle of exactly these two checks.
**4. The `provenance.authority == "state-hub"` requirement is struck.** State Hub is
a read model. It is not the runtime approval authority and never was; flex-auth's own
contract says so. A validator that requires it would fail closed against every
correctly issued claim. `secrets-engine` removes the constant with the validator split.
Consequent changes: `approval-engine` none — the claim schema stands as published;
`secrets-engine` splits its validator and drops the authority constant; `flex-auth`
records that the proposal is shelved on this path. Nothing here gates
`APPROVAL-WP-0002-T03``secrets-engine` is fail-closed until its own gates land,
and this record governs first live consume, not deployment.
## Deferred
A ratified post-decision `ActionAuthorization` — one composed, signed, forwardable
object — remains coherent and is recorded here so it is not rediscovered as new. It
is not adopted now because it has no named issuer or lifecycle owner and the sequence
is already settled without one. Revisit on any of: a third or fourth PEP-shaped
consumer; a requirement for a single signed forwardable artifact (offline
verification, or an audit that must replay one object rather than a join); resolution
of flex-auth's open G3 finding by composition rather than by adding a lifetime to the
envelope; or assent of the statute §17 Taxonomy request-claim schema
(`APPROVAL-IN-0001`) — in which case converge there and do **not** revive this
separately.
Also rejected, so they are not re-proposed: serving `ActionAuthorization` at the claim
endpoint (structurally impossible for step 1, and it would assert an authority
`approval-engine` does not hold); and extending the claim with `approvals.required_count`
or `entries` (publishing approver identities is a deliberate least-disclosure non-goal,
and it would still not satisfy the validator).
## Reversal
Revert this record and the amendment to `docs/contracts/approval-consumption.md`. The
falsifier is a demonstrated check that two-artifact validation cannot perform and a
single composed artifact can — most plausibly offline or forwarded verification with
no access to the PDP. That is a trigger for the deferred option above, not for
returning `ActionAuthorization` to the claim endpoint, which stays forbidden on
structural grounds regardless.

View file

@ -3,8 +3,9 @@
**Owner:** gate-house
**PIP:** approval-engine
**PDP:** access-engine (currently flex-auth)
**Status:** normative for GH-WP-0002-T06; recorded as `GH-DEC-2026-003`
**Date:** 2026-08-29
**Status:** normative for GH-WP-0002-T06; recorded as `GH-DEC-2026-003`,
amended by `GH-DEC-2026-005` (step-1 artifact and split validation)
**Date:** 2026-09-06
**Statute:** `net-kingdom/canon/standards/security-layer-model_v0.7.md` §9.4, §9.7.34, §16
**Blocks:** `APPROVAL-WP-0001-T05`, `FLEX-WP-0017-T05`
@ -30,6 +31,35 @@ companion §5 already treats as PEP-shaped.
Holding a claim with `valid_now: true`, or an ALLOW against that claim, is not
authority to act. The consume is.
## What each step's artifact is
Amended by `GH-DEC-2026-005`.
**Step 1 serves the approval-claim** (`approval-engine/docs/approval-claim.md`).
That is the artifact `valid_now` belongs to, and it is the only object the claim
endpoint serves. flex-auth's proposed `ActionAuthorization` is **not** required
here, is not served here, and MUST NOT be served from this endpoint: a step-1
response cannot contain a step-2 decision.
**A PEP validates across both artifacts it already fetches**, and each against
the layer that owns its data:
| Artifact | Source | What the PEP checks |
| --- | --- | --- |
| approval-claim | step 1, `approval-engine` (PIP) | binding digest, validity window, consumption state, observation freshness, issuer |
| `DecisionEnvelope` | step 2, `access-engine` (PDP) | exact `CheckRequest` match, policy package and version pin |
A PIP MUST NOT republish the PDP's decision, and a PEP MUST NOT accept the
approval fact from the decision artifact or the decision from the approval
artifact. Composing the two into one served object is a separate, post-decision
artifact at a separate endpoint if it is ever ratified — not a change to the
claim.
**Claim provenance is not State Hub.** A PEP MUST NOT require
`provenance.authority == "state-hub"` on the claim. State Hub is a read model and
holds no runtime approval authority; the issuer to check is the engine that
served the claim.
## Why consume is before the side effect
§9.7.3 says consumption MUST NOT be inferred from a decision record. That

View file

@ -131,7 +131,7 @@ state_hub_intake_id: "01a04b04-dd82-73a4-a8bf-9aeba5ef575f"
id: GH-IN-0002
kind: intake
title: Claim envelope on the PEP consumption path — which artifact is step 1 of GH-DEC-2026-003
status: open
status: closed
origin: cross-repo
origin_ref: approval-engine APPROVAL-IN-0002 (decision request)
priority: high