Compare commits
3 commits
cf646c3195
...
1a920a5490
| Author | SHA1 | Date | |
|---|---|---|---|
| 1a920a5490 | |||
|
|
60e2e7de65 | ||
|
|
be18542cc6 |
3 changed files with 187 additions and 2 deletions
|
|
@ -453,3 +453,120 @@ NetKingdom security profile, or if Info Tech Canon cannot provide a stable
|
|||
cross-domain contract boundary. Reversal must still name one owner for every
|
||||
artifact; returning to undifferentiated "Taxonomy ownership" is not an
|
||||
acceptable outcome.
|
||||
|
||||
## GH-DEC-2026-005 — The approval-claim is the step-1 artifact on the PEP consumption path
|
||||
|
||||
```yaml
|
||||
id: GH-DEC-2026-005
|
||||
kind: decision
|
||||
title: The approval-claim is the step-1 artifact on the PEP consumption path
|
||||
status: resolved
|
||||
owner: Bernd Worsch
|
||||
repo: gate-house
|
||||
standard: net-kingdom/canon/standards/security-layer-model_v0.7.md
|
||||
source_note: docs/contracts/approval-consumption.md
|
||||
origin: GH-IN-0002
|
||||
requested_dispositions:
|
||||
- approved
|
||||
- revised
|
||||
- rejected
|
||||
affects:
|
||||
- gate-house
|
||||
- approval-engine
|
||||
- flex-auth
|
||||
- secrets-engine
|
||||
- ops-warden
|
||||
rationale: 'Confirmed, with one addition. GH-DEC-2026-003 already named step 1 by
|
||||
endpoint and by field; the approval-claim is what that endpoint serves and valid_now
|
||||
is its field. ActionAuthorization is a proposed, unratified shape carrying no doctrine
|
||||
standing here. The addition is that the split validation is stated as doctrine rather
|
||||
than left implicit: each artifact is checked by the consumer against the layer that
|
||||
owns its data, and no PIP republishes a PDP decision. The state-hub authority requirement
|
||||
in the secrets-engine validator is struck because State Hub is a read model and
|
||||
holds no runtime approval authority.'
|
||||
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
|
||||
|
|
|
|||
|
|
@ -124,3 +124,41 @@ closed_at: '2026-08-29T00:55:21.377495Z'
|
|||
outcome: promoted
|
||||
state_hub_intake_id: "01a04b04-dd82-73a4-a8bf-9aeba5ef575f"
|
||||
```
|
||||
|
||||
## GH-IN-0002 — Claim envelope on the PEP consumption path — which artifact is step 1 of GH-DEC-2026-003
|
||||
|
||||
```yaml
|
||||
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: closed
|
||||
origin: cross-repo
|
||||
origin_ref: approval-engine APPROVAL-IN-0002 (decision request)
|
||||
priority: high
|
||||
owner: gate-house
|
||||
requested_by: approval-engine
|
||||
lane: red
|
||||
description: 'approval-engine asks gate-house to confirm which artifact satisfies
|
||||
step 1 of the GH-DEC-2026-003 consumption sequence. secrets-engine''s PEP validator
|
||||
(validate_action_authorization) expects a flex-auth ActionAuthorization envelope
|
||||
but fetches GET /v1/approvals/{id}/claim, which serves approval-engine''s approval-claim.
|
||||
Two different objects on one path.
|
||||
|
||||
|
||||
GH-DEC-2026-003 already names step 1 by endpoint and by field — ''GET /v1/approvals/{id}/claim
|
||||
-> valid_now (a fact, not permission)''. valid_now is an approval-claim field; ActionAuthorization
|
||||
has no such field and appears nowhere in gate-house doctrine. It 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.
|
||||
|
||||
|
||||
Secondary finding: the secrets-engine validator hard-requires provenance.authority
|
||||
== ''state-hub'' (AUTHORITY constant, src/secrets_engine/authorization.py), while
|
||||
flex-auth''s own contract holds that State Hub decision records are not the runtime
|
||||
approval authority.
|
||||
|
||||
|
||||
Requested disposition is a confirmation, not a redesign. Resolved as GH-DEC-2026-005.'
|
||||
created: '2026-09-05T23:28:11.977565Z'
|
||||
updated: '2026-09-05T23:28:11.977565Z'
|
||||
```
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue