Internet-Draft Execution Handle September 2026
Das Expires 20 March 2027 [Page]
Workgroup:
Individual Submission
Internet-Draft:
draft-das-execution-handle-01
Published:
Intended Status:
Informational
Expires:
Author:
S. Das
Independent

Possession Is Not Authority: Execution Handle, Sink Verification, Atomic Consumption, and Finality Receipt

Abstract

Across agentic AI, payments, cloud control planes, industrial actuation, and cross-border processing, a machine can prepare a concrete operation long before that operation is allowed to become externally effective. Existing protocols already move identity, authorization data, attestation results, and signed statements. They do not, by themselves, define the small set of interoperable objects required at the effectuation boundary: a canonical Candidate Act Descriptor, a scoped non-bearer Execution Handle bound to that exact act and to a designated Finality Sink, a verify operation that reconstructs the pending effect, an atomic consume that prevents replay, and a Finality Receipt that records what was actually permitted.

The residual failure is familiar and does not require token forgery. An access token, capability, session cookie, SPIFFE SVID, WIMSE credential, OAuth grant, attestation result, or signed mandate can remain cryptographically valid while being presented for a different tool call, a substituted beneficiary, a second sink, a replayed payment, a migrated region, or an alternate administrative path. Bearer possession then becomes mistaken for current, act-specific authority to effectuate.

Existing mechanisms already address important adjacent problems. OAuth 2.0 and OAuth Rich Authorization Requests can express fine-grained authorization data [RFC6749] [RFC9396]. DPoP and certificate-bound tokens constrain sender possession [RFC9449] [RFC8705]. JWT and CWT carry signed claims [RFC7519] [RFC8392]. HTTP Message Signatures authenticate individual requests [RFC9421]. WIMSE addresses workload identity in multi-system environments [WIMSE-ARCH]. RATS supplies Evidence and Attestation Results [RFC9334]. SCITT supplies signed statements, transparency, and receipts [RFC9943]. MCP and similar tool interfaces dispatch agent-selected functions. None of these objects is specified as a non-bearer, exact-act, sink-bound, single-use-or-bounded effectuation authority whose verification is serialized with protected commit.

This document specifies those wire objects and the verify/consume/receipt exchange. A Candidate Act remains in a Non-Effective State until a Finality Sink reconstructs the security-relevant pending operation, verifies that a current Execution Handle authorizes that exact operation at that sink, consumes or reserves the handle according to its reuse policy, and optionally emits a Finality Receipt. The Execution Handle is not a session token and is not valid merely because the caller can present it.

Prevention is claimed only when exact-act binding, sink binding, currentness, reuse policy, consequence-path coverage, and verification-to-commit serialization are load-bearing. If a deployment uses ordinary bearer tokens, advisory act identifiers, post-hoc logs, or a gateway that can be routed around, the result is mitigation or evidence rather than the same prevention guarantee. Encoding profiles are provided for JSON and COSE/CWT; the architecture requires the semantics, not one exclusive encoding.

Three rejections are expected and are addressed in the body rather than dismissed here. First, a saga, 2PC, or workflow plus ordinary tokens already coordinates steps; that coordinator is complementary, and is enough only if each sink also reconstructs the live act and consumes act-bound authority. Second, atomic consume is not a process-wide lock: SINGLE_USE is per handle, COUNTED and ENVELOPE exist for high-QPS classes, and rails that already keep idempotency keys already pay this cost. Third, reconstruction is required only at the component that would first make the effect real, over fields that sink can observe — not at every mesh hop, and not as blind trust in a caller digest. Reviewers who hold any of those objections are asked to read those sections and to supply a counterexample if the residual gap is already closed. Criticism, prior art, and a recommendation to stop the work remain invited.

Status of This Memo

This Internet-Draft is submitted in full conformance with the provisions of BCP 78 and BCP 79.

Internet-Drafts are working documents of the Internet Engineering Task Force (IETF). Note that other groups may also distribute working documents as Internet-Drafts. The list of current Internet-Drafts is at https://datatracker.ietf.org/drafts/current/.

Internet-Drafts are draft documents valid for a maximum of six months and may be updated, replaced, or obsoleted by other documents at any time. It is inappropriate to use Internet-Drafts as reference material or to cite them other than as "work in progress."

This Internet-Draft will expire on 20 March 2027.

Table of Contents

1. What This Version (-01) Contains

This Internet-Draft is draft-das-execution-handle-01. It specifies the wire objects for execution finality at one Finality Sink: Candidate Act Descriptor, Execution Handle, verify, atomic consume, and Finality Receipt. Companion drafts [DAS-REG] and [DAS-COMPOSITE] name the codes and the multi-sink join.

1.1. Contents of -01

  • Problem, existing OAuth/DPoP/WIMSE/RATS/SCITT mechanisms, residual gap, and the handle objects.
  • Formal model, hash function for the Act Digest (SHA-256 default), and bounded prevention argument.
  • Pseudocode with VERIFY inside the atomic consume block and generations rechecked at commit.
  • ENVELOPE identical-digest replay forbidden unless explicitly allowed.
  • Anticipated criticisms (saga plus tokens, consume cost, reconstruction) and matching abstract hints.
  • Industrial roadmap alignment with non-endorsement, community questions, and IETF venue mapping.
  • Non-normative note on TLA+, Tamarin/ProVerif, and Alloy embeddings.

1.2. Changes from -00

  • Document name and series info updated to -01.
  • Abstract names the three expected rejections so reviewers do not stop at the first page.
  • Verify/generation/revocation checks moved inside the atomic consume block.
  • ENVELOPE default forbids identical replay.
  • Hash-function and formal-verification-tool sections added.
  • Family references aligned to current titles and to registries/composite -01.

2. Introduction

2.1. Vulnerability: A Valid Credential Can Authorize the Wrong Effect

A system can authenticate a caller, verify a signature, confirm an attestation result, and accept a previously issued authorization object, yet still permit an effect that was never the authorized act. The object presented at the boundary may be authentic while the pending operation has been widened, substituted, replayed, relocated, or sent to a different sink.

t0                         t1                         t2
|                          |                          |
| Authority issued for     | arguments / sink /      | protected
| Candidate Act C17        | destination / replay     | effect K
|                          | become C18               |
|--------------------------|--------------------------|
                                                       |
                                                       v
                                          EFFECT of C18 using
                                          authority issued for C17

If C18 is not the authorized act, a valid object at t0
MUST NOT silently authorize K at t2.
Figure 1: Possession of a valid credential survives into the wrong effect

This failure does not necessarily require breaking TLS, forging a JWT, or compromising the issuer. The earlier authorization object can remain intact while the correspondence between that object and the live pending operation is lost.

2.2. Existing Mechanisms Already Address Important Parts

OAuth access tokens authenticate delegated access to an API [RFC6749]. Rich Authorization Requests can carry fine-grained authorization details such as actions, resources, and purpose [RFC9396]. DPoP and certificate-bound access tokens reduce bearer theft by binding a token to a proof-of-possession key [RFC9449] [RFC8705]. JWT and CWT provide signed or encrypted claim sets [RFC7519] [RFC8392]. HTTP Message Signatures can authenticate a particular HTTP request [RFC9421].

WIMSE identifies workloads across systems [WIMSE-ARCH]. RATS appraises execution environments [RFC9334]. SCITT registers signed statements and issues receipts [RFC9943]. Payment mandates, cloud IAM policies, and industrial permit-to-work systems already encode some form of prior approval.

These mechanisms are not treated as deficient. If a deployment already binds current, exact-act, sink-specific, non-replayable authority to the actual consequence and refuses effect otherwise, it already satisfies the core property described here.

2.3. Why the Residual Gap Can Remain

The residual gap appears when the object that crosses the effectuation boundary is still a permission to call an API, prove workload identity, or show that an environment was attested, rather than authority for this exact pending operation at this sink now.

An OAuth token can be sender-constrained and still authorize any operation inside a broad scope. A RAR authorization-detail can describe an intended act and still be evaluated only at token issuance. A DPoP proof can show that the presenter holds a key without showing that the presented arguments are the authorized arguments. An HTTP message signature can cover the bytes on the wire without a sink-local consume record that makes a second identical request fail. A WIMSE identity can remain stable while the act changes. A RATS Attestation Result can remain valid while the model emits a different tool call. A SCITT receipt can prove that a statement was registered without making that statement a prerequisite of effectuation.

Agent tool interfaces amplify the gap. A model can select payout.create, plc.write, or weights.release after a human or policy approved a different action. The dispatch path often treats a valid caller credential as sufficient to invoke the selected function.

2.4. What This Architecture Introduces

The proposed contribution is a compact object set and exchange, not a new identity system and not a replacement for OAuth, WIMSE, RATS, or SCITT.

  • Define a Candidate Act Descriptor (CAD) as the canonical, digestable description of the security-relevant pending operation.
  • Define an Execution Handle (EH) as scoped, preferably non-bearer effectuation authority bound to that CAD digest, a Finality Sink, a reuse policy, and current generations.
  • Define sink verification as reconstruction of the live pending operation and comparison with the handle, not as token presence checking.
  • Define atomic consumption or reservation so that verify-then-effectuate-then-replay is not a successful protocol path.
  • Define a Finality Receipt as evidence of what was verified and whether authority was consumed.
  • Keep the Candidate Act non-effective until verification and the required consume step succeed.

3. Conventions and Requirements Language

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals.

4. Direct Question: What Threat Does This Architecture Solve?

If authority H was issued for Candidate Act C17 at sink S17, what prevents H from making a different act C18 effective, or from making C17 effective a second time, or at sink S18?

Authorized(H) = (C17, S17, g_now, reuse_policy)

Observed(pending) = (C18, S18)

NOT ExactCorrespondence(H, pending)
    OR NOT ConsumeSucceeds(H, pending)
        ==>
NOT Effective(K, pending)

The architecture does not decide whether C17 should have been authorized. It makes the issued authority unusable for a non-corresponding effect.

5. Motivating Scenario: Approved Payout, Substituted Beneficiary

An enterprise agent is permitted to pay a vendor. A Protected Enforcement Domain evaluates the instruction and issues an Execution Handle bound to payer account A, amount 500.00 EUR, beneficiary IBAN-X, rail SEPA_INSTANT, and settlement sink core-post-eu-1. Before the post, a prompt-injected tool argument or a compromised worker replaces IBAN-X with IBAN-Y, or sends the same handle to a second PSP sink. The caller still possesses a valid handle and a valid workload credential.

                 PED issues EH(C17)
                         |
                         v
+-------------+    +------------------+
| Agent / API |--->| Candidate C17    |
|             |    | pay 500 to X     |
+-------------+    +--------+---------+
                            |
                   argument substitution
                   or second sink
                            |
                            v
                     +-------------+
                     | pending C18 |
                     | pay 500 to Y|
                     +------+------+
                            |
                            v
                     [ Settlement Sink ]
                            |
                    reconstruct pending
                    compare to EH(C17)
                       /          \
                     no            yes
                     |              |
                  REJECT     consume + post
Figure 2: Valid handle presented for a substituted settlement act

The same pattern appears in tool dispatch (approved search, live payout.create), OT actuation (approved setpoint, live coil write), and model-release (approved summary, live weight dump). The wire objects are shared; the consequence class is a profile input.

6. Problem Space

6.1. An Access Token Is Not an Execution Handle

An access token typically answers "may this principal use this API under this scope?" An Execution Handle answers "may this exact pending operation become effective at this sink under current generations and reuse policy?"

6.2. Proof of Possession Is Not Exact-Act Binding

Sender-constraining a token to a key prevents some theft cases. It does not bind the token to the digest of the live arguments, destination, rail, coil, or recipient.

6.3. A Request Signature Is Not Atomic Consumption

Signing the request authenticates one presentation. Without sink-local monotonic state, the same signed request, or a second request under the same authority, can still complete more than once.

6.4. Attestation Is Not Effectuation Authority

An Attestation Result can establish that a GPU, TEE, or confidential VM matches expected measurements. It does not authorize a particular subsequent tool call, payment, or actuation.

6.5. A Transparency Receipt Is Not a Permit to Effectuate

SCITT can prove that a statement was signed and registered. Registration does not by itself make the statement a load-bearing precondition of the external effect.

7. Threat Model and Assurance Scope

7.1. Adversary Capabilities

The adversary MAY control or influence the requester, AI agent, prompt, retrieved context, tool-router, application process, ordinary operating system, worker queue, service-mesh route, unprotected argument fields, log redaction, or an alternate administrative path outside the declared Finality Sink.

The adversary MAY replay an Execution Handle, present it at another sink, substitute CAD fields after issuance, fragment one effect into several smaller acts, suppress consume records, crash between verify and commit, or attach a valid handle to a different Candidate Act that shares a session or workload identity.

7.2. Threat Severity and Applicability

Severity is consequence-dependent. The issue deserves high attention for financial settlement, industrial actuation, RF transmit enablement, model-weight or secret release, cross-border disclosure, child-reachable rendering, cloud control-plane mutation, and other irreversible or high-impact effects.

The same objects can be used for lower-risk operations, but a cacheable read of public data should not be forced through single-use consume semantics unless the deployment chooses that profile.

7.3. Baseline Handle Profile

The requester, agent, ordinary network, and unprotected caches are untrusted. The handle issuer / Protected Enforcement Domain, the Finality Sink, cryptographic verification roots, and the consume-state store are trusted.

7.4. High-Assurance Handle Profile

A higher-assurance profile MAY additionally distrust the host operating system, orchestrator, tool server, or application runtime. Handle verification, consume-state, and protected commit must then be anchored in a domain those components cannot rewrite or bypass, such as a TEE, HSM, DPU/SmartNIC, independent settlement core, or hardware-isolated sink.

7.5. Trusted Roots and Limits

The base model assumes the issuer and sink are honest with respect to their declared roles, that consume-state is monotonic for the reuse policy in force, and that every path capable of producing the protected consequence crosses an equivalent sink. Full compromise of issuer and sink, or effectuation outside the declared consequence domain, is outside the base prevention claim.

8. Design Goals and Non-Goals

The design goal is to make exact-act effectuation authority current, sink-bound, reconstructable, consumable, testable, and receivable at the consequence boundary.

This document does not replace OAuth, create a new login protocol, replace WIMSE workload identity, replace RATS, replace SCITT, define which acts should be authorized, determine applicable law, or require every implementation to use a single token syntax.

A profile MAY encode the Execution Handle as a CWT, a detached COSE signature over a CAD digest, a JWT, a protected local capability, or another representation. The architecture requires the semantics in Section 11.

9. Existing Mechanisms and the Proposed Delta

9.1. OAuth Access Tokens and RAR

OAuth tokens and RAR authorization details can express who may do what class of operation on which resource [RFC6749] [RFC9396]. This document does not claim that fine-grained authorization data is new. The residual question is whether the object presented at effectuation is still bound to the live act, the live sink, and a consume record.

9.2. DPoP and Certificate-Bound Tokens

Sender-constrained tokens reduce presentation by a thief who lacks the bound key [RFC9449] [RFC8705]. They do not by themselves digest the pending operation or consume authority at a designated sink.

9.3. HTTP Message Signatures

RFC 9421 can cover selected request components [RFC9421]. A profile MAY use HTTP Message Signatures to authenticate a verify request. Signature validity is not a substitute for CAD correspondence or atomic consume.

9.4. WIMSE, RATS, and SCITT

WIMSE identifies the acting workload. RATS appraises the environment. SCITT can register policy, CAD hashes, or receipts. Each is an input or an evidence channel. None is specified here as the Execution Handle.

9.5. Comparison Summary

Table 1: Existing mechanism and residual effectuation question
Mechanism Strong existing property Residual question only where not already enforced
OAuth access token Delegated API access Does the token authorize this exact pending act at this sink once?
OAuth RAR Fine-grained authorization data Is that data re-bound to the live arguments at commit?
DPoP / cert-bound token Sender constraint Is the sender-constrained object also act- and sink-bound?
JWT / CWT Signed claims container Which claims are load-bearing for effectuation and consume?
HTTP Message Signatures Request authentication Is there sink-local consume state after a valid signature?
WIMSE Workload identity Does this workload's current act match the issued handle?
RATS Environment appraisal Is the Attestation Result being used as a substitute for act authority?
SCITT receipt Registered signed statement Is registration a permit to effectuate, or only evidence?

9.6. What Is New in This Document

The proposed contribution is the composed wire invariant, not any single encoding.

Valid credential for principal P
        !=
authority for pending act C at sink S

For protected act C:

EH binds H(C), S, generations, reuse
AND sink reconstructs C_now
AND Consume(H, C_now, S) succeeds
immediately before or atomically with effectuation.

10. Terminology

Candidate Act: A proposed consequence-bearing operation that has been prepared but has not yet been permitted to become externally effective.

Candidate Act Descriptor (CAD): The canonical, security-relevant description of a Candidate Act used for digesting, issuance, and sink reconstruction.

Act Digest: A cryptographic digest over the canonical CAD fields that the deployment treats as load-bearing.

Execution Handle (EH): Scoped effectuation authority bound to an Act Digest, a Finality Sink, current generations, and a reuse policy. Possession alone is not sufficient.

Protected Enforcement Domain (PED): The function that evaluates act-specific predicates and issues or refuses an Execution Handle.

Finality Sink: The protected functional boundary where the Candidate Act would first become externally effective and where verify/consume occurs.

Non-Effective State: A state in which the Candidate Act cannot yet produce the protected consequence.

Consume: The sink-local state transition that records use of an Execution Handle according to its reuse policy, atomically with or immediately before protected commit.

Finality Receipt: A signed or otherwise protected record that a named sink verified a named Act Digest, applied a consume outcome, and did or did not permit effectuation.

Reuse Policy: The rule governing whether a handle is single-use, bounded-use, or envelope-use inside an explicit hot-path envelope.

11. Object Model

Five objects are defined. Implementations MAY physically merge some of them, but the semantic roles MUST remain distinguishable.

CAD  --digest-->  ActDigest
                     |
                     v
                   PED
                     |
                     v
                    EH  --------+
                                |
pending live operation          |
        |                       |
        v                       v
   reconstructed CAD      [ Finality Sink ]
        |                       |
        +-----------compare-----+
                                |
                         consume state
                                |
                                v
                      effect + Receipt

12. Candidate Act Descriptor

A CAD contains the fields that, if changed, would change the authorization question. Profiles select required fields by consequence class. Fields that are not security-relevant for the profile MUST NOT be included in the Act Digest.

12.1. Core Fields

CAD = {
    version,
    object_type: "candidate_act",
    candidate_act_id,
    act_type,
    consequence_class,
    created_at,
    expires_at,
    actor,                  ; workload / agent / principal reference
    operation,              ; tool, function, instruction type
    arguments_digest,       ; digest of canonical arguments
    destination,            ; resource, payee, coil, recipient, URL class
    purpose,                ; if purpose-sensitive
    jurisdiction_policy_id, ; if jurisdiction-sensitive
    finality_sink,
    policy_generation,
    freshness,
    parent_act_id,          ; optional composition
    extensions
}

candidate_act_id identifies the instance. arguments_digest covers the canonical argument encoding, not a mutable presentation copy. finality_sink names the sink that is allowed to consume the eventual handle.

12.2. Canonicalization and Act Digest

An implementation MUST define a deterministic canonicalization for digest input. JSON profiles SHOULD use JCS [RFC8785] or an explicitly declared equivalent. CBOR profiles SHOULD use deterministic CBOR encoding [RFC8949].

ActDigest = H( Canonical(CAD_load_bearing_fields) )

H is a collision-resistant hash identified in the digest object.

The sink MUST recompute the digest from observed or reconstructed fields. It MUST NOT trust a caller-supplied digest as the sole correspondence check.

12.3. Hash Function for the Act Digest

Hash in d(C) = Hash(Canon(CAD(C)|F)) is a collision-resistant cryptographic hash, not a checksum and not an encryption function. Its only jobs in this protocol are: (1) make two CADs with different load-bearing fields produce different digests except with negligible probability; (2) give the handle a fixed-size binding that can be compared in the atomic consume step.

d(C) = Hash( Canon( fields_F(C) ) )

Collision resistance used by the bounded argument:
    if fields_F(C17) != fields_F(C18)
    then  Pr[ d(C17) = d(C18) ]  is negligible.

Therefore:
    H issued for C17
    and sink observes C18
    =>  d(C18) != H.d
    =>  VERIFY fails with EF-023

Hash does NOT provide:
    confidentiality of arguments
    policy correctness
    sender authentication   (that is sigma / key-binding)
    freshness by itself     (that is g and t_exp)

JSON profiles SHOULD identify the algorithm as SHA-256 [RFC6234] unless the profile declares another collision-resistant function. The digest object MUST name the algorithm so two implementations do not silently hash with different functions. SHA-1 and non-cryptographic checksums (CRC, CityHash) MUST NOT be used for d(C). Collision-resistant unkeyed hashes such as BLAKE2b and BLAKE3 MAY be used if the profile names them.

Canonicalization happens *before* the hash. Hashing a different JSON serialization of the same fields is a correspondence bug, not a hash-function bug. That is why JCS or deterministic CBOR is required.

Privacy: if F has low entropy (small amount set, small beneficiary set), d(C) can be brute-forced offline. Profiles for those classes SHOULD include a per-act nonce in F, or SHOULD treat the digest as sensitive in receipts sent off-path. A hash does not hide a guessable act.

12.4. Illustrative JSON CAD

{
  "version": "1.0",
  "object_type": "candidate_act",
  "candidate_act_id": "urn:example:act:7f3c",
  "act_type": "PAYMENT_POST",
  "consequence_class": "FINANCIAL",
  "created_at": "2026-09-16T16:01:00Z",
  "expires_at": "2026-09-16T16:11:00Z",
  "actor": {
    "workload_id": "spiffe://example/agent-pay"
  },
  "operation": {
    "tool_id": "payout.create",
    "function_id": "create"
  },
  "arguments_digest": {
    "algorithm": "SHA-256",
    "value": "base64url-digest-of-canonical-args"
  },
  "destination": {
    "beneficiary_id": "iban:X",
    "rail": "SEPA_INSTANT"
  },
  "finality_sink": {
    "sink_id": "core-post-eu-1",
    "sink_type": "SETTLEMENT"
  },
  "policy_generation": "pg-441",
  "freshness": {
    "nonce": "n-19",
    "not_before": "2026-09-16T16:01:00Z"
  }
}

13. Execution Handle

An Execution Handle is issued only after PED validation of the CAD. It is authority to complete verification at a named sink, not a general API credential.

13.1. Required Semantic Fields

EH = {
    version,
    object_type: "execution_handle",
    handle_id,
    issuer,
    issued_at,
    expires_at,
    act_digest,
    candidate_act_id,
    finality_sink_id,
    reuse_policy,           ; SINGLE_USE | COUNTED | ENVELOPE
    max_uses,               ; if COUNTED
    envelope,               ; if ENVELOPE: bounded field ranges
    generations,            ; policy, revocation, topology, context
    confirmation_method,    ; how the sink proves correspondence
    not_bearer_alone,       ; true in the strict profile
    key_binding,            ; optional PoP key
    extensions
}

13.2. Non-Bearer Rule

In the strict profile, presenting EH is never sufficient. The sink MUST additionally establish at least:

  1. correspondence between EH.act_digest and the reconstructed pending CAD;
  2. correspondence between EH.finality_sink_id and the verifying sink;
  3. currentness of required generations;
  4. success of the reuse/consume rule;
  5. any required key-binding or workload-binding proof.

A profile MAY add sender key-binding. Key-binding WITHOUT act digest and sink binding is DPoP-class mitigation, not an Execution Handle in the sense of this document.

13.3. Reuse Policy

SINGLE_USE:
    first successful consume wins;
    later presentations fail with AUTHORITY_ALREADY_USED.

COUNTED:
    consume increments a protected counter;
    fail when count would exceed max_uses.

ENVELOPE:
    handle authorizes repeated acts only while each live CAD
    remains inside an explicit bounded envelope.
    Identical replay of the same act digest is FORBIDDEN
    unless the envelope textually sets allow_identical_replay.

Envelope reuse MUST NOT be used to smuggle a changed destination, amount, coil, recipient, or consequence class. Those fields are outside the envelope by default unless the envelope textually includes them. Identical replay defaults to forbidden so that ENVELOPE cannot become an unbounded bearer replay window.

14. Sink Verification, Consume, and Receipt

14.1. Verify

Verify is performed by the Finality Sink, not by the caller. The sink reconstructs the pending operation from sink-local observation where possible.

VERIFY(pending, EH) =
    handle_integrity_valid(EH)
AND handle_not_expired(EH)
AND sink_id_matches(EH, this_sink)
AND act_digest_matches(EH, reconstruct(pending))
AND generations_current(EH)
AND workload_binding_ok_if_required(EH, pending)
AND pop_ok_if_required(EH, pending)
AND reuse_state_allows(EH)

Failure codes in Section 19 are illustrative pending registry action.

14.2. Atomic Consume

For SINGLE_USE and COUNTED handles, consume MUST be serialized with protected commit so that the following history is not a successful protocol:

Verify(EH, C) success
        |
        v
Effect(K)
        |
        v
Replay(EH, C) success     <-- forbidden

The required ordering is:

atomic {
    assert VERIFY(pending, EH)          // includes generations
    CONSUME(EH)
    COMMIT(pending)
}

VERIFY outside this block is only a hint.
Generations, digest, sink, and pending correspondence
MUST be re-evaluated inside the block.
A revocation or generation change that lands after an
out-of-block verify and before commit MUST fail
(EF-041 or EF-062), not commit.

If the platform cannot provide a single atomic section, it MUST provide crash recovery that cannot complete a second effect from the same SINGLE_USE handle, and it MUST re-run VERIFY immediately before consume. An implementation that verifies once outside the block and only rechecks consume-state inside it does not meet this document, because that path admits a revocation between verify and commit.

14.3. Finality Receipt

A Finality Receipt records the sink's decision. It is evidence, not a new handle. A receipt MUST NOT be presented in place of an Execution Handle to authorize a further effect unless a profile explicitly defines receipt-to-handle derivation, which this document does not.

Receipt = {
    object_type: "finality_receipt",
    receipt_id,
    sink_id,
    handle_id,
    candidate_act_id,
    act_digest,
    decision,            ; EFFECTUATED | REJECTED
                         ; PREPARED | ABORTED are composite-child
                         ; decisions (prepare / abort reserve),
                         ; not a second handle.  See DAS-COMPOSITE.
    consume_outcome,     ; CONSUMED | RESERVED | RELEASED
                         ;   | UNCHANGED | FAILED
    reason_code,         ; if REJECTED
    generations_observed,
    issued_at
}

A profile MAY register receipts with SCITT [RFC9943]. Transparency of the receipt does not replace sink verification of a later act.

15. State Machine

+----------------+
| CANDIDATE ACT  |
| NON-EFFECTIVE  |
+-------+--------+
        |
        v
+-------------------------+
| PED validates predicates|
| issues EH or refuses    |
+------------+------------+
             |
        issued EH
             |
             v
