diff --git a/docs/approval-consumption.md b/docs/approval-consumption.md index ea19c73..cc5b31e 100644 --- a/docs/approval-consumption.md +++ b/docs/approval-consumption.md @@ -41,3 +41,36 @@ after consumption, the approval remains spent and a retry needs a new approval. The response is mutation evidence, not a permission decision. It contains no `effect`, `allow`, `deny`, or decision result. + +## The claim response is not an `ActionAuthorization` + +`GET /v1/approvals/{id}/claim` serves the **approval-claim** envelope defined in +[`approval-claim.md`](approval-claim.md). It is not the `ActionAuthorization` +object that secrets-engine's `validate_action_authorization` currently expects, +and a PEP that points that validator at this URL fails closed for the wrong +reason. + +Both envelopes carry `schema_version: "0.1"`, so the version check passes and +the mismatch surfaces later as a missing-field or wrong-authority error. Do not +read that failure as an approval-engine outage. + +| Validator expectation | What the claim actually serves | +| --- | --- | +| `id` (canonical UUID) | `approval_id` — the object id, same value, different key | +| `status == "approved"` | `state` (`approved`, `consumed`, `revoked`, `superseded`, `expired`, `requested`) plus the `valid_now` predicate | +| `superseded_by` | absent; supersession appears as `state: "superseded"` | +| `provenance.authority == "state-hub"` | `issuer: "approval-engine"` — this engine is the authority for the approval object; the State Hub is a read model and never issues one | +| `request` (full CheckRequest) | `binding` (`action`, `actor`, `principal`, `purpose`, `target`) plus `binding.digest`, and `binding.pdp_digest` when recorded at issue | +| `approvals.required_count` / `entries` | not exposed; the distinct-approver threshold is already folded into `valid_now`, with `reason_code: "insufficient_approvers"` when unmet | +| policy package/version pin | not carried; the policy pin belongs to the access-engine decision, not to the approval fact | + +The omissions are deliberate. A claim is a *fact about an approval object*, not +a decision and not a permission; approver identities and policy pins are not +republished to consumers. The consumer checks in +[`approval-claim.md`](approval-claim.md) ("Required verification") are the +supported validation path. + +Reconciling the two envelopes is a cross-repo contract change under +`GH-DEC-2026-003`, not a unilateral edit here. Until it is decided, this engine +keeps serving the approval-claim shape and does not emit a `state-hub` +authority it does not have. diff --git a/workplans/APPROVAL-WP-0002-production-readiness-and-consumer-adoption.md b/workplans/APPROVAL-WP-0002-production-readiness-and-consumer-adoption.md index 52ebf5e..f99cc75 100644 --- a/workplans/APPROVAL-WP-0002-production-readiness-and-consumer-adoption.md +++ b/workplans/APPROVAL-WP-0002-production-readiness-and-consumer-adoption.md @@ -8,7 +8,7 @@ status: active owner: codex topic_slug: netkingdom created: "2026-09-01" -updated: "2026-09-02" +updated: "2026-09-06" reviewed_at: "2026-09-01" reviewed_against_commit: "ebce5abb276c01ab29ce2526f3b8abb332dc9e90" reviewed_note: >- @@ -185,3 +185,15 @@ claim refusal, and unreachable-engine callback suppression. Waiting on live closure: this service deployed (T03) and a durable consume binding served (`SECRETS-WP-0007-T04` / `SECRETS-WP-0008-T02`). This repo does not claim the OpenBao side effect. + +2026-09-06 follow-up: secrets-engine reports its PIP join is implemented and +blocked on deployment, not contract (inbox `61ae1174`). Review of its +`validate_action_authorization` shows a real envelope divergence: it expects a +`state-hub`-authority `ActionAuthorization` (`id`, `status`, `superseded_by`, +`request`, `approvals.entries`, policy pin) while this engine serves the +governed approval-claim (`approval_id`, `state`/`valid_now`, `binding`, +`freshness`, `reason_code`, `issuer: approval-engine`). Both declare +`schema_version` `0.1`, so the mismatch surfaces as a field/authority error +rather than a version error. Recorded in `docs/approval-consumption.md`; +reconciling the envelopes is a `GH-DEC-2026-003` cross-repo change, not a +unilateral edit here. T05 stays `wait`: still no deployed base URL (T03).