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:
parent
60e2e7de65
commit
1a920a5490
3 changed files with 115 additions and 3 deletions
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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.3–4, §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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue