Publish reviewed strict execution consumption confirmation client
Assistant: codex Assistant-Model: gpt-6.1-sol Assistant-Session: 01a126e1-76f8-7643-8cf3-e93336539ade
This commit is contained in:
parent
097a2f2834
commit
e864305d4d
5 changed files with 455 additions and 0 deletions
143
docs/task-execution-consumption-contract.md
Normal file
143
docs/task-execution-consumption-contract.md
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
# Approval Engine metadata execution consumer contract — source proposal
|
||||
|
||||
Author: approval-engine source reviewer (Codex), staged only. Work record:
|
||||
APPROVAL-WP-ADHOC-2026-10-11-T01, bounded completed source preparation. Existing
|
||||
APPROVAL-WP-0002-T05 remains unchanged wait/residual adoption. This is an
|
||||
author-qualified technical proposal, not a formal delegated owner review,
|
||||
owner acknowledgement, founder approval, identity admission or runtime receipt.
|
||||
Source checkout: c8ae88057d5f2ff3743a37c158d7f692d90cce23, including pre-existing
|
||||
uncommitted owner files listed in source-state.json; none modified.
|
||||
|
||||
Reviewed proposals: SECRETS-EXEC-20261011-v1 and platform-task-execution/v1.
|
||||
Their exact source-file hashes are in source-state.json. Initial execute-ccr
|
||||
metadata pilot only; no generic grants, daemon, standing service permissions,
|
||||
raw bearer handoff or full Secrets adoption.
|
||||
|
||||
## Existing route and trust boundary
|
||||
|
||||
- GET /v1/approvals/{id}/claim requires approval:read and exact store tenant.
|
||||
It supplies fresh approval facts and native five-field act binding, approval-free
|
||||
PDP digest, PDP/human declarations. consumed=true lacks consumed request/decision
|
||||
correspondence and cannot confirm execution admission.
|
||||
- POST /v1/approvals/{id}/consume requires approval:consume, exact tenant and
|
||||
service/agent principal. Body is request_digest plus decision_id. It returns
|
||||
approval_id, status=consumed, request_digest, original decision_id when stored,
|
||||
consumed_at and explicit idempotent boolean. Direct response to an authenticated
|
||||
independent mediator is authoritative mutation evidence on its trusted transport.
|
||||
- GET /v1/approvals/{id} requires approval:read. Approval.as_dict returns id,
|
||||
persisted status, exact binding, validity, and consumption containing original
|
||||
request_digest/decision_id/consumed_at. This existing read is the independent
|
||||
consume-confirmation surface. It includes approver entries, so capture in memory
|
||||
and discard them; never serialize the raw object into a receipt or tool output.
|
||||
|
||||
There is no signed portable consume receipt or dedicated public confirmation
|
||||
endpoint. A caller boolean, ConsumedApproval dataclass, JSON receipt or local file
|
||||
is not trusted proof. The mediator fetches the authoritative object itself through
|
||||
its owner-pinned authenticated endpoint, with no caller-selected origin/opener.
|
||||
Bearer authentication identifies the client to the server; the Platform owner must
|
||||
also establish the server/transport identity. Generic HTTP support in the helper
|
||||
is not evidence of an admitted production transport.
|
||||
|
||||
Identity/read reachability is explicitly unproved. The admitted Secrets client
|
||||
does not grant a new Platform mediator approval:read/consume custody. KeyCape owns
|
||||
any exact client/audience/scope/tenant registration and Platform owns transport and
|
||||
credential custody; do not widen an identity profile or reuse Secrets credentials
|
||||
merely to make a read work. In-cluster callers require the existing reviewed
|
||||
NetworkPolicy namespace admission too. No credential was obtained in this review.
|
||||
|
||||
## Exact binding responsibilities
|
||||
|
||||
Source mechanisms: api.py ApiApplication.identity and consume route; auth.py
|
||||
RS256/JWKS claim verification; store.py Engine.consume/Approval.as_dict/claim;
|
||||
binding.py canonical_binding; execution_confirmation.py staged strict client.
|
||||
|
||||
Native binding digest covers action/actor/principal/purpose/target, preserving
|
||||
arbitrary nested target. Extra top-level execution context is not part of this
|
||||
native digest. It must be covered by the PDP's approval-free digest issued as
|
||||
pdp_digest and the full enriched decision binding.request_digest submitted to
|
||||
consume. Access owner reports ApprovalBindingDigest removes only top-level
|
||||
context.approval: execution_contract remains covered. Compute through Access's
|
||||
actual canonical CheckRequest implementation; never assume Python sorted-key JSON
|
||||
is the Go request digest. Full enriched request includes the served claim.
|
||||
|
||||
Engine.consume validates digest syntax, not equivalence to pdp_digest or act, and
|
||||
does not validate a DecisionEnvelope, decision_id existence or consuming sub
|
||||
against binding.actor. This is the PIP boundary, not a second policy decision
|
||||
point. A service holding consume scope can spend an approved object with an
|
||||
unrelated well-formed digest; that response cannot substitute for the mediator's
|
||||
prior independent exact claim/PDP/body/action/target/actor/principal validation.
|
||||
|
||||
Access's present v2 apply rules do not evaluate execution_contract. A distinct
|
||||
execute-ccr action, published exact package/version/digest and verified initiating
|
||||
principal/representation mapping are prerequisites, not inferred semantics.
|
||||
Create enforces binding.actor==verified requester sub; the design must resolve
|
||||
actual initiating principal vs execution service with Identity/Access owners,
|
||||
without guessing actor strings or treating environment subject text as evidence.
|
||||
All owner-compiled CCR/grant/catalog/source revisions, methods/paths/body hashes,
|
||||
operation UUID and deadlines must remain in the approved underlying context.
|
||||
Approval IDs and served claim additions must follow Access's explicit exclusion.
|
||||
|
||||
## Idempotency and lifecycle
|
||||
|
||||
BEGIN IMMEDIATE serializes consume; status compare-and-swap and local use outbox
|
||||
are one transaction. The first consume requires approved status, current validity
|
||||
window and declared human-control evidence. Different consumed digest conflicts.
|
||||
Same digest returns idempotent=true and the original decision_id even if a retry
|
||||
submits another decision_id, even after original expiry. No second use event is
|
||||
created. That success is historical consumption, never renewed execution power.
|
||||
The staged client requires exact original decision correspondence and rejects
|
||||
string/integer booleans, missing times and decision-shaped responses.
|
||||
|
||||
Revoked/superseded/expired objects reject a first consume. Consumed is terminal:
|
||||
revoke and supersede cannot cancel it, and expiry does not erase historical
|
||||
consumption. A spent claim has valid_now=false (after deadline its reason/state
|
||||
is expired while consumed remains true). Rechecking valid_now after consume
|
||||
cannot validate continuation. The original validated approval/PDP/operation
|
||||
deadlines bound every business write; failure stops further writes. In-flight
|
||||
cancellation requires a separately owned execution stop/cleanup mechanism, not
|
||||
post-consume approval revocation. Cleanup has its explicit original obligation.
|
||||
|
||||
## Independent mediator sequence
|
||||
|
||||
1. Independently reconstruct owner-approved operation bodies and binding; check
|
||||
identity/source/revisions/deadline and exact published PDP package. No native
|
||||
secret read/login, token mint or mutation during preparation.
|
||||
2. Atomically reserve a one-shot execution journal admission for the immutable
|
||||
approval/request/operation tuple; only creator proceeds. This journal is
|
||||
Platform execution state, distinct from approval-engine outbox/consumption.
|
||||
3. Fetch and validate a fresh human-controlled PDP-path claim, call Access Check,
|
||||
require exact underlying/full digest, original act and policy pin, then one
|
||||
CAS consume. Prefer consume at this mediator boundary to early CLI consumption.
|
||||
4. Validate direct consume evidence with consume_exact; if separate Secrets code
|
||||
returns a receipt, independently GET confirm_consumption with expected native
|
||||
act and approval-free PDP digest. Match original exact decision/full digest/time.
|
||||
Do not issue another mutating consume merely to discover whether one happened.
|
||||
5. Persist confirmed evidence in the existing live journal before protected
|
||||
calls. A successful idempotent response or GET without that same live one-shot
|
||||
admission never permits execution. A CAS/read timeout marks unknown; owner
|
||||
reconciliation may read confirmation but does not automatically resume work.
|
||||
6. Check original deadlines before every native call, record about-to-call then
|
||||
outcome, and maintain separately confirmed cleanup. Duplicate completed input
|
||||
returns existing receipt only. Any incomplete/unknown operation requires owner
|
||||
reconciliation and fresh exact recovery approval for another protected action.
|
||||
|
||||
The staged client implements only exact direct evidence and independent read
|
||||
confirmation. It does not implement the journal, authorization policy, server
|
||||
identity admission or execution. Existing Secrets consume_approval accepts wrong
|
||||
approval_id, does not require original decision match and coerces idempotent;
|
||||
Secrets owns its strict handoff refinement. Do not silently extend the generic
|
||||
ProtectedActionHarness into an at-most-once execution service.
|
||||
|
||||
## Gates and validation
|
||||
|
||||
Existing owners/tasks retained: APPROVAL-WP-0002-T05 served T-06 consumer proof;
|
||||
APPROVAL-WP-0002-T01 issuer/profile plus schema-v6 release evidence;
|
||||
SECRETS-WP-0013 implementation and SECRETS-WP-0008-T06 full adoption;
|
||||
RPF-WP-0035-T02 native lane adoption; exact Access/Identity action/representation
|
||||
admission under those owners' records. No dependency is marked closed.
|
||||
|
||||
24 focused tests pass, including authenticated WSGI GET with no mutation/outbox
|
||||
change, wrong act/target/actor/principal/purpose/digest/decision refusal, strict
|
||||
booleans/time, denied read, filtered evidence and idempotency after expiry with
|
||||
terminal revoke/supersede refusal. Staged full suite: 219 passed, one existing
|
||||
JWT short-test-key warning. No production HTTP/DB/OpenBao call or native action.
|
||||
Loading…
Add table
Add a link
Reference in a new issue