+-------------------------+
| PRESENT AT SINK         |
| reconstruct pending CAD |
+------------+------------+
             |
             v
+-------------------------+
| VERIFY                  |
+------+-------------+----+
       |             |
      fail          pass
       |             |
       v             v
    RECEIPT     CONSUME + COMMIT
    REJECTED         |
                     v
                  RECEIPT
                  EFFECTUATED
Figure 3: Handle lifecycle from Candidate Act to receipt

16. Formal Model

Let C be the Candidate Act, CAD(C) its descriptor, H an Execution Handle, S the verifying sink, K the protected consequence, and Store the sink-local consume state. The identities below are the same rules as the later pseudocode, written so that a substitution or a verify/consume race can be named.

Let Fields(C) be the load-bearing field set of profile pi.
Let Canon be the profile canonicalization.

    d(C)  =  Hash( Canon( CAD(C) | Fields(C) ) )

    H     =  ( id, d(C), S, g, rho, t_exp, sigma )

where g is the generation vector,
rho in {SINGLE_USE, COUNTED, ENVELOPE},
sigma is the issuer authenticator,
and t_exp is expiry.

Possession(caller, H) is not a predicate of authority:

    Auth(H, C', S', g_now, Store, t)
        iff  VerifySig(H.sigma)
        and  t < H.t_exp
        and  d(C') = H.d
        and  S' = H.S
        and  Current(H.g, g_now)
        and  ConsumeOK(H, Store, C')

    Effect(K, C', S', t)
        iff  Auth(H, C', S', g_now(t), Store, t)
        and  Commit(S', C', t)
        and  PathCovered(K, S')

Prevention (bounded):
    not Auth(...)  =>  not Effect(K, C', S', t)

Race constraint (verify must be inside the atomic step):

    let t_v < t_c be verify time and consume time.
    if g_now(t_c) != g_now(t_v) or Revoked(H, t_c)
        then Consume at t_c MUST fail.

    i.e.   Auth uses g_now(t_c), not g_now(t_v).

ENVELOPE replay default:
    ReplayRuleOK(H, C', Store)
        iff  InsideEnvelope(C', H.envelope)
        and  ( d(C') notin UsedDigests(Store, H)
               or H.envelope.allow_identical_replay = true )
Issued(H, C, S) :=
       PEDValidated(C)
   AND H.act_digest == Digest(CAD(C))
   AND H.finality_sink_id == S.id
   AND HandleIntegrityValid(H)

Corresponds(H, C_now, S_now) :=
       Issued(H, C_iss, S_iss)
   AND Digest(CAD(C_now)) == H.act_digest
   AND S_now.id == H.finality_sink_id
   AND GenerationsCurrent(H)
   AND NotExpired(H)

ConsumeOK(H, Store) :=
    case H.reuse_policy of
      SINGLE_USE => Store[H.id] == UNUSED
      COUNTED    => Store[H.id].count < H.max_uses
      ENVELOPE   => InsideEnvelope(C_now, H.envelope)
                    AND ReplayRuleOK(H, C_now, Store)
Effective(K, C_now)
    ==>
Corresponds(H, C_now, S_now)
AND ConsumeOK(H, Store)
AND ProtectedCommit(S_now, C_now)
AND PathCovered(K, S_now)

Strict prevention:

NOT Corresponds(H, C_now, S_now)
 OR NOT ConsumeOK(H, Store)
    ==>
NOT Effective(K, C_now)

16.1. Bounded Prevention Argument

Assume: (1) every load-bearing field of C is in CAD and therefore in the Act Digest; (2) the sink reconstructs those fields from the pending effect rather than trusting the caller digest alone; (3) consume-state is monotonic and crash-safe for the reuse policy; (4) verification and commit are serialized against consume-state updates; and (5) every technically viable path to K crosses an equivalent sink.

Suppose K becomes effective for C18 using H issued for C17, or a second K is produced from a SINGLE_USE H. Then either Digest(CAD(C18)) equals Digest(CAD(C17)) while the security-relevant fields differ, contradicting collision resistance and canonicalization, or consume-state allowed a second use, contradicting monotonic consume, or a path bypassed the sink, contradicting path coverage. The argument establishes only enforcement of the issued handle semantics; it does not prove that the PED decision was a good policy decision.

16.2. Formal Verification Tools (Non-Normative)

This document is an Internet-Draft, not a machine-checked development. The identities in the formal model are written so they can be transcribed into existing tools. No tool is required to implement a sink. A checked model is useful when a reviewer disputes the verify/consume race or the ENVELOPE replay default.

Suggested embeddings:

  • TLA+ / PlusCal: encode Store, q in {UNUSED, USED, COUNTED(n), PREPARED}, and the atomic action VerifyConsumeCommit as one TLA+ action. Invariants: SINGLE_USE handle produces at most one EFFECTUATED; generations sampled inside the action equal g_now at commit; a revoked handle never commits.
  • Tamarin or ProVerif: treat H.sigma as a signature, d(C) as a hash query, and Effect as an event. Correspondence lemma: Effect(C',S') occurs only if Issued(H,C,S) with d(C')=d(C) and S'=S.
  • Alloy or Quint: small-scope check that two workers cannot both observe UNUSED and both commit.
TLA+ invariant (SINGLE_USE):

    []( Cardinality({ k : Effectuated(H, k) }) <= 1 )

Tamarin-style correspondence:

    Effect(C', S')
        ==>
    Ex H, C.
        Issued(H, C, S')
        & d(C') = d(C)
        & not Revoked(H)

These lemmas are the same claims as the
pseudocode in consume_and_commit.
A counterexample in TLA+ would be a protocol bug;
a counterexample only in a mis-written spec would not.

Composite join [DAS-COMPOSITE] is the part that most benefits from TLA+: the COMMIT-then-crash-then-TTL-abort path is exactly the split state EF-047. A model that allows that path under PreventionWellFormed is wrong.

17. Encoding Profiles

This section is non-normative as to exclusive syntax. An interoperable profile MUST declare one encoding and one canonicalization.

17.1. JSON Profile

CAD, EH, verify request/response, and receipts MAY be JSON objects. Digests use JCS [RFC8785] over the declared load-bearing subset. HTTP deployments MAY carry EH in an Authorization header of the form:

Authorization: EFHandle <base64url(EH)>
EF-Act-Digest: sha-256=<base64url>

The header names above are illustrative. A later revision or companion registry draft may request permanent field names.

17.2. COSE / CWT Profile

An Execution Handle MAY be a CWT [RFC8392] whose claims include act digest, sink identifier, reuse policy, generations, and expiry. The CWT MAY be sender-constrained by a confirmation claim, but confirmation does not replace act digest or sink identifier.

A Finality Receipt MAY be a COSE_Sign1 object over the receipt fields, optionally registered in a SCITT Transparency Service [RFC9943].

18. Illustrative HTTP Binding

The following exchange is illustrative for an HTTPS sink. MCP, industrial buses, and settlement cores can map the same verbs onto their native transports.

POST /finality/verify-and-commit
Content-Type: application/ef-pending+json
Authorization: EFHandle ...

{
  "pending": { ... observed operation fields ... },
  "handle": { ... EH or handle reference ... },
  "nonce": "n-88"
}

201
Content-Type: application/ef-receipt+json

{
  "object_type": "finality_receipt",
  "decision": "EFFECTUATED",
  "consume_outcome": "CONSUMED",
  "act_digest": "...",
  "handle_id": "...",
  "sink_id": "core-post-eu-1"
}

A sink MAY separate verify from commit only if consume-state prevents a second commit. Soft-verify without consume MUST NOT be treated as permission to effectuate.

19. Failure Codes

The following codes are illustrative and are not IANA assignments. A companion registry draft should own the stable namespace.

EF-002  NO_FINALITY_AUTHORITY
EF-003  HANDLE_INTEGRITY_FAILURE
EF-004  HANDLE_EXPIRED
EF-005  AUTHORITY_ALREADY_USED
EF-006  REPLAY_DETECTED
EF-012  SCOPE_MISMATCH
EF-020  DESTINATION_MISMATCH
EF-023  ACT_DIGEST_MISMATCH
EF-040  SINK_MISMATCH
EF-041  GENERATION_STALE
EF-042  REUSE_POLICY_VIOLATION
EF-043  ENVELOPE_EXCEEDED
EF-062  REVOCATION_ACTIVE
EF-070  ESCALATION_REQUIRED
EF-080  FAIL_CLOSED
EF-081  CONSUME_STATE_UNAVAILABLE

A strict prevention profile MUST fail closed when consume-state is unavailable (EF-081), rather than treating missing state as unused.

20. Illustrative Pseudocode

The following pseudocode is non-normative. It separates CAD construction, digesting, issuance, reconstruction, verify, consume, commit, receipt, crash recovery, and envelope reuse.

20.1. Construct and Digest a Candidate Act

function make_cad(pending):
    fields = security_relevant_fields(pending)
    cad = {
        version: "1.0",
        object_type: "candidate_act",
        candidate_act_id: new_id(),
        act_type: fields.act_type,
        consequence_class: fields.consequence_class,
        actor: fields.actor,
        operation: fields.operation,
        arguments_digest: digest(canonicalize(fields.arguments)),
        destination: fields.destination,
        finality_sink: fields.finality_sink,
        policy_generation: current_policy_generation(),
        freshness: { nonce: new_nonce(), not_before: now() },
        created_at: now(),
        expires_at: now() + pending.ttl
    }
    cad.act_digest = digest(canonicalize(load_bearing(cad)))
    return cad

20.2. Issue an Execution Handle

function issue_handle(cad, policy):
    if !verify_cad_integrity(cad):
        reject("EF-003")

    if !ped_predicates_satisfied(cad, policy):
        reject("EF-002")

    if cad.expires_at <= now():
        reject("EF-004")

    eh = {
        object_type: "execution_handle",
        handle_id: new_id(),
        issuer: ped_id(),
        issued_at: now(),
        expires_at: min(cad.expires_at, policy.handle_ttl),
        act_digest: cad.act_digest,
        candidate_act_id: cad.candidate_act_id,
        finality_sink_id: cad.finality_sink.sink_id,
        reuse_policy: policy.reuse_policy_for(cad),
        generations: current_generation_vector(),
        not_bearer_alone: TRUE
    }
    return sign_or_mac(eh, ped_key())

20.3. Reconstruct the Pending Act at the Sink

function reconstruct_pending(observed):
    # Prefer sink-local observation of the effect about to occur.
    # Do not accept caller CAD as authoritative if the sink can
    # see the live operation fields.

    live = {
        act_type: observed.act_type,
        operation: observed.operation,
        arguments: observed.arguments,
        destination: observed.destination,
        actor: observed.actor_if_known
    }

    cad_now = make_cad_from_live(live)
    return cad_now

20.4. Verify Handle Against Reconstructed Act

function verify_handle(eh, cad_now, sink):
    if !verify_signed(eh, trusted_issuers()):
        return FAIL("EF-003")

    if eh.expires_at <= now():
        return FAIL("EF-004")

    if eh.finality_sink_id != sink.id:
        return FAIL("EF-040")

    if eh.act_digest != cad_now.act_digest:
        return FAIL("EF-023")

    if !generations_current(eh.generations):
        return FAIL("EF-041")

    if eh.key_binding and !proof_of_possession(eh):
        return FAIL("EF-012")

    return PASS

20.5. Consume and Commit

function reject(code):
    write_receipt(REJECTED, code)
    remain_non_effective()
    return REJECTED

function consume_and_commit(eh, cad_now, sink, pending):
    begin_protected_finality_section()

    atomic {
        # VERIFY is inside the block so revocation /
        # generation change after a speculative check
        # cannot commit.
        result = verify_handle(eh, cad_now, sink)
        if result != PASS:
            return reject(result.code)

        if !generations_current(eh.generations):
            return reject("EF-041")
        if revoked(eh):
            return reject("EF-062")
        if eh.act_digest != cad_now.act_digest:
            return reject("EF-023")

        state = consume_store.get(eh.handle_id)

        if eh.reuse_policy == SINGLE_USE:
            if state != UNUSED:
                return reject("EF-005")
            consume_store.put(eh.handle_id, USED)

        else if eh.reuse_policy == COUNTED:
            if state.count >= eh.max_uses:
                return reject("EF-005")
            consume_store.put(eh.handle_id,
                              state.count + 1)

        else if eh.reuse_policy == ENVELOPE:
            if !inside_envelope(cad_now, eh.envelope):
                return reject("EF-043")
            if replayed_identical_act(eh, cad_now) and
               not eh.envelope.allow_identical_replay:
                return reject("EF-006")
            record_envelope_use(eh, cad_now)

        assert exact_observed_effect_still_matches(
                   pending, cad_now)
        commit_protected_effect(pending)
    }

    write_receipt(EFFECTUATED, CONSUMED)
    return EFFECT_COMMITTED

20.6. Crash-Safe Recovery

function recover(handle_id, candidate_id):
    commit_state = protected_commit_state(candidate_id)
    consume_state = consume_store.get(handle_id)

    if commit_state == EFFECTIVE:
        return DO_NOT_REPLAY

    if commit_state == COMMITTING:
        outcome = resolve_atomic_commit(candidate_id)
        if outcome == EFFECT_COMMITTED:
            return DO_NOT_REPLAY
        return REVERIFY_AND_RESUME_OR_FAIL_CLOSED

    if consume_state == USED and commit_state != EFFECTIVE:
        # consume happened; effect uncertain
        return RESOLVE_FROM_SINK_LOG_OR_FAIL_CLOSED

    return REVERIFY_CURRENT

20.7. Forward a Handle Reference Across Hops

function forward_to_next_workload(cad, eh, next):
    envelope = {
        candidate_act_id: cad.candidate_act_id,
        act_digest: cad.act_digest,
        handle_reference: reference_for(eh),
        sink_id: eh.finality_sink_id,
        generations: eh.generations
    }
    return authenticated_forward(next, envelope)

# Downstream MUST NOT treat the forwarded reference as current
# authority.  Only the named Finality Sink consumes.

20.8. Emit a Finality Receipt

function write_receipt(decision, consume_outcome, eh, cad_now, code):
    receipt = {
        object_type: "finality_receipt",
        receipt_id: new_id(),
        sink_id: this_sink.id,
        handle_id: eh.handle_id,
        candidate_act_id: cad_now.candidate_act_id,
        act_digest: cad_now.act_digest,
        decision: decision,
        consume_outcome: consume_outcome,
        reason_code: code,
        generations_observed: current_generation_vector(),
        issued_at: now()
    }
    signed = sign_or_mac(receipt, sink_key())
    store_local(signed)
    optionally_register_scitt(signed)
    return signed

21. Composition with Existing Protocols

21.1. OAuth

An access token MAY authenticate the caller to the PED or to the sink transport. It MUST NOT be treated as the Execution Handle unless it carries every required handle field and the sink applies verify/consume semantics. RAR authorization details MAY populate CAD fields at issuance time; the sink still reconstructs the live act.

21.2. WIMSE

WIMSE credentials can populate CAD.actor and EH workload binding [WIMSE-ARCH]. Stable workload identity does not imply a stable act. The handle remains bound to ActDigest, not only to the workload identifier.

WIMSE identity:  workload://tenant/agent-pay
                      |
                      | remains stable
                      v
                 +----------+
                 | Workload |
                 +----+-----+
                      |
            +---------+----------+
            |                    |
            v                    v
        CAD C17               CAD C18
        pay vendor X          pay vendor Y

Same identity, different ActDigest, different EH requirement.
Figure 4: Workload identity can remain stable while the pending act changes

21.3. RATS

An Attestation Result MAY be a PED input that the environment is acceptable [RFC9334]. It is not an Execution Handle. A profile MAY include an attestation-result digest among CAD freshness or trust fields when environment currentness is load-bearing for the act.

21.4. SCITT

SCITT can register jurisdiction or purpose policy, CAD hashes, issuer public keys, or Finality Receipts [RFC9943]. A SCITT receipt for policy registration does not authorize effectuation of C.

21.5. MCP and Tool Dispatch

For tool interfaces, the Finality Sink is the component that would otherwise invoke the selected function. The CAD operation fields identify tool and function. The arguments_digest covers canonical tool arguments. Dispatch without verify/consume is an alternate path if that dispatch can produce the same external effect.

22. Consequence-Path Completeness

Handle verification at one API is insufficient when another route can produce the same consequence. A prevention profile composes with consequence-path completeness.

Normal path:
  C -> PED -> EH -> Sink verify/consume -> K

Alternate path:
  C -> raw API key / admin console / replica worker ------> K

If the alternate path can produce K without equivalent
verify/consume, the deployment cannot claim prevention.
Figure 5: Valid handle path beside an unmediated alternate path

23. Attack Analysis

23.1. Argument or Destination Substitution

Live arguments change after issuance. Reconstructed ActDigest diverges and verify fails with EF-023 or EF-020.

23.2. Handle Replay

The same SINGLE_USE handle is presented again. Consume state returns EF-005 or EF-006.

23.3. Cross-Sink Presentation

A handle issued for sink S17 is sent to S18. Sink binding fails with EF-040.

23.4. Stolen Handle Without Live Correspondence

Theft of a handle object does not authorize an arbitrary act. The thief must also cause the sink to observe a pending operation matching the bound digest. If they can do that through an unmediated path, the failure is path coverage, not handle syntax.

23.5. Act Fragmentation

An adversary splits one prohibited 10,000 payment into twenty 500 payments under an envelope. Envelope profiles MUST bind amount ceilings, destination sets, and aggregation rules if fragmentation is in the threat model.

23.6. Verify-Then-Effect-Then-Replay

Without atomic consume, two workers can both observe UNUSED and both commit. Serialization or compare-and-swap on consume-state is required.

23.7. Crash Between Consume and Commit

Recovery must not reopen a SINGLE_USE handle after consume, and must not leave an effect without a consume record if the platform later treats UNUSED as authorizable.

23.8. Receipt Presented as Authority

A prior EFFECTUATED receipt is replayed as if it were a new handle. Sinks MUST reject receipts in the handle slot.

24. Deployment Patterns

24.1. Inline Sink

The component that would emit the external effect implements verify/consume itself. This is the preferred prevention placement.

24.2. Organization Egress Sink

When the external service will not implement handles, the deploying organization places the sink at its own egress and forwards only after consume. Residual risk is any other path that can reach the same external effect.

24.3. Hot-Path Envelope

Repeated low-risk calls inside a fixed envelope MAY reuse one handle. The sink check remains mandatory. Crossing the envelope is a new Candidate Act.

25. Industrial Relevance and Public-Roadmap Alignment

Public product roadmaps already move identity, tool connectivity, sovereign-cloud residency, confidential-compute attestation, and agent governance forward. This section records only that complementary relationship. It does not assert that any named company has a gap, has adopted this architecture, plans to adopt it, or should adopt it. Where a vendor system already reconstructs the live act, binds authority to that act and sink, consumes reuse state, and refuses effect otherwise, that deployment already satisfies the core property.

25.1. How This Section Must Be Read

Named companies, products, foundations, and protocols appear only as documented public surfaces on which an Execution Handle could be composed. They are not accused of vulnerability, deficiency, non-conformance, incomplete security, or inadequate governance. They are not described as partners, customers, or implementers of this Internet-Draft. Roadmap language below is limited to what the cited public materials already state. Readers who work at those organizations are asked to correct any mis-statement of their public position.

Public roadmap object          Complementary handle question
-------------------------      -----------------------------------------
MCP tool listing / call        Is tools/call the live CAD, or only a name?
Copilot / agent connector      Does the connector credential authorize
                               this exact pending invoke?
Sovereign cloud / EU boundary  Is the current effectuation context still
                               the one the handle was issued under?
GPU / Realm attestation        Is the Attestation Result an input to PED
                               issuance, or a substitute for the handle?
PSP / rail API token           Does the token authorize this beneficiary,
                               amount, rail, and sink once?
Egress / API gateway           Can the same K occur on a path that never
                               verifies or consumes a handle?

25.2. Agent Tool Connectivity: MCP and Copilot-Class Platforms

Anthropic published the Model Context Protocol as an open interface for connecting models to tools and data [MCP-SPEC]. OpenAI, Google DeepMind, Microsoft, AWS, and others have publicly described MCP support in agent products. Microsoft documents MCP integration in Copilot Studio, including tool listing and connector-mediated enterprise controls [MS-MCP-GA] [MS-MCP-LEARN]. Anthropic later donated MCP to the Linux Foundation Agentic AI Foundation with public support from additional industry participants [AAIF-MCP].

Those roadmaps address connectivity, discovery, and (in some products) caller authentication and data-loss-prevention at the connector. They do not, in the cited materials, define a non-bearer Execution Handle bound to a reconstructed live argument digest, a designated dispatch sink, and atomic consume. The composition is therefore:

MCP / Copilot / Agents SDK
   "which tools exist and how is the caller authenticated?"
            |
            v
PED + Execution Handle
   "is THIS reconstructed tools/call the authorized act?"
            |
            v
dispatch sink verify / consume
            |
            v
external tool effect

If an MCP server, Copilot connector, or agent runtime already performs that exact-act verify/consume step, this draft adds only vocabulary. If it does not, the draft is a candidate profile, not a claim that the product is unsafe.

25.3. Cloud Identity, IAM, and WIMSE-Shaped Workload Credentials

Microsoft Entra, AWS IAM, and Google Cloud workload identity already issue principal and workload credentials at planetary scale. WIMSE is standardizing workload identity across multi-system environments with active industry participation [WIMSE-ARCH].

Those systems answer "which workload is acting?" An Execution Handle answers a later question: whether the current pending operation of that workload is the authorized operation at this sink. A stable Azure managed identity, AWS role, or SPIFFE ID can outlive the act it was thought to cover. Composition is additive:

Cloud IAM / WIMSE / SPIFFE
        "who is the workload?"
                |
                v
Execution Handle
        "what exact act may become effective, where, how many times?"

25.4. Sovereign Cloud and Data-Boundary Roadmaps

Microsoft documents the EU Data Boundary and continuing-transfer cases [MS-EUDB] [MS-EUDB-TRANSFERS]. AWS documents the European Sovereign Cloud [AWS-ESC]. Google Cloud documents partner-operated Sovereign Controls including residency, external key management, and local supervision [GOOGLE-SOV].

Those roadmaps supply residency, operator, and key-control dimensions. They are natural inputs to CAD fields and to jurisdiction-bound finality [DAS-JURISDICTION]. They are not replaced by an Execution Handle. The handle only makes the current permitted context a load-bearing condition of the specific act that is about to commit.

25.5. Confidential Compute and Accelerator Attestation

NVIDIA documents local and remote GPU and NVSwitch attestation [NVIDIA-ATTEST]. Arm documents the Confidential Compute Architecture and Realm attestation [ARM-CCA]. Cloud providers similarly document confidential VMs and attested GPU attachments.

Those roadmaps establish technical trust in hardware, firmware, and isolation state. An Attestation Result remains an input to PED issuance or to a CAD trust field. It does not become the Execution Handle. Treating a valid GPU attestation as permission to release weights, post a payment, or invoke an arbitrary MCP tool would collapse two layers this document keeps separate.

25.6. Agentic Payments and Rail APIs

Payment service providers, card schemes, and banks already operate settlement sinks, mandates, strong-customer-authentication, and replay controls. Some platforms also publish MCP servers or agent-payment APIs so that a model can construct an instruction.

A rail token or vendor mandate is complementary prior approval. The Execution Handle is the later object that must still match amount, currency, beneficiary, rail, and settlement sink at post time. A PSP that already consumes instruction-digest-bound, single-use authority at the core already implements the invariant under another name.

25.7. Edge, API Gateway, and Organization Egress

Cloudflare and similar platforms publicly host remote MCP servers and organization egress controls. Cloud customer accounts already terminate TLS and apply IAM at API gateways. When a third-party SaaS will not implement handles, the deploying organization's egress is the realistic Finality Sink. That placement is an integration pattern, not a requirement that any gateway vendor change its product.

25.8. What This Document Does Not Claim About Industry Roadmaps

  • It does not claim that MCP, Copilot Studio, ChatGPT Agents, Gemini, Bedrock, Entra, IAM, EU Data Boundary, European Sovereign Cloud, Sovereign Controls, NVIDIA attestation, or Arm CCA are incomplete, insecure, or non-compliant.
  • It does not claim that any named company has reviewed, implemented, funded, or endorsed this Internet-Draft.
  • It does not interpret a public preview, GA announcement, or foundation donation as a commitment to Execution Handles.
  • It does not treat marketplace tool listing as effectuation authority.
  • It does not treat confidential-compute attestation as legal or act-specific authorization.
  • It does not require a vendor to place the sink inside their hosted model. An organization-side egress sink is a conforming placement.

25.9. Corrections and Criticism from Named Parties Are Requested

Engineers, product counsel, and standards participants at the organizations named above — and at any organization omitted by mistake — are invited to correct this section. Useful corrections include:

  • a public mechanism that already binds a reconstructed live tool call or payment instruction to single-use or counted consume state at the actual consequence;
  • a mis-cited roadmap URL, date, or product name;
  • a product that already fails closed when consume-state is unavailable;
  • a reason that profiling existing OAuth, DPoP, WIMSE, or MCP authorization is sufficient and this object is unnecessary;
  • a privacy, performance, or operational reason that sink reconstruction is infeasible in a named product class;
  • a request to remove a company name because the alignment is overstated.

A demonstrated equivalent mechanism should shrink this draft. Silence from a named company MUST NOT be read as agreement, disagreement, or product intent.

25.10. Non-Endorsement, Non-Affiliation, and Non-Criticism

Microsoft, OpenAI, Anthropic, Google, Amazon Web Services, NVIDIA, Arm, Cloudflare, Linux Foundation / AAIF, payment networks, and any other named organization are referenced only as public technical context. This document does not assert vulnerability, deficiency, non-conformance, affiliation, partnership, funding, endorsement, or a requirement that any named product adopt this architecture. Trademarks remain the property of their owners.

26. Performance and Availability

CAD construction, policy evaluation, and handle issuance can occur on a cold path. The hot path is digest compare, generation compare, consume-state update, and commit. Synchronous PED round-trips on every effect are not required if a still-current handle exists and the sink revalidates currentness locally.

Consume-state unavailability MUST fail closed for SINGLE_USE high-consequence acts. Read-only or low-assurance profiles MAY define an explicit degraded mode; they MUST NOT label that mode as equivalent to the strict profile.

Consume-state does not have to be a single global database. A sink MAY partition by handle_id, by destination, or by tenant, provided that two workers that could commit the same handle share one linearizable row or compare-and-swap slot for that handle. Horizontal scaling of unrelated handles is therefore the same problem as any other single-row unique constraint. What this document forbids is scaling-by-ignoring: two replicas both posting because neither saw the other consume.

27. Anticipated Criticisms

Three objections are expected from distributed-systems and platform reviewers. They are treated as design constraints, not as attacks on the reviewers. Where the objection is correct, the profile MUST shrink its claim.

27.1. Objection: A Saga or 2PC Plus Ordinary Tokens Is Enough

Workflow engines, sagas, TCC, XA, and transactional outbox already order side effects. An OAuth or WIMSE token can sit on each step. That combination is often the right engineering answer for mitigation: the workflow retries, compensates, and leaves an audit trail.

It is not the same property as an Execution Handle. A saga step that presents a still-valid access token after the beneficiary, amount, or tool arguments have changed will still run. A 2PC prepare that does not reconstruct the live child act will prepare the wrong act. Compensation that reuses the original token is not a new authorized reverse; it is another presentation of the same bearer object. Those cases are specified in [DAS-COMPOSITE].

saga + access token
    orders steps
    and authenticates the caller

handle at the sink
    binds THIS reconstructed act
    at THIS sink
    THIS many times

both can exist
    saga is the coordinator
    handle is the child authority

saga success log
        !=
    every required child effectuated
        under a current exact-act handle

If a deployment can show that each saga step already reconstructs the live act, binds a single-use or counted authority to that digest and sink, and fails closed on consume-store loss, that deployment already implements this draft under other names. The useful review is that demonstration, not the existence of sagas.

27.2. Objection: Atomic Consume Is a Serialization Tax

Forcing a crash-safe monotonic consume before every post looks like a cross-replica lock on a hot rail. That criticism is correct if consume-state is designed as one global counter for all traffic.

The intended hot path is:

cold path (once per act):
    build CAD, evaluate policy, issue EH

hot path (per attempt):
    reconstruct digest OR compare declared digest
    compare sink_id and generations
    CAS consume-row[handle_id]
    commit local effect

SINGLE_USE is required only where a second effect of the same act is the failure mode (payment post, coil write, weight release). COUNTED and ENVELOPE exist so that high-QPS low-consequence calls are not forced through one-shot consume. A profile that puts SINGLE_USE on every MCP list_files call has mis-applied the registry, not discovered a protocol bug.

Rails that already authorize-then-capture, or that already keep an idempotency key per instruction id, already pay this tax under another name. The draft asks that the key be bound to the reconstructed act digest and to the sink, not that a new consensus cluster be inserted in front of every gateway.

27.3. Objection: Sink Reconstruction Is Too Hard in a Mesh

Independently rebuilding a canonical CAD from "what the sink is about to do" is difficult when the pending effect is scattered across headers, body fields, side channels, and defaulted microservice context. That difficulty is real. It is also the reason substitution works.

This document does not require every mesh hop to become a Finality Sink. Reconstruction is required only at the component that would first make the external effect real. Intermediate proxies MAY forward the handle. They MUST NOT be treated as having consumed it.

A profile MAY define a closed field set and a deterministic canonicalization for that sink class (amount, currency, beneficiary, rail; or tool name plus named arguments). It MUST list those fields. A sink that cannot reconstruct a field MUST treat the field as digest-covered only if it can observe it. Hidden context that can change the effect and is omitted from the digest is an incomplete CAD (Section 32.1), not a reason to trust the caller-supplied blob.

Allowed:
    sink observes live post fields
    builds CAD_live
    compares digest(CAD_live) to EH.act_digest

Allowed with documented residual:
    sink accepts caller CAD
    plus proof that CAD equals live fields
    it actually observes

Forbidden in strict profile:
    sink trusts caller digest
    and never looks at the live effect

If a sink class cannot observe enough of the live effect to build a meaningful digest, that sink class cannot claim exact-act prevention. It can still authenticate the caller. Those are different claims.

27.4. What Would Falsify or Fast-Track the Objection

The fastest honest test is a small sink middleware — for example an MCP server wrapper or a payment-post adapter — that issues a handle for a reconstructed tool call or payout and refuses a mutated argument, a replay, or a prompt-injected destination. If that wrapper cannot be written without a global lock, the performance objection stands. If it can, the object is implementable.

This document does not ship that code. An implementation that does is invited and would be more useful to a working group than a further architectural draft.

28. Required Classes of Test Vectors

A concrete profile or implementation SHOULD test at least:

29. Questions to the IETF Community

Criticism, corrections, counterexamples, operational experience, prior art, and evidence that existing standards already provide the full property are explicitly invited. Recommendations to narrow, merge, or stop the work are useful outcomes.

  1. Is a distinct Execution Handle object useful, or should these semantics be profiled onto existing OAuth tokens, CWTs, or WIMSE credentials?
  2. Which CAD fields are universal, and which must remain profile extensions?
  3. Should canonicalization be JCS, deterministic CBOR, HTTP Message Signature component names, or profile-declared?
  4. Is SINGLE_USE the default reuse policy for high-consequence classes?
  5. How should envelope reuse be bounded so it cannot become a second bearer scope?
  6. Must the sink reconstruct arguments from the live effect, or may it accept a caller CAD plus proof?
  7. What consume-state store is realistic at payment, OT, and tool-dispatch latency?
  8. Should Finality Receipts be SCITT statements, COSE_Sign1, or both?
  9. How should handles travel across WIMSE multi-hop chains without becoming portable bearer authority?
  10. Is an HTTP header binding worth standardizing, or only an abstract verify/consume API?
  11. Which existing token confirmation methods (DPoP, TLS-bound, WIMSE) should be optional EH key-binding methods?
  12. What privacy risk does an Act Digest create if arguments are low-entropy?
  13. What counterexample shows that DPoP plus RAR plus HTTP signatures already close this gap?
  14. Which venue is best for further discussion: OAuth, WIMSE, RATS, SCITT, HTTPAPI, DISPATCH, or SAAG?
  15. Does a documented saga or 2PC plus DPoP/RAR already reconstruct the live act and consume single-use authority at the actual sink?
  16. Can consume-state be a per-handle compare-and-swap row, or do reviewers still require a different reuse default for high-QPS sinks?
  17. For which sink classes is live reconstruction infeasible, and should those classes be excluded from the strict profile rather than allowed to trust the caller CAD?

30. Potential IETF Discussion Venues

This document does not claim that any named group should adopt the work. The mapping below is overlap review, not a presumed home.

30.1. OAuth

Relevant if the handle is profiled as a constrained token type using RAR data at issuance. OAuth should not be asked to own actuation, RF, or composite join.

30.2. WIMSE

Relevant to workload identity inside CAD.actor and multi-hop presentation. WIMSE identity is not exact-act authority.

30.3. RATS

Relevant when an Attestation Result is a PED input. RATS should not own consume-state.

30.4. SCITT

Relevant to logging Finality Receipts and policy hashes. A SCITT receipt is not a permit to effectuate.

30.5. HTTPAPI

Relevant if an HTTP verify/consume binding or problem+json mapping is standardized later.

30.6. DISPATCH

Natural first stop because the object spans token, HTTP, and non-HTTP sinks.

30.7. SAAG

Useful for Security Area review of whether a new effectuation object is justified. SAAG does not adopt documents.

30.8. No Presumed Home

Individual submission. Venue choice is an open community question.

32. Security Considerations

A handle-prevention claim is only as strong as CAD completeness, sink reconstruction, consume-state integrity, and path coverage.

32.1. Incomplete CAD

If a load-bearing field is omitted from the Act Digest, substitution of that field will not be detected. Profiles MUST list digest-covered fields.

32.2. Caller-Supplied Digest

Accepting a caller digest without reconstruction lets the caller bind a handle to a different live operation. Sinks SHOULD reconstruct.

32.3. Bearer Degradation

If a deployment treats handle possession as sufficient, the object becomes an access token under another name. The strict profile forbids that degradation.

32.4. Consume-Store Integrity

An attacker who can reset consume-state can replay SINGLE_USE handles. The store is part of the trusted computing base for prevention claims.

32.5. Alternate Path

Raw credentials, admin consoles, replicas, and debug ports can negate handle enforcement. Prevention requires equivalent mediation of every path to K.

32.6. Low-Entropy Arguments

Digests of small argument sets can enable dictionary confirmation of sensitive destinations. Profiles SHOULD salt or include high-entropy instance identifiers in the digested CAD.

32.7. Handle Correlation

Stable handle_id and candidate_act_id values can correlate activity across hops. Short-lived identifiers and sink-local verification reduce exposure.

32.8. Issuer Compromise

A compromised PED can issue handles for unauthorized acts. This draft does not solve issuer honesty. Separation of PED and sink, attestation of PED, and dual control are deployment mitigations.

33. Privacy Considerations

CADs and receipts can reveal tool choice, destination, amount class, jurisdiction, and workload identity. Implementations SHOULD hash raw arguments on untrusted paths, emit the minimum receipt fields needed for the relying party, and avoid logging full tool arguments when the digest suffices.

34. IANA Considerations

This version requests no IANA actions. A companion registries draft is expected to request media types, error codes, consequence classes, sink types, and claim names if the community wants a shared namespace. Codes in Section 19 are illustrative only.

35. Criticism, Corrections, and Review Invited

This document is presented for adversarial review. Particularly useful feedback is a concrete protocol already requiring exact-act reconstruction, sink binding, and atomic consume before consequence. Such evidence should reduce the scope of this proposal.

Equally useful is correction of Section 25. If a public Microsoft, OpenAI, Anthropic, Google, AWS, NVIDIA, Arm, Cloudflare, PSP, or foundation mechanism already implements the handle invariant, or if this draft mis-describes a published roadmap, the text should be amended or the industrial example removed. Named parties are not expected to respond; a response is a courtesy, not an obligation, and neither response nor silence is an endorsement.

36. Conclusion

Identity, sender constraint, attestation, and signed statements solve indispensable parts of machine authorization. The narrow question addressed here is whether the object presented at the effectuation boundary still corresponds to the live pending operation, at the intended sink, under current generations, and under a consume rule that makes replay a protocol failure.

POSSESSION
      !=
AUTHORITY TO EFFECTUATE

Valid for C17 at S17
      !=
Valid for C18, or at S18, or a second time

For strict handle finality:

Corresponds(H, C_now, S_now) AND ConsumeOK(H)
        OR
Candidate remains non-effective.

37. Normative References

[RFC2119]
Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, , <https://www.rfc-editor.org/rfc/rfc2119>.
[RFC8174]
Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, , <https://www.rfc-editor.org/rfc/rfc8174>.

38. Informative References

[AAIF-MCP]
Linux Foundation, "Linux Foundation Announces the Formation of the Agentic AI Foundation", , <https://www.linuxfoundation.org/press/linux-foundation-announces-the-formation-of-the-agentic-ai-foundation>.
[ARM-CCA]
Arm, "Arm Confidential Compute Architecture", , <https://www.arm.com/architecture/security-features/arm-confidential-compute-architecture>.
[AWS-ESC]
Amazon Web Services, "Opening the AWS European Sovereign Cloud", , <https://aws.amazon.com/blogs/aws/opening-the-aws-european-sovereign-cloud/>.
[DAS-AGENTIC]
Das, S., "Tool Selection Is Not Execution: Finality for Agentic Tool Dispatch in High-Risk AI Systems", Work in Progress, Internet-Draft, draft-das-agentic-execution-finality-02, , <https://datatracker.ietf.org/doc/draft-das-agentic-execution-finality/>.
[DAS-COMPOSITE]
Das, S., "Partial Commit Is Not Finality: Composite Candidate Acts Across Multiple Finality Sinks", Work in Progress, Internet-Draft, draft-das-composite-execution-finality-01, , <https://datatracker.ietf.org/doc/html/draft-das-composite-execution-finality-01>.
[DAS-JURISDICTION]
Das, S., "Authorized Here, Not Authorized There: Jurisdiction-Bound Execution Finality for Cross-Border and Sovereign Systems", Work in Progress, Internet-Draft, draft-das-jurisdiction-bound-execution-finality-00, , <https://datatracker.ietf.org/doc/html/draft-das-jurisdiction-bound-execution-finality-00>.
[DAS-PATH]
Das, S., "When the Gate Can Be Bypassed: Consequence-Path Completeness for Execution Finality", Work in Progress, Internet-Draft, draft-das-consequence-path-completeness, , <https://datatracker.ietf.org/doc/draft-das-consequence-path-completeness/>.
[DAS-PROTOCOL]
Das, S., "The Missing Protocol Layer for the Agentic Internet: Computation Is Not Authority", Work in Progress, Internet-Draft, draft-das-execution-finality-protocol-layer-01, , <https://datatracker.ietf.org/doc/draft-das-execution-finality-protocol-layer/>.
[DAS-PURPOSE]
Das, S., "Data-Purpose Laundering Prevention: Execution-Finality for Preventing Cross-Domain Data Reuse", Work in Progress, Internet-Draft, draft-das-purpose-execution-finality-03, , <https://datatracker.ietf.org/doc/draft-das-purpose-execution-finality/>.
[DAS-RATS]
Das, S., "Attestation-Bound Execution Finality for GPU, AI Accelerator, DPU, SmartNIC, and Confidential-Computing Infrastructure", Work in Progress, Internet-Draft, draft-das-rats-attestation-bnd-execution-finality-04, , <https://datatracker.ietf.org/doc/draft-das-rats-attestation-bnd-execution-finality/>.
[DAS-REG]
Das, S., "Illustrative Codes Are Not a Namespace: Registries for Execution-Finality Objects", Work in Progress, Internet-Draft, draft-das-ef-registries-01, , <https://datatracker.ietf.org/doc/html/draft-das-ef-registries-01>.
[DAS-REVOCATION]
Das, S., "Revoked but Still Executable: Closing the Authorization-to-Effect Gap with Finality-Bound Revocation", Work in Progress, Internet-Draft, draft-das-finality-bound-revocation-00, , <https://datatracker.ietf.org/doc/html/draft-das-finality-bound-revocation-00>.
[DAS-STATE]
Das, S., "When Valid Authorization Becomes Stale: State and Policy Continuity at the Execution-Finality Boundary", Work in Progress, Internet-Draft, draft-das-state-policy-continuity-finality-00, , <https://datatracker.ietf.org/doc/html/draft-das-state-policy-continuity-finality-00>.
[DAS-TOOL]
Das, S., "tool_use Is Not invoke(): Binding Execution-Finality to Agentic Tool-Call Interfaces and MCP", Work in Progress, Internet-Draft, draft-das-agentic-tool-binding-03, , <https://datatracker.ietf.org/doc/draft-das-agentic-tool-binding/>.
[GOOGLE-SOV]
Google Cloud, "Sovereign Controls by Partners", , <https://cloud.google.com/security/products/sovereign-controls-by-partners>.
[MCP-SPEC]
Model Context Protocol, "Model Context Protocol Specification", , <https://modelcontextprotocol.io/specification>.
[MS-EUDB]
Microsoft, "Customer data storage and processing for European customers in Microsoft Entra ID", , <https://learn.microsoft.com/en-us/entra/fundamentals/data-storage-eu>.
[MS-EUDB-TRANSFERS]
Microsoft, "Continuing data transfers that apply to all EU Data Boundary Services", , <https://learn.microsoft.com/en-us/privacy/eudb/eu-data-boundary-transfers-for-all-services>.
[MS-MCP-GA]
Microsoft, "Model Context Protocol (MCP) is now generally available in Microsoft Copilot Studio", , <https://www.microsoft.com/en-us/microsoft-copilot/blog/copilot-studio/model-context-protocol-mcp-is-now-generally-available-in-microsoft-copilot-studio/>.
[MS-MCP-LEARN]
Microsoft, "Extend your agent with Model Context Protocol", , <https://learn.microsoft.com/en-us/microsoft-copilot-studio/agent-extend-action-mcp>.
[NVIDIA-ATTEST]
NVIDIA, "NVIDIA Attestation SDK — GPU and Switch Attestation", , <https://docs.nvidia.com/attestation/attestation-client-tools-sdk/latest/gpu_and_switch_attestation.html>.
[RFC6234]
IETF, "US Secure Hash Algorithms (SHA and SHA-based HMAC and HKDF)", RFC 6234, , <https://www.rfc-editor.org/rfc/rfc6234>.
[RFC6749]
IETF, "The OAuth 2.0 Authorization Framework", RFC 6749, , <https://www.rfc-editor.org/rfc/rfc6749>.
[RFC7519]
IETF, "JSON Web Token (JWT)", RFC 7519, , <https://www.rfc-editor.org/rfc/rfc7519>.
[RFC8392]
IETF, "CBOR Web Token (CWT)", RFC 8392, , <https://www.rfc-editor.org/rfc/rfc8392>.
[RFC8705]
IETF, "OAuth 2.0 Mutual-TLS Client Authentication and Certificate-Bound Access Tokens", RFC 8705, , <https://www.rfc-editor.org/rfc/rfc8705>.
[RFC8785]
IETF, "JSON Canonicalization Scheme (JCS)", RFC 8785, , <https://www.rfc-editor.org/rfc/rfc8785>.
[RFC8949]
IETF, "Concise Binary Object Representation (CBOR)", RFC 8949, , <https://www.rfc-editor.org/rfc/rfc8949>.
[RFC9334]
IETF, "Remote ATtestation procedureS (RATS) Architecture", RFC 9334, , <https://www.rfc-editor.org/rfc/rfc9334>.
[RFC9396]
IETF, "OAuth 2.0 Rich Authorization Requests", RFC 9396, , <https://www.rfc-editor.org/rfc/rfc9396>.
[RFC9421]
IETF, "HTTP Message Signatures", RFC 9421, , <https://www.rfc-editor.org/rfc/rfc9421>.
[RFC9449]
IETF, "OAuth 2.0 Demonstrating Proof of Possession (DPoP)", RFC 9449, , <https://www.rfc-editor.org/rfc/rfc9449>.
[RFC9943]
IETF, "An Architecture for Trustworthy and Transparent Digital Supply Chains", RFC 9943, , <https://www.rfc-editor.org/rfc/rfc9943>.
[WIMSE-ARCH]
IETF WIMSE Working Group, "Workload Identity in a Multi System Environment (WIMSE) Architecture", Work in Progress, Internet-Draft, draft-ietf-wimse-arch-08, , <https://datatracker.ietf.org/doc/draft-ietf-wimse-arch/>.

Author's Address

Sangam Das
Independent
Balasore
Odisha
India