Authorization Receipts for High-Risk Agent Actions
draft-schrock-ep-authorization-receipts-11
This document is an Internet-Draft (I-D).
Anyone may submit an I-D to the IETF.
This I-D is not endorsed by the IETF and has no formal standing in the
IETF standards process.
| Document | Type | Active Internet-Draft (individual) | |
|---|---|---|---|
| Author | Iman Schrock | ||
| Last updated | 2026-08-09 | ||
| RFC stream | (None) | ||
| Intended RFC status | (None) | ||
| Formats | |||
| Additional resources |
GitHub Repository
Additional Web Page |
||
| Stream | Stream state | (No stream defined) | |
| Consensus boilerplate | Unknown | ||
| RFC Editor Note | (None) | ||
| IESG | IESG state | I-D Exists | |
| Telechat date | (None) | ||
| Responsible AD | (None) | ||
| Send notices to | (None) |
draft-schrock-ep-authorization-receipts-11
Network Working Group I. Schrock
Internet-Draft EMILIA Protocol, Inc.
Intended status: Standards Track 9 August 2026
Expires: 10 February 2027
Authorization Receipts for High-Risk Agent Actions
draft-schrock-ep-authorization-receipts-11
Abstract
This document defines the EMILIA Protocol (EP) authorization receipt,
an evidence artifact binding an enrolled approver key to one
canonical action before execution. An approver-held key signs an
Authorization Context containing the action hash, policy reference,
shared authorization instance, per-signoff nonce, audience, and
validity window. A Trust Receipt carries the signed contexts,
terminal consumption record, and Merkle inclusion material so a
relying party can verify the recorded event offline under
independently selected log, directory, policy, and approver trust
inputs.
The receipt establishes only the guarantees of the selected
verification profile. The mapping from an enrolled approver
identifier to a natural person is asserted by the directory
authority. Offline verification does not establish current
revocation status, global non-replay, comprehension, legality,
safety, or execution. Replay prevention requires an online atomic
consumption store at the executor. The state-machine invariants are
machine-checked under the assumptions stated in this document.
This revision defines the closed EP-AUTHORIZATION-BUNDLE-v1 pre-
execution profile and its verification algorithm. The bundle carries
the Action Object, signed Authorization Contexts, signoffs, key
proofs, and presentation evidence; it deliberately carries no
terminal consumption or execution claim. An optional, profile-
identified authorization binding can commit the human evidence to an
independently verified native authorization artifact without
replacing that artifact or making this receipt format depend on its
transport or trust model.
Schrock Expires 10 February 2027 [Page 1]
Internet-Draft EP Authorization Receipts August 2026
A receipt is evidence, not authorization. This document does not
treat a local user interaction as an authorization decision. It
defines one evidence artifact that an authorization architecture can
use in a human-confirmation flow: the signed Authorization Context is
action-bound confirmation evidence an authorization server MAY
validate and bind to the grant it issues. The resulting Trust
Receipt records terminal consumption and remains evidence; neither
object makes the authorization decision. That decision remains with
the authorization server.
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 10 February 2027.
Copyright Notice
Copyright (c) 2026 IETF Trust and the persons identified as the
document authors. All rights reserved.
This document is subject to BCP 78 and the IETF Trust's Legal
Provisions Relating to IETF Documents (https://trustee.ietf.org/
license-info) in effect on the date of publication of this document.
Please review these documents carefully, as they describe your rights
and restrictions with respect to this document. Code Components
extracted from this document must include Revised BSD License text as
described in Section 4.e of the Trust Legal Provisions and are
provided without warranty as described in the Revised BSD License.
Table of Contents
1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 4
1.1. Design Goals . . . . . . . . . . . . . . . . . . . . . . 6
1.2. Scope of Identity . . . . . . . . . . . . . . . . . . . . 6
2. Terminology . . . . . . . . . . . . . . . . . . . . . . . . . 7
3. The Action Object and Action Hash . . . . . . . . . . . . . . 8
Schrock Expires 10 February 2027 [Page 2]
Internet-Draft EP Authorization Receipts August 2026
4. The Authorization Context . . . . . . . . . . . . . . . . . . 9
4.1. Presentation Binding (OPTIONAL, Policy-Required) . . . . 10
4.2. Initiator Attestation (OPTIONAL) . . . . . . . . . . . . 11
4.3. Agent Binding (OPTIONAL) . . . . . . . . . . . . . . . . 14
5. Approver Keys and the Signoff Signature . . . . . . . . . . . 18
5.1. Key Classes . . . . . . . . . . . . . . . . . . . . . . . 18
5.2. Enrollment and the Approver Directory . . . . . . . . . . 18
5.3. The Signoff . . . . . . . . . . . . . . . . . . . . . . . 19
6. Pre-Execution Authorization Bundle . . . . . . . . . . . . . 20
6.1. Optional Native Authorization Binding . . . . . . . . . . 21
6.2. Pre-Execution Verification Algorithm . . . . . . . . . . 21
6.3. Required Hostile Conformance Cases . . . . . . . . . . . 23
7. Consumption, Commitment, and the Trust Receipt . . . . . . . 24
7.1. State Machine . . . . . . . . . . . . . . . . . . . . . . 24
7.2. The Trust Receipt . . . . . . . . . . . . . . . . . . . . 25
7.3. Offline Verification Algorithm . . . . . . . . . . . . . 26
8. Companion Receipt Extensions and Digest Binding . . . . . . . 27
8.1. Provisional Extension Registry . . . . . . . . . . . . . 29
8.2. Relationship to the Action Lifecycle . . . . . . . . . . 30
9. Multi-Approver Policies (m-of-n) . . . . . . . . . . . . . . 30
10. Delegation Constraints . . . . . . . . . . . . . . . . . . . 30
11. Conformance Classes and Execution-Side Enforcement . . . . . 31
12. Relationship to Other Work . . . . . . . . . . . . . . . . . 31
13. Security Considerations . . . . . . . . . . . . . . . . . . . 34
13.1. Operator Compromise . . . . . . . . . . . . . . . . . . 34
13.2. Approver Device Compromise . . . . . . . . . . . . . . . 34
13.3. Presentation Attacks . . . . . . . . . . . . . . . . . . 35
13.4. Log Equivocation . . . . . . . . . . . . . . . . . . . . 35
13.5. What the Formal Models Do and Do Not Prove . . . . . . . 36
13.6. Directory Authority . . . . . . . . . . . . . . . . . . 37
13.7. What Separation of Duties Does and Does Not Provide . . 38
13.8. Approver Fatigue . . . . . . . . . . . . . . . . . . . . 38
13.9. Initiator Attestation as an Attack Surface . . . . . . . 38
13.10. No symmetric key on the verification trust path . . . . 39
13.11. Canonicalization Robustness . . . . . . . . . . . . . . 40
14. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 40
15. References . . . . . . . . . . . . . . . . . . . . . . . . . 42
15.1. Normative References . . . . . . . . . . . . . . . . . . 42
15.2. Informative References . . . . . . . . . . . . . . . . . 43
Appendix A. Acknowledgments . . . . . . . . . . . . . . . . . . 45
Appendix B. Changes since -10 . . . . . . . . . . . . . . . . . 45
Appendix C. Changes since -09 . . . . . . . . . . . . . . . . . 46
Appendix D. Changes since -08 . . . . . . . . . . . . . . . . . 46
Appendix E. Changes since -07 . . . . . . . . . . . . . . . . . 47
Appendix F. Changes since -06 . . . . . . . . . . . . . . . . . 47
Appendix G. Changes since -04 . . . . . . . . . . . . . . . . . 48
Appendix H. Changes since -00 (through -04) . . . . . . . . . . 48
Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 49
Schrock Expires 10 February 2027 [Page 3]
Internet-Draft EP Authorization Receipts August 2026
1. Introduction
Agentic AI systems increasingly hold credentials sufficient to
perform irreversible operations: releasing payments, modifying
beneficiary records, rotating production credentials, deleting data.
Session-level authentication and authorization alone answer whether
an actor may operate within a scope. A deployment can separately
require evidence that an enrolled approver key signed one exact
proposed action before execution.
Three structural gaps follow:
1. *The action gap.* Identity and access management authorizes
_sessions and scopes_, not individual actions. Fraud that occurs
inside a valid session through approved channels (e.g., business
email compromise leading to a beneficiary change) is invisible to
session-level controls.
2. *The accountability gap.* Where human approval exists, it is
typically a click in a workflow tool, recorded in a mutable
application database controlled by the operator of the approval
system. A deployment can instead require portable evidence
binding an enrolled approver key to the specific action.
3. *The verification gap.* Auditors, counterparties, and regulators
may need to evaluate evidence outside the operator that produced
it, including after the live service is unavailable or the
operators disagree.
This document addresses those deployment requirements with a receipt
profile: before an irreversible action executes, an enrolled approver
signs the exact action with an approver-held key; an executor records
terminal consumption through an atomic state transition; and the
resulting receipt remains independently verifiable offline for as
long as its algorithms and trust material remain acceptable or are
renewed.
Adjacent mechanisms answer related but non-identical questions. The
distinctions below are profile boundaries, not claims that portable
approval or intent evidence exists nowhere else.
* OAuth 2.0 with Rich Authorization Requests [RFC9396] and GNAP (RFC
9635) authorize a client's _requested scope_; they do not produce
a named human's offline-verifiable signature over the exact action
that executed.
Schrock Expires 10 February 2027 [Page 4]
Internet-Draft EP Authorization Receipts August 2026
* The OAuth Step-Up Authentication Challenge (RFC 9470) can _demand_
fresh human authentication for a sensitive operation, but yields
no durable, portable artifact of that approval.
* Transaction Tokens (draft-ietf-oauth-transaction-tokens) propagate
call context across workloads within a trust domain; they are
short-lived, online-validated, and assert _workload_ identity, not
a human's authorization of an action.
* The Security Event Token (RFC 8417) and CAEP convey, as issuer
assertions, that an event _occurred_; they are not a human's pre-
execution approval bound to one exact action.
* RATS (RFC 9334) and the Entity Attestation Token (RFC 9711) attest
the trustworthiness of a _platform or workload_, not that a named
human authorized an action -- a different trust root.
* SCITT (RFC 9943) provides an append-only transparency log and
inclusion receipts, but is deliberately agnostic about the
application semantics and authority behind a statement. An EP
receipt can be carried as one such application statement.
* The agent-action evidence work now emerging around that
architecture -- per-action receipt envelopes, action capsules,
post-execution profiles, pre-execution permits, and refusal events
-- makes agent actions transparent, logged, and policy-checked.
Some define approval or intent evidence with different ceremony,
identity, freshness, or consumption guarantees.
The use case for this receipt is narrower than agent logging in
general: a relying party needs an action-bound approval event under a
named verification profile, portable outside the operator, agent
runtime, and transparency service. EP is one such artifact and is
not a replacement for any of the above: it composes with them
(Section 12) and can be carried in their formats -- for example, an
EP receipt expressed as a COSE Signed Statement and logged by a SCITT
Transparency Service, or referenced by digest from an action receipt,
capsule, or permit.
The human-approval mechanism this document specifies -- a user-
verification-gated signature over the exact Authorization Context
(Section 5.1, Class A) -- is native to EP and self-contained. It
does not depend on, and is not a profile of, any other draft's
acquiescence, consent, or confirmation mechanism; a conforming EP
signoff is produced entirely by the controls defined here. Where EP
composes with adjacent work (Section 12), that composition is by
reference, not dependency.
Schrock Expires 10 February 2027 [Page 5]
Internet-Draft EP Authorization Receipts August 2026
1.1. Design Goals
* *G1 -- Action binding.* An approval is cryptographically bound to
one exact action. It cannot authorize anything else.
* *G2 -- Approver-held keys.* The approver's signature is produced
by a key the EP operator does not possess. The operator
orchestrates; it cannot forge.
* *G3 -- One-time consumption.* An authorization reaches a terminal
state at most once within the executor's shared atomic consumption
domain. Replay presented to that domain MUST be rejected. An
offline receipt alone cannot prove that no independent executor
consumed the same authorization.
* *G4 -- Separation of duties.* The initiator of an action MUST NOT
be an approver of that action. Policies MAY require m-of-n
distinct approvers.
* *G5 -- Offline verifiability.* A receipt is verifiable with no
network access, using only the receipt, the approver's public key
material, and a published log checkpoint. Offline verification
establishes authenticity and log inclusion as of commit time, not
current revocation status (Section 7.3).
* *G6 -- Execution-side enforcement.* The strongest deployment
places verification at the system of record: the executing service
verifies the receipt before performing the action. Middleware-
only deployments are explicitly defined as a weaker conformance
class (Section 11).
* *G7 -- Machine-checked safety.* The protocol state machine's
safety properties are maintained as formal models (TLA+, Alloy,
and Tamarin) and checked in continuous integration.
Implementations can be tested against a published conformance
suite.
1.2. Scope of Identity
This document binds an approval to an _approver identifier_ whose key
is enrolled in the Approver Directory (Section 5.2); it does not, by
itself, prove that the holder of that identifier is a particular
natural person. Proof of a specific real-world identity -- that
ep:approver:jchen-controller is the human Jordan Chen -- is out of
scope. The Approver Directory trust root (Section 5.2) is the
explicit slot where an identity-proofing or key-discovery layer binds
keys to named persons; the strength of any such binding is a property
of that layer, not of the receipt format. A receipt proves that a
Schrock Expires 10 February 2027 [Page 6]
Internet-Draft EP Authorization Receipts August 2026
key enrolled under a given approver identifier signed the exact
action; the mapping from identifier to person is established and
asserted by the directory authority.
2. Terminology
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, as shown here.
*Initiator.* The entity (typically an AI agent or automated process)
that proposes a high-risk action. The initiator is identified but
never trusted with approval authority over its own actions.
*Approver.* A named human (or, for lower assurance classes, an
organizational role occupied by a named human at decision time) who
holds approval authority under policy. The approver controls a
private signing key; see Section 5.
*Action.* A single proposed operation with concrete parameters (e.g.,
one wire transfer to one beneficiary for one amount). Actions are
represented by an Action Object and identified by their action hash
(Section 3).
*Policy.* A named, versioned rule set determining, for a class of
actions, which approvers are required (including m-of-n thresholds),
validity windows, and amount or scope limits.
*Authorization Context.* The canonical structure an approver signs:
action hash, policy reference, initiator identity, relying-party
audience, nonce, expiry, and chain binding (Section 4).
*Authorization Bundle.* The closed pre-execution artifact containing
one Action Object, its signed Authorization Contexts, signoffs, key
proofs, and any presentation evidence. A valid bundle is approval
evidence; it is not an authorization grant, policy decision,
reservation, consumption record, or execution receipt (Section 6).
*Initiator Attestation.* An OPTIONAL claim by the initiator, carried
inside the Authorization Context, stating why the initiator escalated
the action to a human (Section 4.2). It is a claim, not proof of the
initiator's internal state.
*Trust Receipt.* The terminal artifact: the Action Object digest, all
approver signatures, the consumption record, and a Merkle inclusion
proof against a signed log checkpoint (Section 7).
Schrock Expires 10 February 2027 [Page 7]
Internet-Draft EP Authorization Receipts August 2026
*Verifying Executor.* A system of record that verifies a Trust
Receipt (or a pre-execution Authorization Bundle) before performing
the action. See Section 11.
*EP Operator.* The party running the orchestration service (policy
registry, signoff routing, log). Under this protocol the operator is
_not_ in the signing trust path for approvals (G2).
3. The Action Object and Action Hash
An Action Object is a JSON document with at minimum:
{
"ep_version": "1.0",
"action_type": "wire.release",
"target": { "system": "treasury.example",
"resource": "wire/8841" },
"parameters": { "amount": "2400000.00", "currency": "USD",
"beneficiary_account_hash": "sha256:..." },
"initiator": "ep:entity:agent-recon-7",
"policy_id": "ep:policy:wires-over-100k@v12",
"requested_at": "2026-06-09T17:21:04Z"
}
The Action Object MUST be serialized using JSON Canonicalization
Scheme (JCS) [RFC8785]. The *action hash* is the SHA-256 digest of
the canonical serialization. Implementations MUST reject approval
requests whose action hash does not match a locally recomputed hash
of the presented Action Object. Sensitive parameter values MAY be
carried as salted hashes (as beneficiary_account_hash above) provided
the executing system can recompute them; the binding property is
preserved because the hash commits to the committed values.
The action hash is this receipt format's native integrity identifier.
It is not assumed to equal an action digest from a different
protocol. When a relying party compares this receipt's action with
an action named by another artifact, it MUST project the natively
verified Action Object under CAID [EP-CAID] using an exact mapping
profile pinned by that relying party. Such mapping occurs only after
receipt verification and does not change this document's signature
input. A missing, failed, lossy, or unpinned mapping is
indeterminate and MUST NOT be treated as an action match. A relying
party that does not perform cross-artifact action comparison need not
derive a CAID.
Schrock Expires 10 February 2027 [Page 8]
Internet-Draft EP Authorization Receipts August 2026
4. The Authorization Context
For each required approver, the orchestrator constructs an
Authorization Context:
{
"ep_version": "1.0",
"context_type": "ep.signoff.v1",
"action_hash": "sha256:9f2c...",
"policy_id": "ep:policy:wires-over-100k@v12",
"policy_hash": "sha256:77ab...",
"initiator": "ep:entity:agent-recon-7",
"authorization_instance": "b64u:Q0ND...",
"audience": "https://payments.example.com",
"approver": "ep:approver:jchen-controller",
"approver_index": 1,
"required_approvals": 2,
"nonce": "b64u:R9w1...",
"issued_at": "2026-06-09T17:21:05Z",
"expires_at": "2026-06-09T17:36:05Z",
"display_hash": "sha256:4a8e...",
"prev_receipt_hash": "sha256:51d0..."
}
Rules:
* authorization_instance MUST be present in every Authorization
Context carried by an EP-AUTHORIZATION-BUNDLE-v1 object. It MUST
contain at least 128 bits of CSPRNG output, MUST be freshly issued
and durably registered for each authorization attempt by the
relying party, authorization server, or another component the
relying party independently trusts for this purpose. The
orchestrator or presenter MUST NOT select it. It MUST be byte-
identical in every context for that attempt. Because it is inside
each signed context, it prevents valid signoffs from separate
approval ceremonies from being spliced into one quorum. Older
Trust Receipts that do not use the new Bundle profile remain valid
under their existing profile and need not contain this member.
* nonce MUST be at least 128 bits of CSPRNG output and MUST be
unique for each approver context within the issuer and
authorization domain. It is the per-signoff replay and freshness
unit, and is the receipt's freshness mechanism in the sense of the
Entity Attestation Token (RFC 9711): a verifier-relevant nonce,
here held to a 128-bit floor (twice the EAT minimum). EP does not
treat a timestamp alone as freshness; absolute time, where a
relying party requires it, is asserted by an independent authority
rather than by the operator.
Schrock Expires 10 February 2027 [Page 9]
Internet-Draft EP Authorization Receipts August 2026
* policy_hash commits to the exact policy version evaluated. A
signature over a context with policy_hash X MUST NOT satisfy a
requirement evaluated under policy_hash Y, even for the same
policy_id.
* audience identifies the relying party or protected resource
expected to evaluate this evidence for the action. It MUST be a
non-empty absolute URI. A verifier MUST compare it to its
independently configured identifier and MUST NOT accept a value
selected only by the presenter. This member corrects the -10
abstract, which named an audience that the -10 Authorization
Context example did not carry.
* prev_receipt_hash chains this authorization to the issuing log's
most recent receipt, contributing to tamper evidence.
* The context is JCS-canonicalized; the *context hash* is its
SHA-256 digest. The approver signs the context hash.
* A conforming signing client MUST render a human-readable
presentation from the exact Action Object covered by action_hash,
not from a separately supplied description. This is a signing-
client behavior requirement. Base receipt verification alone does
not prove that a faithful rendering reached a human. A relying
party that requires verifiable presentation evidence MUST apply
the profile below.
4.1. Presentation Binding (OPTIONAL, Policy-Required)
EP-PRESENTATION-BINDING-v1 is an optional verification profile over a
natively verified receipt and one presentation-evidence artifact. It
standardizes existing EP display_hash and EP-DISPLAY-ATTESTATION-v1
mechanisms; it does not add a third, profileless disclosure digest to
the base receipt.
A producer MAY include display_hash in an ep.signoff.v1 Authorization
Context. When present, it MUST use the lowercase sha256:<64-
lowercase-hex> form and MUST be the SHA-256 digest defined by the
selected presentation-evidence profile. Because the complete context
is JCS-canonicalized before the approver signs its hash, display_hash
is covered by the approver's signature. The evidence artifact itself
is carried with the verification input or by a digest-bound
companion; it is not inserted as a new member of the closed base
Trust Receipt.
A relying party selects the acceptable presentation profile and its
trust inputs independently of the presenter. This revision defines
three composition cases:
Schrock Expires 10 February 2027 [Page 10]
Internet-Draft EP Authorization Receipts August 2026
* EP-MOBILE-PRESENTATION-v1: recompute SHA-256 over the JCS form of
the closed mobile presentation object and require equality with
display_hash in the already verified Authorization Context.
* EP-DISPLAY-ATTESTATION-v1: re-derive the deterministic rendering
from the exact Action Object, require both action and display
digests to match, and verify the detached proof under a signing-
client key pinned by the relying party. A key carried only by the
producer is not a trust input.
* An OASNT dsp claim [I-D.thallapelly-oasnt]: first perform OASNT
native verification, require its action to match this receipt
under the relying-party-pinned CAID mapping, then recompute dsp
over the exact canonical-display UTF-8 octets. Native
verification is not replaced by an EP digest comparison.
A verifier applying this profile MUST return one of the following
stable refusal reasons before the evidence can satisfy a presentation
requirement:
* display-unbound: policy requires presentation binding and no
accepted presentation-evidence artifact is present;
* display-mismatch: the profile-defined display digest or action
binding differs from the independently recomputed value; or
* display-untrusted: the artifact is unknown, malformed, not
natively verified, or verified only under a key or trust input not
pinned by the relying party.
A successful result establishes only that trusted evidence binds
profile-defined disclosure bytes to the exact action. It does not
prove the human comprehended or legally consented to the action, that
the claimed bytes became physical pixels, or that the operating
system, display path, or signing client was uncompromised. A relying
party that requires those stronger properties needs a separately
graded trusted display path.
4.2. Initiator Attestation (OPTIONAL)
A producer MAY include an initiator_attestation member in any
ep.signoff.v1 Authorization Context. The member carries the
initiator's own stated reason for escalating the action to a human.
When present it MUST be a JSON object with the following members and
no others:
Schrock Expires 10 February 2027 [Page 11]
Internet-Draft EP Authorization Receipts August 2026
+==================+==================+======+=====================+
|Field |Required |Type |Description |
+==================+==================+======+=====================+
|escalation_trigger|REQUIRED |string|Why the initiator |
| | |(enum)|escalated. Exactly |
| | | |one of: |
| | | |irreversibility, |
| | | |magnitude, |
| | | |uncertainty, novelty,|
| | | |authority_gap, |
| | | |policy_rule. |
+------------------+------------------+------+---------------------+
|policy_basis |OPTIONAL (REQUIRED|string|Identifier of the |
| |whenever a | |policy or rule that |
| |deterministic | |fired, e.g. |
| |policy rule fired,| |ep:policy:wires-over-|
| |including always | |100k@v12/rule:dual- |
| |when | |auth. |
| |escalation_trigger| | |
| |is policy_rule) | | |
+------------------+------------------+------+---------------------+
|statement |OPTIONAL |string|Short free-text |
| | | |reason the initiator |
| | | |gives the approver. |
| | | |MUST NOT exceed 280 |
| | | |characters. |
+------------------+------------------+------+---------------------+
Table 1
Enum semantics:
* irreversibility -- the action cannot be undone once executed.
* magnitude -- the amount or scope exceeds what the initiator should
act on alone.
* uncertainty -- the initiator's confidence in its own assessment is
too low to proceed unaided.
* novelty -- the action or counterparty has no precedent in the
initiator's history.
* authority_gap -- the action requires authority the initiator was
never granted.
Schrock Expires 10 February 2027 [Page 12]
Internet-Draft EP Authorization Receipts August 2026
* policy_rule -- a deterministic policy rule required signoff and
none of the five substantive categories above captures why;
policy_basis names the rule.
Example context (fields as above, with the new member):
{
"ep_version": "1.0",
"context_type": "ep.signoff.v1",
"action_hash": "sha256:9f2c...",
"policy_id": "ep:policy:wires-over-100k@v12",
"policy_hash": "sha256:77ab...",
"initiator": "ep:entity:agent-recon-7",
"initiator_attestation": {
"escalation_trigger": "magnitude",
"policy_basis": "ep:policy:wires-over-100k@v12/rule:dual-auth",
"statement": "Exceeds my single-action limit; new beneficiary."
},
"approver": "ep:approver:jchen-controller",
"approver_index": 1,
"required_approvals": 2,
"nonce": "b64u:R9w1...",
"issued_at": "2026-06-09T17:21:05Z",
"expires_at": "2026-06-09T17:36:05Z"
}
Rules:
* *Status.* The member is OPTIONAL. Existing issuers remain
conformant; the field can be adopted policy-by-policy.
* *Binding.* No new signature, digest, or verification step is
introduced. The context is JCS-canonicalized as already required
above; JCS serializes every member present, so
initiator_attestation and everything inside it are part of the
signed bytes. The approver's signature therefore covers the
stated reason: the receipt proves the stated reason was part of
what the approver signed. Receipts carrying this member verify
under the existing Section 7.3 verifiers unmodified; a context
without the member produces byte-identical canonical material to
one produced today.
Schrock Expires 10 February 2027 [Page 13]
Internet-Draft EP Authorization Receipts August 2026
* *Trigger/basis precedence.* escalation_trigger always carries the
substantive reason: when one of the first five enum values
applies, the producer MUST use it, whether or not a deterministic
rule also fired; policy_rule MUST be used only when no substantive
category fits. Independently of which trigger is chosen, whenever
a deterministic policy rule fired, policy_basis MUST be populated
with that rule's identifier.
* *Cross-context consistency.* When a receipt contains multiple
contexts (m-of-n approvals), the initiator_attestation object, if
present in any context, MUST be present in every context of that
receipt, and its canonical form --
canonicalize(initiator_attestation) -- MUST be identical across
all of them. Every approver signs the same stated reason.
* Producers MUST NOT add members beyond the three defined above in
v1.
* A signing client implementing this member MUST render the
attestation to the approver alongside the human-readable
presentation derived from the exact Action Object that this
section already requires, subject to the untrusted-content display
rules in Section 13.9.
* A signing client presented with a context whose statement exceeds
280 characters MUST refuse to render it for signing.
The attestation is a claim by the initiator, which this document
identifies but never trusts (Section 2): it is the initiator's stated
reason, not a verified fact, and it is not evidence of the
initiator's internal state. Verifiers implementing this member MUST
check the cross-context consistency rule above and SHOULD surface the
attestation and flag other violations of this section in verification
reports; none of these checks affects signature validity, by design,
so receipts verify on verifiers that predate this member.
4.3. Agent Binding (OPTIONAL)
A producer MAY include an agent_binding member in any ep.signoff.v1
Authorization Context. The member attributes the authorized action
to an external *agent identity* and, optionally, the external
*delegation* under which that agent was authorized to act. When
present it MUST be a JSON object with the following members and no
others:
Schrock Expires 10 February 2027 [Page 14]
Internet-Draft EP Authorization Receipts August 2026
+============+==========+========+================================+
| Field | Required | Type | Description |
+============+==========+========+================================+
| agent_id | REQUIRED | string | Non-empty external agent- |
| | | | identity reference (URI, DID, |
| | | | or opaque id). This document |
| | | | does not constrain its scheme. |
+------------+----------+--------+--------------------------------+
| delegation | OPTIONAL | object | The external delegation that |
| | | | authorized the agent; members |
| | | | below, no others. |
+------------+----------+--------+--------------------------------+
| statement | OPTIONAL | string | Short free-text note for the |
| | | | approver. MUST NOT exceed 280 |
| | | | characters. |
+------------+----------+--------+--------------------------------+
Table 2
When delegation is present it MUST be a JSON object with the
following members and no others:
+=============+==========+========+==============================+
| Field | Required | Type | Description |
+=============+==========+========+==============================+
| scheme | REQUIRED | string | Non-empty name of the |
| | | | external delegation |
| | | | standard, e.g. "WIMSE", |
| | | | "DRP". |
+-------------+----------+--------+------------------------------+
| ref | REQUIRED | string | Non-empty external receipt/ |
| | | | credential identifier. |
+-------------+----------+--------+------------------------------+
| hash | OPTIONAL | string | Content hash of the |
| | | | referenced artifact, |
| | | | formatted "sha256:<64- |
| | | | lowercase-hex>". |
+-------------+----------+--------+------------------------------+
| observed_at | OPTIONAL | string | RFC 3339 timestamp recording |
| | | | when the external delegation |
| | | | evidence was observed or |
| | | | known valid. See L4 |
| | | | evidence freshness below. |
+-------------+----------+--------+------------------------------+
Table 3
Example context (fields as above, with the new member):
Schrock Expires 10 February 2027 [Page 15]
Internet-Draft EP Authorization Receipts August 2026
{
"ep_version": "1.0",
"context_type": "ep.signoff.v1",
"action_hash": "sha256:9f2c...",
"policy_id": "ep:policy:wires-over-100k@v12",
"policy_hash": "sha256:77ab...",
"initiator": "ep:entity:agent-recon-7",
"agent_binding": {
"agent_id": "did:web:agents.example.com:recon-7",
"delegation": {
"scheme": "WIMSE",
"ref": "urn:wimse:cred:9c41ab",
"hash": "sha256:2f9a...",
"observed_at": "2026-06-09T17:20:48Z"
},
"statement": "Acting for treasury-ops under wire delegation."
},
"approver": "ep:approver:jchen-controller",
"approver_index": 1,
"required_approvals": 2,
"nonce": "b64u:R9w1...",
"issued_at": "2026-06-09T17:21:05Z",
"expires_at": "2026-06-09T17:36:05Z"
}
Rules:
* *Status.* The member is OPTIONAL. Existing issuers remain
conformant; the field can be adopted policy-by-policy.
* *Claim, not proof.* agent_binding records that the action was
_presented_ as being taken by agent_id under delegation ref. This
document identifies but never trusts the binding (Section 2): it
is neither proof of the agent's identity nor proof of the
delegation's validity, both of which remain the responsibility of
the referenced external system. A verifier MUST NOT treat
agent_binding as proof of either; it MAY surface agent_id and
delegation to the relying party as part of the verified context,
clearly labeled as a reference to an external system.
* *Binding.* No new signature, digest, or verification step is
introduced. The context is JCS-canonicalized as already required
above; JCS serializes every member present, so agent_binding and
everything inside it are part of the signed bytes. The approver's
signature therefore covers the binding. Receipts carrying this
member verify under the existing Section 7.3 verifiers unmodified;
a context without it produces byte-identical canonical material to
one produced today.
Schrock Expires 10 February 2027 [Page 16]
Internet-Draft EP Authorization Receipts August 2026
* *Cross-context consistency.* When a receipt contains multiple
contexts (m-of-n approvals), the agent_binding object, if present
in any context, MUST be present in every context of that receipt,
and its canonical form -- canonicalize(agent_binding) -- MUST be
identical across all of them. Every approver signs the same
attribution.
* Producers MUST NOT add members beyond those defined above in v1,
in either agent_binding or its delegation.
* A signing client implementing this member SHOULD render agent_id
(and delegation if present) to the approver alongside the human-
readable presentation derived from the exact Action Object that
this section already requires, subject to the untrusted-content
display rules in Section 13.9. A signing client presented with a
context whose statement exceeds 280 characters MUST refuse to
render it for signing.
*L4 evidence freshness (OPTIONAL).* A human authorization decision is
only as trustworthy as the upstream agent-identity and delegation
evidence it relied on. If a decision is enforced correctly against a
delegation claim that was never constrained or has since expired, the
failure surfaces at the authorization layer but originates in the
identity/delegation layer beneath it. This document makes that
dependency explicit and recordable without absorbing the identity
layer:
* A producer MAY populate delegation.observed_at with the RFC 3339
time at which the external delegation evidence was observed or
known valid. Like the rest of the binding, it is covered by the
approver's signature.
* A relying party MAY enforce freshness against observed_at. When
it does, the evaluation MUST fail closed: a missing observed_at, a
timestamp later than the evaluation time, or an age exceeding the
relying party's configured maximum MUST be treated as not-fresh.
When no maximum age is configured, freshness is not evaluated and
the evidence is still surfaced for the audit record.
This keeps the receipt agnostic to which external identity/delegation
scheme prevails: the relying party binds to and records whatever
evidence was presented rather than requiring that layer to converge,
and a stale or unconstrained upstream claim becomes detectable after
the fact rather than silently absorbed. As with the Initiator
Attestation, none of these checks affects signature validity, by
design, so receipts verify on verifiers that predate this member.
Schrock Expires 10 February 2027 [Page 17]
Internet-Draft EP Authorization Receipts August 2026
5. Approver Keys and the Signoff Signature
This section is the core upgrade over server-side approval systems.
5.1. Key Classes
Key classes classify KEY CUSTODY -- who holds and exercises the
approver's signing key -- and nothing else. They are distinct from,
and unrelated to, any assurance-level or conformance-class vocabulary
used elsewhere. Cross-protocol requirements ought to name verifier-
visible properties such as user verification, device binding,
initiator exclusion, distinct humans, freshness, and status rather
than treating these receipt-local custody labels as universal
assurance grades.
*Class A -- Device-bound keys (RECOMMENDED).* The approver's key is
generated and held in a platform authenticator or security key and
exercised via WebAuthn [WEBAUTHN]. The signature algorithm is ES256
(P-256) or Ed25519 where supported. The WebAuthn challenge MUST be
the context hash. The authenticator's user-verification flag
(biometric or PIN) MUST be required for signoff credentials. This
user-verification-gated signature is the native EP human-approval
act; it is fully defined by this section and does not rely on any
external acquiescence or confirmation mechanism. Attestation SHOULD
be captured at enrollment so relying parties can establish that the
key is hardware-bound.
*Class B -- Software keys.* An Ed25519 keypair held in the approver's
client environment (CLI keychain, mobile secure enclave via app).
Acceptable where WebAuthn is impractical (headless approval
terminals), with the reduced assurance noted in receipts.
*Class C -- Operator-custodied keys (LEGACY).* The EP operator signs
on the approver's behalf after authenticating them. This class
exists only to describe pre-existing deployments. Receipts produced
under Class C MUST be labeled key_class: "C" and relying parties
SHOULD treat them as evidence of operator assertion, not approver
signature. New deployments SHOULD NOT use Class C.
5.2. Enrollment and the Approver Directory
Approver public keys are enrolled into a signed Approver Directory
maintained per organization: a Merkle tree over (approver_id,
public_key, key_class, valid_from, valid_to, roles) entries, with
signed tree heads published alongside receipt log checkpoints. A
receipt's offline verifiability (G5) includes an inclusion proof of
the approver's key entry, so a verifier needs no live directory
access. Key rotation appends a new entry and terminates the old one;
Schrock Expires 10 February 2027 [Page 18]
Internet-Draft EP Authorization Receipts August 2026
signatures verify against the key entry valid at issued_at.
Directory authority is a trust root and MUST NOT default to the EP
operator. The directory tree head MUST be signed by an organization-
controlled directory key (custody options parallel Section 5.1; an
organization-held hardware key is RECOMMENDED). Where directory
_operation_ is delegated to the EP operator, every enrollment entry
MUST carry a second-party attestation -- a signature over the new
entry by an organization administrator key or by a quorum of already-
enrolled approvers -- and that attestation MUST be included in the
receipt's approver_key_proofs. Verifiers MUST treat a directory head
signed only by an operator-held key as operator assertion (Class
C-equivalent assurance), regardless of the key class of the
individual signoffs. Rationale: an operator that unilaterally
controls directory membership cannot forge an enrolled approver's
signature, but it can enroll a key it controls under a legitimate
approver's name -- relocating the forgery rather than preventing it.
See Section 13.6.
This directory is also the binding point between approver identifiers
and real-world persons (Section 1.2). The strength of that binding
-- how an organization proves that an enrolled identifier is the
person it names, and how key-discovery layers attach to it -- is a
property of the directory authority and any identity layer bound to
it, not of the receipt format defined here.
5.3. The Signoff
A signoff is:
{
"context_hash": "sha256:c41e...",
"signature": "b64u:MEUCIQ...",
"key_class": "A",
"approver_key_id": "ep:key:jchen-controller#2026-01",
"signed_at": "2026-06-09T17:24:40Z",
"webauthn": { "authenticator_data": "b64u:...",
"client_data_json": "b64u:..." }
}
For Class A, verifiers MUST validate the WebAuthn assertion per
[WEBAUTHN] including that clientDataJSON.challenge equals the context
hash and that the user-verification bit is set. A denial is also
signed (over the context hash with a decision: "denied" envelope) so
that refusals are equally attributable, tamper-evident, and terminal.
This is a cryptographic statement; legal non-repudiation is out of
scope.
Schrock Expires 10 February 2027 [Page 19]
Internet-Draft EP Authorization Receipts August 2026
6. Pre-Execution Authorization Bundle
The EP-AUTHORIZATION-BUNDLE-v1 profile is the portable pre-execution
form of the human evidence defined by this document. It closes the
gap left by earlier revisions, which named an Authorization Bundle
without defining its wire object or verification algorithm.
{
"bundle_version": "EP-AUTHORIZATION-BUNDLE-v1",
"bundle_id": "ep:authorization-bundle:01J...",
"action": { "...": "full Action Object" },
"action_hash": "sha256:9f2c...",
"contexts": [ { "...": "Authorization Context 1" },
{ "...": "Authorization Context 2" } ],
"signoffs": [ { "...": "Signoff 1" },
{ "...": "Signoff 2" } ],
"approver_key_proofs": [ { "directory_inclusion": "..." } ],
"presentation_evidence": []
}
The bundle MUST be a closed JSON object with exactly the eight
members shown above. Each member is required; approver_key_proofs
and presentation_evidence MAY be empty arrays only when the
verifier's pinned trust inputs and policy do not require those
artifacts. Unknown, duplicated, or missing members are a bundle-
malformed refusal. The Action Object, Authorization Context,
Signoff, key-proof, and presentation- evidence semantics are those
defined elsewhere in this document.
The *bundle digest* is the SHA-256 digest of the JCS serialization of
the complete closed object, formatted as sha256: followed by 64
lowercase hexadecimal characters. The digest is computed, not
carried as a ninth member. A native grant, policy-decision record,
or audit event can bind the complete bundle by this digest without
copying its contents.
The bundle contains no consumption, log_proof, execution outcome, or
success assertion. Constructing or validating it does not reserve
capacity, issue a grant, authorize the action, consume the action,
prove that an effect occurred, or make an uncertain action safe to
retry. Those properties belong to the authorization server, policy
decision point, executor, and terminal Trust Receipt.
For an m-of-n policy, contexts contains the n approver contexts
independently selected by current policy, with distinct approver
identifiers, indexes, and nonces. Every context MUST carry the same
signed authorization_instance. The bundle_id is only an external
identifier and MUST NOT substitute for that signed value. signoffs
Schrock Expires 10 February 2027 [Page 20]
Internet-Draft EP Authorization Receipts August 2026
contains at least m and at most n entries, each covering a different
context. An unsigned context identifies an eligible approver slot
that did not contribute to the satisfied quorum; it is not a
malformed bundle. A signoff that does not cover one of the selected
contexts, two signoffs covering one context, fewer than m valid
signoffs, or more than one signoff from the same approver is a
refusal.
6.1. Optional Native Authorization Binding
An Authorization Context MAY contain an authorization_binding object.
The object MUST contain a non-empty profile identifier; every other
member and its native verification procedure are defined by that
profile. The complete object is part of the signed Authorization
Context.
The Bundle verifier does not select or trust the profile named by the
presenter. Before accepting the binding, the relying party MUST
independently select the profile, natively verify the source artifact
under pinned trust inputs, derive the expected binding object from
that verified artifact, and compare the JCS serializations of the
expected and presented objects. A malformed or unequal binding is
REFUSE. An unavailable verifier, trust input, or lossless mapping is
INDETERMINATE.
Every Authorization Context in one bundle MUST either omit
authorization_binding or carry the same byte-identical binding. A
mixture of bound and unbound contexts is a refusal. This document
defines no OAuth, AP2, WIMSE, transaction-challenge, or other native
binding profile; such profiles are separate and cannot change the
Bundle's signature or verification rules.
6.2. Pre-Execution Verification Algorithm
A verifier evaluating a bundle before a grant or action MUST perform
the following steps in order:
1. Apply the strict JSON and canonicalization gates in
Section 13.11 and verify the closed bundle shape.
2. Recompute action_hash from the canonical Action Object.
3. Recompute each context hash and require every context to commit
to that action hash, one policy hash, one audience, one shared
authorization_instance, and, when present, one identical
authorization binding. Each context nonce remains distinct.
Schrock Expires 10 February 2027 [Page 21]
Internet-Draft EP Authorization Receipts August 2026
4. Require the signed authorization_instance to equal the value
independently issued and durably registered for this approval
ceremony. An unavailable expected value is INDETERMINATE; a
presenter-selected or unequal value is REFUSE.
5. Verify every presented signoff against the independently trusted
approver key and directory proof, including relying-party
acceptance of the key class, key validity, signing time, and the
WebAuthn user-verification requirements for Class A. Require
each signoff to cover one distinct selected context; do not
require signoffs for the n-m eligible contexts that did not
contribute.
6. Require the context approver set to equal the set independently
selected for this transaction by the authorization server or
current policy. Then apply initiator exclusion, pairwise
approver independence, delegated-approver constraints, and the
required m-of-n threshold. A presenter-selected set is
insufficient even when every signature is valid.
7. Require the relying-party clock to fall within every context's
validity window. Historical or clockless verification is not a
pre-execution authorization check.
8. Require every context audience to equal the verifier's
independently configured audience.
9. When current directory, revocation, presentation, or delegation
evidence is required by policy, verify it from pinned trust
inputs. Unavailable or stale required state is INDETERMINATE,
never an implicit pass.
10. When authorization_binding is present, apply the independently
selected native profile and verifier. Derive the expected
binding from natively verified inputs, compare its JCS bytes to
the signed binding, and require a lossless match to the exact
Action Object under a relying-party-pinned mapping.
11. Re-evaluate the verifier's current local policy and require its
policy digest to equal the digest signed by every context.
Unavailable or stale policy state is INDETERMINATE; a refusal or
digest mismatch is REFUSE. The human evidence does not freeze
or replace relying-party policy.
The result is exactly one of:
SATISFIED The bundle satisfies the selected evidence profile. This
result is evidence input only and is not an authorization verdict.
Schrock Expires 10 February 2027 [Page 22]
Internet-Draft EP Authorization Receipts August 2026
REFUSE A definite structural, signature, action, actor, subject,
audience, policy, freshness, revocation, independence, threshold,
or replay mismatch occurred.
INDETERMINATE A required current trust input, status source,
mapping, or policy evaluation was unavailable or could not be
completed.
An authorization server that accepts a bundle for grant issuance MUST
atomically bind the bundle digest, signed authorization_instance, and
context nonce set to one grant identifier. Concurrent or repeated
presentation MUST NOT create two independently usable grants; an
idempotent retry can return the same grant result. The executor
remains responsible for atomic one-time admission of the native
transaction or grant in its authoritative state domain. Neither rule
claims global double-spend prevention across independent
authorization servers or executors.
6.3. Required Hostile Conformance Cases
A claimed implementation of EP-AUTHORIZATION-BUNDLE-v1 MUST publish
and pass cases covering at least:
* approval of action A presented for materially different action B;
* the correct action with the wrong resource-server audience;
* the correct delegated subject with a different agent actor, and
the correct actor with a different delegated subject;
* a valid generic UI confirmation that is not bound to the native
grant or transaction;
* expired, revoked, stale, malformed, and unavailable approval
evidence;
* wrong policy digest, incomplete quorum, duplicate human, and
initiator self-approval;
* a valid m-of-n bundle with exactly m signoffs and n-m unsigned
eligible approver contexts, to prevent an implementation from
silently replacing m-of-n with n-of-n;
* valid signoffs from two different authorization instances spliced
into one apparent quorum, which MUST be refused even when action,
policy, audience, approvers, and signatures otherwise match;
Schrock Expires 10 February 2027 [Page 23]
Internet-Draft EP Authorization Receipts August 2026
* an internally consistent bundle whose shared authorization
instance was selected by the presenter rather than matching the
relying party's registered instance;
* valid signatures from a presenter-selected approver set that does
not equal the authorization-server or policy-selected set;
* a missing, lossy, unpinned, or profile-mismatched native
authorization-to-Action mapping;
* native challenge or mandate replay distinguished from grant replay
and from executor-side action consumption;
* a dynamic plan expansion beyond the approved action or trusted
effect envelope, which requires a new bundle; and
* a status, policy, or provider timeout producing INDETERMINATE
without blind execution or blind retry.
7. Consumption, Commitment, and the Trust Receipt
7.1. State Machine
An authorization attempt proceeds:
REQUESTED -> {PARTIALLY_APPROVED}* -> APPROVED -> COMMITTED
\-> DENIED \-> EXPIRED
\-> EXPIRED
COMMITTED, DENIED, and EXPIRED are terminal. The protocol invariants
-- maintained as machine-checked models and REQUIRED of conforming
implementations -- are:
* *ConsumeOnce.* Within one conforming shared, atomic consumption
domain, an authorization instance transitions to a terminal state
at most once. Any second presentation to that domain MUST be
rejected with a replay error. The model does not assert
coordination with an independent store that does not share this
state. For a Bundle-derived Trust Receipt, consumption.nonce MUST
equal the Bundle's shared authorization_instance. A legacy
single-context receipt without that member retains its context
nonce as the consumption key.
* *BindingMatch.* A signoff satisfies only the context (and
therefore only the action hash) it signs.
* *TerminalIrreversibility.* No transition exits a terminal state.
Schrock Expires 10 February 2027 [Page 24]
Internet-Draft EP Authorization Receipts August 2026
* *SelfApprovalImpossible.* For every signoff, approver !=
initiator; for m-of-n policies, approvers are pairwise distinct
and each distinct from the initiator.
* *NoBypassWrite.* A COMMITTED state is reachable only through the
full sequence; conforming verifying executors MUST NOT execute
without verifying it (Section 11).
7.2. The Trust Receipt
Upon commitment the orchestrator assembles and logs the Trust
Receipt:
The object in this section together with the verification algorithm
in Section 7.3 is the EP-AUTHORIZATION-RECEIPT-v1 format profile.
The profile name is an out-of-band format identifier; it is not an
additional member of the signed object. Implementations MUST NOT
identify this detailed format as EP-RECEIPT-v1: that identifier
predates this document and names a different generic { @version,
payload, signature } envelope. A consumer that is told only EP-
RECEIPT-v1 therefore MUST NOT dispatch to this section's verifier.
{
"receipt_id": "ep:receipt:01J...",
"action": { "...": "full Action Object" },
"action_hash": "sha256:9f2c...",
"contexts": [ { "...": "Authorization Context 1" },
{ "...": "Authorization Context 2" } ],
"signoffs": [ { "...": "Signoff 1" },
{ "...": "Signoff 2" } ],
"consumption": { "nonce": "b64u:R9w1...",
"state": "COMMITTED",
"committed_at": "2026-06-09T17:25:02Z" },
"log_proof": { "leaf_index": 88412,
"inclusion_path": ["sha256:...", "..."],
"checkpoint": { "tree_size": 90210,
"root_hash": "sha256:...",
"log_signature": "b64u:...",
"log_key_id": "ep:log:acme#1" } },
"approver_key_proofs": [ { "directory_inclusion": "..." } ]
}
For a receipt produced from an EP-AUTHORIZATION-BUNDLE-v1 object, the
value carried as consumption.nonce MUST equal the signed
authorization_instance shared by every context. The field name is
retained for compatibility with the base receipt profile; the
equality prevents the terminal state from being detached from the
approval ceremony.
Schrock Expires 10 February 2027 [Page 25]
Internet-Draft EP Authorization Receipts August 2026
7.3. Offline Verification Algorithm
A verifier with (receipt, trusted log public key, trusted directory
root or pinned approver keys) and *no network access* MUST be able to
establish all of the following; the published verifier package
performs exactly these steps:
1. Recompute the action hash from the canonical Action Object;
compare.
2. For each context: recompute the context hash; confirm it commits
to the action hash, the policy hash, and a distinct approver.
For a Bundle-derived receipt, require one shared
authorization_instance, distinct per-context nonces, and equality
between that instance and consumption.nonce.
3. For each signoff: verify the signature (and WebAuthn assertion
where present) over the context hash against the approver key
entry, checking the key's validity window contains issued_at.
4. Confirm SoD: initiator appears in no approver slot; approvers are
pairwise distinct; the approval count satisfies
required_approvals.
5. Verify the Merkle inclusion proof of the receipt leaf against the
checkpoint root, and the checkpoint signature against the log
key.
6. Confirm signed_at and committed_at fall within [issued_at,
expires_at].
Degenerate empty-path rule (step 5). An empty inclusion_path MUST be
accepted only when the checkpoint's tree_size is exactly 1 and the
leaf_index, when present, is 0; an empty path presented with any
other tree size (including a missing or non-integer tree_size) MUST
be refused, before any Merkle computation. Without this rule an
empty path degenerates to "leaf hash equals root hash", which a
forged checkpoint can satisfy at any claimed tree size by simply
repeating the leaf hash as its root. Two public reject vectors in
the EP conformance suite (reject_empty_path_tree_size_not_1 and
reject_empty_path_nonzero_leaf_index) pin this rule across the cross-
language reference verifiers.
Step 5 is what distinguishes EP receipts from log-access designs: the
checkpoint travels _inside_ the receipt, so verification requires no
query to the log. Detecting log equivocation (split-view attacks)
additionally benefits from gossip or witness cosigning
(Section 13.4), which is an online activity; the offline guarantee is
Schrock Expires 10 February 2027 [Page 26]
Internet-Draft EP Authorization Receipts August 2026
that _this receipt is internally consistent, correctly signed by
enrolled approver keys, and was included in a log tree whose head the
log operator signed_.
Offline verification establishes authenticity, not currency. Two
properties are explicitly NOT established offline: (a) post-issuance
revocation -- a receipt whose approver key was revoked an hour after
commitment still verifies; the artifact is evidence of validity _at
commit time_; and (b) log honesty against split views (Section 13.4).
A relying party with freshness or revocation requirements MUST
additionally consult a current directory head and log checkpoint
online. Implementations MUST NOT describe offline verification as
establishing that a receipt is "currently valid."
The Initiator Attestation (Section 4.2), where present, is covered by
the context hash recomputed in step 2 above; no additional
verification step is required for it.
8. Companion Receipt Extensions and Digest Binding
Extensions MUST NOT be inserted into the base Trust Receipt. The EP-
AUTHORIZATION-RECEIPT-v1 object, its closed schema, its canonical
bytes, and the verification procedure in Section 7.3 remain
unchanged. In particular, a base verifier MUST NOT strip, ignore, or
otherwise preprocess an unrecognized receipt member before
verification.
A producer MAY convey lifecycle or composition bindings in a separate
companion object whose version is EP-RECEIPT-EXTENSIONS-v1. The
companion is not part of the base Trust Receipt and confers no
authority by itself. It MUST be a closed object with exactly
version, base_receipt_digest, base_action_digest, and entries:
{
"version": "EP-RECEIPT-EXTENSIONS-v1",
"base_receipt_digest": "sha256:...",
"base_action_digest": "sha256:...",
"entries": [
{
"name": "ai.emiliaprotocol.trust-program.stage-receipts.v1",
"operation_id": "provider-stable-operation-id",
"consequence_digest": null,
"artifact_digest": "sha256:..."
}
]
}
Schrock Expires 10 February 2027 [Page 27]
Internet-Draft EP Authorization Receipts August 2026
The base_receipt_digest MUST be SHA-256 over the JCS canonicalization
of the complete, unchanged base Trust Receipt. No member is removed
or added for this calculation. This value is the identity of the
complete portable receipt, not the Merkle leaf hash; implementations
MUST NOT substitute a leaf digest that omits log_proof or
approver_key_proofs. The base_action_digest MUST equal that base
receipt's action_hash. Digest values in this companion MUST use the
lowercase sha256: prefix followed by exactly 64 lowercase hexadecimal
characters. The entries member MUST contain between 1 and 32 closed
objects, each with exactly name, operation_id, consequence_digest,
and artifact_digest.
* name MUST be an ASCII lowercase, dot-separated extension name.
Each label begins and ends with a lowercase letter or digit and
can contain interior hyphens. A name MUST NOT exceed 255 ASCII
characters. A name allocated outside the document-local namespace
SHOULD begin with a reversed DNS name controlled by its allocator.
Control of a name is only collision avoidance; it conveys no
trust. An entries array MUST NOT contain the same name more than
once.
* operation_id is either null or the stable operation identifier
selected by the extension profile. A lifecycle extension
governing a material attempt MUST use a non-null value and MUST
NOT derive it from presenter-controlled display text. A non-null
value MUST be non-empty, contain no control characters, and
contain no more than 512 Unicode scalar values.
* consequence_digest is either null for a pre-effect extension or
the extension profile's digest of the exact observed, claimed, or
settled consequence. A null value conveys no execution or outcome
proof.
* artifact_digest MUST be the SHA-256 digest of the exact companion
artifact under the canonicalization rule named by the selected
extension definition.
An extension-aware relying party MUST first verify the unchanged base
Trust Receipt using the base verification procedure. It then
separately verifies the companion version, recomputes both base
digests, and evaluates the extension names required by its own
policy. The companion envelope is an untrusted index, not an
authenticated assertion. Companion artifacts are conveyed
separately; this document defines no network retrieval or presenter-
supplied locator. Parsers MUST apply the duplicate-member,
surrogate, number, and depth rejection rules in Section 13.11 to the
companion before using any entry. For each required entry, an
extension-specific verifier MUST verify the companion artifact under
Schrock Expires 10 February 2027 [Page 28]
Internet-Draft EP Authorization Receipts August 2026
relying-party-selected trust and MUST require that artifact to bind
the same extension name, base action digest, base receipt digest,
operation identifier, and consequence digest. It then recomputes the
artifact digest over that exact artifact. The extension profile MUST
define any freshness, replay, revocation, and terminal-state checks
needed for its assurance claim. Merely carrying a digest does not
establish the artifact's validity, authority, freshness, non-replay,
or execution semantics.
An extension-aware relying party MAY ignore an unknown sidecar entry
only when its policy does not require that extension name. It MUST
fail closed when a required entry is absent, unknown, duplicated,
malformed, untrusted, or mismatched. The required extension set is
selected independently by relying-party policy; a presenter cannot
weaken it by omitting an entry. A verifier that implements only EP-
AUTHORIZATION-RECEIPT-v1 does not process the companion and gains no
additional assurance from its presence.
8.1. Provisional Extension Registry
This revision defines the design rules for a provisional, document-
local namespace; it does not create an IANA registry. Names
beginning with ep. are reserved for assignments made by a future
revision of this document or by a separately versioned public
extension index explicitly referenced by such a revision. This
revision makes no ep. assignments. Other specifications can self-
allocate a reversed-DNS name under a domain they control.
Every extension definition MUST specify its immutable name,
controlling specification and version, companion artifact version,
canonicalization rule, artifact-digest rule, operation-identifier
semantics, consequence-digest semantics, relying-party trust inputs,
freshness and replay behavior, and fail-closed conditions. An
incompatible semantic change MUST allocate a new name. An extension
definition MUST NOT redefine the base Action Object, Authorization
Context, signoff, consumption, or log-proof bytes.
A relying party MUST pin the exact extension definition it accepts;
discovering a syntactically valid name is not authorization to trust
it. A future document could request an IANA registry if
interoperable use demonstrates that centralized allocation is needed.
Such a request is outside the scope of this revision.
Schrock Expires 10 February 2027 [Page 29]
Internet-Draft EP Authorization Receipts August 2026
8.2. Relationship to the Action Lifecycle
This subsection is informative. The companion seam permits a
revocation statement to retract future authority without rewriting an
executed effect; an outcome-binding artifact to compare approved
bytes with an observed effect; an action-remedy receipt to describe a
newly authorized compensating action with its own CAID and rollback:
false; or an evidence challenge to name evidence missing before
execution. These examples do not soften the base receipt's terminal
or consumption semantics.
An Authority Program (also described informally as a Trust Program)
can use the same companion seam for immutable stage receipts whose
sorted predecessor receipt digests bind a relying-party-pinned
recursive series/parallel program to one root CAID and action. An
Authorization Evidence Chain composition artifact can bind a
separately verified set of evidence nodes to the same receipt and
action digests. A staged DTC settlement profile could likewise bind
a receipt or certificate state root. These are informative, non-
exhaustive consumers. Base receipt verification does not validate
any such chain, program, lifecycle, or settlement artifact. This
document does not claim that Authority Program or DTC settlement
infrastructure is standardized, independently implemented, deployed,
or proved by base receipt or companion-envelope verification.
9. Multi-Approver Policies (m-of-n)
A policy MAY require k distinct approvers from a role set. Each
approver receives and signs an individual Authorization Context
sharing the same action_hash and signed authorization_instance but
carrying a distinct nonce and approver_index. Commitment occurs only
when k valid, distinct signoffs exist before expires_at. Partial
approval confers no authority: a verifying executor presented with
fewer than k signoffs MUST refuse.
10. Delegation Constraints
Where an approver's authority is itself delegated, the delegation
record MUST be presented in the receipt's approver_key_proofs, and
the constraint *DelegateCannotExceedPrincipal* applies: the effective
scope of a delegate is the intersection of the delegation grant and
the principal's authority at signing time. Delegation chains are
bounded (RECOMMENDED depth of at most 2) and every link is
independently signed.
Schrock Expires 10 February 2027 [Page 30]
Internet-Draft EP Authorization Receipts August 2026
11. Conformance Classes and Execution-Side Enforcement
Honesty about deployment topology is a protocol feature. Three
classes:
*EP-Verified Execution (STRONG).* The system of record (payment
switch, registry, deployment controller) verifies the EP-
AUTHORIZATION-BUNDLE-v1 object and the current native grant or policy
decision before executing, atomically consumes the native transaction
or grant in its authoritative state domain, and refuses otherwise.
The pre-execution bundle deliberately contains no consumption
attestation. The gate cannot be bypassed by any party that does not
control the system of record itself.
*EP-Gated Middleware (STANDARD).* An interception layer between the
agent and the executing credential enforces the gate. Provides
strong protection against agent error and prompt injection; an
operator with code control can bypass. Receipts remain valid
evidence of what _was_ approved.
*EP-Evidence Only (BASIC).* Actions execute independently; receipts
are produced for audit. No enforcement claim is made.
Implementations MUST declare their class in receipts
(enforcement_class), and marketing or compliance claims MUST NOT
state a stronger class than deployed. This section exists because
the difference between "we proved the protocol" and "your deployment
is unbypassable" is the most common overclaim in this category.
12. Relationship to Other Work
*Companion EP documents.* This document is self-contained: a receipt
is issued, verified, and consumed under this specification alone. A
family of separately published companion documents composes with it
without altering its semantics, grouped by function: action identity
and comparison across independently issued artifacts as defined by
CAID [EP-CAID]; multi-approver policies as defined by EP-QUORUM
[EP-QUORUM] and display binding; enforcement-side ordering and
bounded multi-action execution (including [EP-BOUNDED-CAP]); post-
execution outcome observation, revocation statements, and
compensating remedies; and evidence composition, challenge, and
reliance records. Each companion consumes this document's digests or
supplies relying-party trust inputs; none is required for conformance
to this document.
*DRP* ([I-D.nelson-agent-delegation-receipts]) binds a _user's_
delegation to an _operator's_ instructions -- upstream consumer
delegation. EP binds an _organizational approver_ to an _exact
Schrock Expires 10 February 2027 [Page 31]
Internet-Draft EP Authorization Receipts August 2026
action_ -- downstream authorization under its own SoD and m-of-n
profiles. The two compose: a DRP delegation can be referenced in an
EP Action Object's provenance field.
*Bounded Capability Receipts* [EP-BOUNDED-CAP] authorize a different
lifecycle. An EP Authorization Receipt can approve the exact act of
issuing a bounded capability, and that issuance receipt is consumed
when the capability is registered. It MUST NOT then be reused as
though it approved every later capability-funded operation. The
capability binds the complete issuance-receipt digest, scope, budget,
holder proof, and validity interval; its shared reserve/commit store
accounts later operations. A deployment that requires human approval
of an individual exercise obtains a new action-bound EP receipt or a
quorum receipt set ([EP-QUORUM]) for that exercise.
*CIBA* [CIBA] transports an authentication-time approval to a
backchannel device; it does not produce an action-bound, offline-
verifiable, one-time-consumable artifact. CIBA MAY serve as the
transport by which an approver is reached; the EP signoff is what
they produce when they get there.
*AI Agent Authentication and Authorization* ([I-D.klrc-aiagent-auth])
keeps the final authorization decision with the authorization server,
requires local user confirmation to be bound to a verifiable grant,
and identifies mid-execution confirmation as an area where additional
work may be needed. The EP-AUTHORIZATION-BUNDLE-v1 object supplies
one concrete, portable approval-evidence profile for that binding,
including exact action, approver independence, audience, actor,
subject, policy, and validity checks. It does not replace the native
grant or authorization-server decision. The same document requires
durable, tamper-evident audit records. An EP Trust Receipt can
supply an action, decision, and terminal-consumption record under the
selected profile, but does not by itself satisfy deployment
monitoring, remediation, retention, or compliance requirements. A
profile can carry the Authorization Context or Trust Receipt digest
in transaction context without redefining transaction-token
semantics.
*OAuth Transaction Authorization Challenge*
[I-D.rosomakho-oauth-txn-challenge] defines an OAuth-specific
protected-resource challenge, asynchronous approval choreography,
RAR-bound access token, and protected-resource validation procedure.
EP does not duplicate those mechanisms. A separate application
profile can map a natively verified transaction and grant to the
generic authorization_binding extension point without making this
receipt format an OAuth extension or replacing the authorization
server's decision.
Schrock Expires 10 February 2027 [Page 32]
Internet-Draft EP Authorization Receipts August 2026
*Mastercard Verifiable Intent* [FIDO-VI], co-developed with Google
and contributed to the FIDO Alliance, describes portable, verifiable
evidence of user intent. The cited page describes a contribution and
prospective standardization, not a final FIDO specification. EP does
not claim portable human evidence is absent. Its receipt profile
separately specifies an enrolled organizational approver directory,
exact Authorization Context, initiator exclusion, terminal
consumption record, and optional distinct-human quorum.
*AuthZEN Access Request and Approval Profile* [AUTHZEN-AARP] defines
requestable denial, asynchronous approval tasks, an approval object
whose optional state carries opaque proof or verifier state, JWS
interoperability when that state is carried by value, an exact-match
baseline, and PDP re-evaluation at enforcement time. EP does not
replace that profile. A deployment can select an EP receipt as an
additional evidence profile when it requires a verifier-visible
approver-held device ceremony, enrolled-human directory binding,
portable initiator exclusion, or one-time executor consumption. The
relying party remains responsible for deciding which profile
satisfies its requirement.
*WIMSE / workload identity* authenticates the workload to services;
EP supplies action-bound approval evidence that a relying party may
require in its local authorization decision. These are complementary
layers.
*Receiver-attested logging (e.g., Sello)* has the receiving service
sign what it observed, post-hoc. EP is pre-execution authorization.
A complete deployment benefits from both: EP records the pre-
execution signing and consumption event under a selected profile;
receiver attestation records what the receiver observed afterward.
Local policy determines whether the former is sufficient for
authorization.
*AgentROA (draft-nivalto-agentroa-route-authorization), AIIP, and
CIRP* define machine-side, per-hop execution and route receipts for
agent actions under delegated authority. Their approval-state or
approval-reference fields do not by themselves define the EP ceremony
and directory profile. EP evidence can fill such a reference where
that profile is selected, and its delegation constraints share
AgentROA's monotonic ("tighten-only") scope-narrowing discipline.
*The Entity Attestation Token (RFC 9711, RATS)* attests the _agent or
platform_ -- model, keys, posture; EP carries evidence of an enrolled
approver key's action-bound decision. The two are orthogonal and
composable: an EAT says the machine is what it claims; an EP receipt
says a named person approved the exact action.
Schrock Expires 10 February 2027 [Page 33]
Internet-Draft EP Authorization Receipts August 2026
*Transaction Tokens (draft-ietf-oauth-transaction-tokens)* propagate
workload and agent authorization context across a machine call chain;
an EP receipt can be one referenced approval artifact when a relying
party requires that profile.
*Evidence Record Syntax (RFC 4998)* preserves signed evidence across
algorithm aging by periodic re-timestamping. EP applies the same
approach to long-lived receipts via an evidence-record renewal chain,
so a receipt verifiable today remains verifiable after its original
algorithms weaken -- a property the 10-25+ year retention schedules
of government records require.
13. Security Considerations
13.1. Operator Compromise
Under key classes A/B, a compromised EP operator can deny service and
can fail to route signoff requests, and it cannot _forge a
signature_: it lacks approver keys, and it cannot replay one (nonces
are single-consumption and receipts chain). Two operator-compromise
paths remain and are stated plainly rather than claimed away. First,
an operator that controls the signing client's rendering can harvest
a _genuine_ signature over an action the approver misunderstood -- a
presentation attack (Section 13.3); for this reason an independently-
authored rendering surface is REQUIRED for high-value policies.
Second, an operator that unilaterally controls the Approver Directory
can enroll keys it controls (Section 5.2, Section 13.6).
Accordingly, the accurate claim for classes A/B is: "the operator
cannot forge an approver's signature." The stronger claim -- "the
operator cannot obtain an unauthorized approval" -- additionally
requires the directory-authority and independent-rendering controls.
Under class C the operator can fabricate outright; hence the labeling
requirement.
13.2. Approver Device Compromise
A stolen authenticator with user verification still requires the
biometric/PIN. Organizations SHOULD require key class A for high-
value policies and SHOULD pair approval with out-of-band action
rendering (the approver sees the wire details on a second surface).
Schrock Expires 10 February 2027 [Page 34]
Internet-Draft EP Authorization Receipts August 2026
13.3. Presentation Attacks
The gravest risk in this protocol, stated without minimization: the
approver signs context hash H believing it represents action X when
it represents action Y. A signature proves user presence and an act
of approval toward the signed context; it does not prove what the
signing surface rendered. Required mitigations, in increasing
strength: (1) the signing client MUST render the Action Object from
the exact bytes that were hashed -- never from a separately supplied
description; (2) for high-value policies, render templates MUST be
registered with the policy and committed by policy_hash, so the
display logic is part of what the approver's signature covers; (3)
for policies above an organization-designated threshold, the material
action parameters (amount, beneficiary identifiers) MUST additionally
be rendered on a second surface not authored by the orchestrating
operator -- for example, delivered by the verifying executor or an
independent operator to the approver's enrolled device over a
separate channel. The residual risk is stated honestly: absent a
trusted display path (hardware the operator does not author),
rendering fidelity is enforced by controls (2)-(3), by audit, and by
consented mismatch drills (Section 13.8) -- not by mathematics. The
base receipt guarantees exactness of the Action Object covered by the
approver signature; by itself it cannot detect a difference between
that object and the pixels the human actually saw. When a relying
party applies Section 4.1, it can detect a mismatch between the
profile-defined display bytes committed by trusted presentation
evidence and the signed action. Even then, a compromised physical
display path remains outside the cryptographic claim.
13.4. Log Equivocation
A malicious log could show different trees to different parties.
Checkpoints SHOULD be witness-cosigned and/or gossiped between
independent EP operators; the federation profile makes cross-operator
checkpoint exchange mandatory. Before a witness signs a checkpoint
or a gossip participant accepts it for comparison, that participant
MUST verify the checkpoint's log signature under the pinned log key
and MUST verify any required consistency proof from the participant's
previously accepted checkpoint. A quorum of witness signatures over
a caller-supplied but unauthenticated tuple is not evidence that the
named log produced that tuple.
Schrock Expires 10 February 2027 [Page 35]
Internet-Draft EP Authorization Receipts August 2026
For this purpose, independent operators require separate
administrative control, key custody, and failure domains; multiple
co-located processes under one operator do not provide independent
witnessing. Comparing supplied authenticated views can prove that
the views conflict. It does not by itself prove freshness,
completeness, or that every relying party received the latest
checkpoint.
13.5. What the Formal Models Do and Do Not Prove
The TLA+/Alloy models prove safety of the authorization state
machine: no replay, no self-approval, no bypass _within the modeled
system_, no partial commitment. They prove nothing about any AI
model's behavior, about host compromise, or about deployments in a
weaker conformance class. Implementations MUST NOT represent the
proofs as covering deployment topologies they do not model. For the
same honesty: three normative mechanisms in this document are
specified ahead of the reference implementation and are not yet
exercised by it or by conformance vectors -- the operator-signed-
directory assurance downgrade (Section 5.2), delegation records in
approver_key_proofs and the DelegateCannotExceedPrincipal check
(Section 8), and enforcement_class emission (Section 9).
Implementers MUST treat the text as normative and the reference
implementation as incomplete on these three points, not the reverse.
The m-of-n quorum flow IS now modeled: a checked Alloy model (formal/
ep_quorum.als in the repository) proves SelfApprovalImpossible,
NoHumanFillsTwoSlots, NoKeyFillsTwoSlots, TwoPersonRuleHolds, and
ordered-chain acyclicity/linearity against the quorum verifier and
its conformance vectors. The models additionally do not yet cover
the WebAuthn challenge binding, the Approver Directory, log
checkpoints, or the Initiator Attestation (Section 4.2); those
sections are specified, not proven, and extending the models to them
is tracked work.
A separate composed Tamarin model joins signed challenge, CAID, two
distinct user-verification-gated approvals, scoped authority under an
exact pinned registry view, revocation, receipt-issuer pinning, one-
time consumption, and execution in one symbolic trace
[FORMAL-STATUS]. Ten named obligations verify, including
execution_requires_full_composition, initiator_cannot_self_approve,
no_issuer_laundering, strict_registry_view_is_exact, and
injective_execution_with_consumption. Two deliberately unsafe
comparison lemmas are falsified with concrete traces: one omits
consumption and admits same-receipt replay; the other omits exact
registry-view binding and admits a stale or equivocating view. The
one-time property is derived by consuming a linear authorization fact
created once for the registered action instance; it is not imposed by
a trace restriction that assumes uniqueness. The model treats
Schrock Expires 10 February 2027 [Page 36]
Internet-Draft EP Authorization Receipts August 2026
signatures as perfect symbolic primitives and does not prove WebAuthn
internals, parser correctness, amount arithmetic, policy authorship,
clock freshness, transparency-log completeness, collusion resistance,
or downstream exactly-once physical effects.
The quorum abstraction in the standalone symbolic model is a fixed
2-of-2 instance. Its checked result is evidence for that instance,
not a proof of the arbitrary k-of-n construction defined by the
companion EP-QUORUM document and not a proof of production code. CI
regression gating of an existing prover result increases
reproducibility; it does not add a lemma or enlarge the model's
scope.
Independent implementation status, stated precisely: the three
reference verifiers (JavaScript, Python, Go) agree on the published
conformance vectors but live in one repository -- a cross-language
consistency check, not independent implementations. A separately
authored Rust verifier was evaluated on 11 July 2026 and passed 16
suites and 164 vectors from a hash-pinned bundle [EXTERNAL-RUST-PIN].
That result is time-pinned: it does not cover the current larger
vector bundle, and the available construction statement predates the
evaluated hardening commit. It is therefore evidence of external
implementation and execution for that bundle, not yet strict clean-
room construction acceptance for the current specification.
The -11 Authorization Bundle algorithm has one TypeScript/JavaScript
reference verifier and 27 generated cases covering the positive path,
structural malformation, action and audience substitution, actor and
subject confusion, approver-set selection, quorum, cross-ceremony
signoff splicing, separation of duties, policy and status
unavailability, revocation, mapping mismatch, and dynamic-plan
expansion. These are same-repository implementation-profile cases,
not independent or cross-language interoperability. The bundle-to-
grant helper models a compare-and-set transition; it does not supply
the authoritative durable store or prove that a deployment performs
the transition atomically.
13.6. Directory Authority
Section 5 removes the operator from the signature path; Section 5.2
must not readmit it as the authority that decides which keys count.
If the EP operator alone signs the Approver Directory, a malicious
operator can satisfy policy by enrolling a key it controls under a
nominally legitimate approver's name. The controls in Section 5.2
(organization-held directory key; second-party attestation on
enrollment; Class C-equivalent treatment otherwise) exist for this
reason. Auditors SHOULD verify directory key custody as part of any
assessment that relies on receipts.
Schrock Expires 10 February 2027 [Page 37]
Internet-Draft EP Authorization Receipts August 2026
13.7. What Separation of Duties Does and Does Not Provide
SelfApprovalImpossible (Section 7) defeats _unilateral_ self-
approval: no initiator can approve its own action, and m-of-n
approvers are pairwise distinct identities. It does not defeat
collusion among distinct enrolled humans, one human who controls
multiple enrolled identities (an enrollment control -- Section 5.2),
or a coerced approver. Receipts make such events _attributable_ --
named, signed, and evidenced -- which raises the cost of insider
fraud; they do not make it impossible, and implementations MUST NOT
claim otherwise.
13.8. Approver Fatigue
A gate that humans route around protects nothing; rubber-stamping is
the empirical failure mode of every human-in-the-loop control under
volume. This protocol is therefore not a general approval workflow:
deployments MUST scope signoff policies to genuinely high-risk, low-
frequency actions and SHOULD handle volume with policy (thresholds,
allow-lists, velocity rules) rather than human throughput.
Operational countermeasures SHOULD include monitoring time-to-sign
distributions (signing latencies near the floor indicate approval
without review), tracking deny rates (a gate that never denies is
either perfectly upstream-filtered or ceremonial), and consented
render-mismatch drills that measure whether approvers read what they
sign. Such telemetry is deployment guidance, not protocol; but the
protocol's guarantees are only as strong as the attention of the
human at its center, and implementations SHOULD say so to their
customers.
13.9. Initiator Attestation as an Attack Surface
The statement member of an Initiator Attestation (Section 4.2) is
attacker-influenceable free text rendered to a human at the moment of
decision -- a social-engineering surface aimed at the approver,
adjacent to the presentation attacks of Section 13.3. A compromised
or prompt-injected initiator can state any trigger and any reason;
injection can change what the initiator _proposes_, including this
field, but it cannot change what a human _approves_ on their own
hardware, because the device-bound signature (Section 5.1) is outside
the model context. Conforming signing clients MUST therefore render
the statement as untrusted content: plain text only, with no markup,
links, or control characters rendered; the 280-character cap
enforced; and visually distinct styling that labels it as the
initiator's unverified claim, clearly separated from the operator-
rendered Action Object. This is consistent with the rendering-
faithfulness discipline of Section 13.3: the approver's decision
input is the rendered Action Object; the statement is commentary from
Schrock Expires 10 February 2027 [Page 38]
Internet-Draft EP Authorization Receipts August 2026
a party the protocol never trusts. A related residual vector is
divide-and-misinform: because each approver signs their own context,
a malicious orchestrator can show different approvers of an m-of-n
receipt different attestations, and every individual signature
remains valid. The cross-context consistency rule (Section 4.2)
exists for this; verifiers implementing the member MUST flag
violations, but on verifiers that predate the member such a receipt
still verifies -- the rule is a conformance check, not a signature
property.
Privacy: statements written by an agent mid-task can leak sensitive
operational context -- counterparty details, internal findings,
fragments of prompts -- into receipts that are long-lived and
portable by design. Deployments SHOULD prefer escalation_trigger
plus policy_basis identifiers over free text wherever a rule id
captures the reason, SHOULD constrain or template statement
generation for regulated data, and MUST apply the same retention and
disclosure controls to attestation content as to the rest of the
receipt.
Absence is not evidence: a receipt without an attestation means only
that the issuer did not populate it -- not that the initiator judged
the action routine, and not that no escalation reasoning occurred.
Verifiers and auditors MUST NOT infer anything from the absence of an
attestation alone. (Separately, and unchanged: for an action a
policy gates on signoff, the absence of any valid receipt at all
remains evidence that the control was bypassed -- that property comes
from the gate, not from this member.)
No trust feedback: policy engines MUST NOT use initiator_attestation
content to relax thresholds, skip approvers, or raise any trust
score. The initiator must gain nothing by saying the right words;
the attestation is a claim by a party the protocol identifies but
never trusts, not proof of its internal state.
13.10. No symmetric key on the verification trust path
Every artifact a relying party verifies offline -- the approver
signoff (Class A: ES256/P-256), the operator commit and receipt
(Ed25519), the log inclusion proof, and the portable revocation
statement (Ed25519) -- is bound by an ASYMMETRIC signature whose
verifying key the relying party holds independently of the issuer.
No step in offline verification relies on a Message Authentication
Code, a shared secret, or any symmetric primitive. This is
deliberate and load-bearing: a symmetric construction (for example an
HMAC-chained audit log) is verifiable only by a party holding the
same secret as the producer, so it does not provide public
verification outside that trust domain. An asymmetric issuer can
Schrock Expires 10 February 2027 [Page 39]
Internet-Draft EP Authorization Receipts August 2026
still sign conflicting histories; witness cosigning or gossip is
required to detect that equivocation. Conforming verifier
implementations MUST NOT introduce a symmetric primitive on the
verification path; an implementation that does so does not provide
EP's public-verifiability property. (HMAC MAY appear elsewhere in a
deployment -- e.g. authenticating an operator's own cron or webhook
calls -- provided it is never a link in the chain a third party
verifies.)
13.11. Canonicalization Robustness
Every signed EP artifact is verified over its canonical JSON form
(Section 3, Section 4), so any divergence between two
implementations' canonicalization behavior is a signature-
verification divergence and therefore a malleability hazard.
Implementations MUST reject the known malleability hazard classes,
and MUST reject them identically: duplicate object member names
(compared after escape decoding), unpaired UTF-16 surrogate escapes,
and inputs outside the profile's number and depth bounds (non-integer
numbers or integers with magnitude greater than 2^53-1, and container
nesting deeper than the profile-pinned bound of 64). The public EP-
CANONICALIZATION-v1 vector suite exercises these classes as raw JSON
texts, with pinned SHA-256 digests over the canonical bytes of every
accepted input, across the cross-language reference verifiers;
divergence from the pinned results is a conformance defect, not an
implementation choice. (In the reference stack the duplicate-name,
surrogate, and depth gates are applied at the parse boundary by the
conformance runners, since the verifier packages receive already-
parsed values; the profile predicate, canonical serialization, and
digests exercise the verifier packages themselves.)
14. IANA Considerations
IANA is requested to register the following media type in the "Media
Types" registry, following RFC 6838 [RFC6838].
Type name: application
Subtype name: ep-authorization-receipt+json
Required parameters: none
Optional parameters: none
Encoding considerations: binary; the representation is a JSON object
encoded as UTF-8 according to RFC 8259 [RFC8259].
Security considerations: See the Security Considerations section of
Schrock Expires 10 February 2027 [Page 40]
Internet-Draft EP Authorization Receipts August 2026
this document. Receipt verification requires independently
selected log, approver, directory, and policy trust inputs. A
valid receipt is evidence, not current authorization, proof of
execution, or proof of human comprehension. Implementations must
also apply the duplicate-member, Unicode-scalar, depth, and number
restrictions in Section 13.11.
Interoperability considerations: The EP-AUTHORIZATION-RECEIPT-v1
format profile and its offline verification algorithm are defined
by this document. The shorter identifier EP-RECEIPT-v1 names a
different generic envelope and is not an alias.
Published specification: This document.
Applications that use this media type: Agent-action authorization
systems, verifying executors, audit systems, and evidence exchange
services.
Fragment identifier considerations: none.
Additional information: Magic number(s): none. File extension(s):
none. Macintosh file type code(s): none.
Person and email address to contact for further information: Iman
Schrock, team@emiliaprotocol.ai
Intended usage: COMMON
Restrictions on usage: none.
Author: Iman Schrock
Change controller: IETF
IANA is also requested to register the following media type for the
closed pre-execution bundle defined in Section 6:
Type name: application
Subtype name: ep-authorization-bundle+json
Required parameters: none
Optional parameters: none
Encoding considerations: binary; the representation is a JSON object
encoded as UTF-8 according to RFC 8259 [RFC8259].
Schrock Expires 10 February 2027 [Page 41]
Internet-Draft EP Authorization Receipts August 2026
Security considerations: See the Security Considerations and
Section 6.2. A valid bundle is approval evidence, not an
authorization grant, reservation, consumption record, execution
receipt, proof of current external facts, or permission to retry
an action with an uncertain effect.
Interoperability considerations: The EP-AUTHORIZATION-BUNDLE-v1
closed object and verification algorithm are defined by this
document. A consumer must independently pin the audience, policy,
action mapping, approver directory, trust roots, and any required
current status sources.
Published specification: This document.
Applications that use this media type: Authorization servers, policy
decision points, protected resources, verifying executors, and
agent-action approval systems.
Fragment identifier considerations: none.
Additional information: Magic number(s): none. File extension(s):
none. Macintosh file type code(s): none.
Person and email address to contact for further information: Iman
Schrock, team@emiliaprotocol.ai
Intended usage: COMMON
Restrictions on usage: none.
Author: Iman Schrock
Change controller: IETF
The extension-name registry in Section 8.1 remains provisional and
document-local; this revision requests no IANA extension-name
registry.
15. References
15.1. Normative References
[CIBA] OpenID Foundation, "OpenID Connect Client-Initiated
Backchannel Authentication Flow - Core 1.0", September
2021, <https://openid.net/specs/openid-client-initiated-
backchannel-authentication-core-1_0.html>.
Schrock Expires 10 February 2027 [Page 42]
Internet-Draft EP Authorization Receipts August 2026
[EP-CAID] Schrock, I., "The Canonical Action Identifier (CAID)",
Work in Progress, Internet-Draft, draft-schrock-canonical-
action-identifier-02, 9 August 2026,
<https://datatracker.ietf.org/doc/draft-schrock-canonical-
action-identifier/>.
[I-D.thallapelly-oasnt]
Thallapelly, A., "OASNT: Attested Action Authorization
Tokens", Work in Progress, Internet-Draft, draft-
thallapelly-oasnt-01, 24 July 2026,
<https://datatracker.ietf.org/doc/draft-thallapelly-
oasnt/>.
[RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119,
DOI 10.17487/RFC2119, March 1997,
<https://www.rfc-editor.org/info/rfc2119>.
[RFC6838] Freed, N., Klensin, J., and T. Hansen, "Media Type
Specifications and Registration Procedures", BCP 13,
RFC 6838, DOI 10.17487/RFC6838, January 2013,
<https://www.rfc-editor.org/info/rfc6838>.
[RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC
2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174,
May 2017, <https://www.rfc-editor.org/info/rfc8174>.
[RFC8259] Bray, T., Ed., "The JavaScript Object Notation (JSON) Data
Interchange Format", STD 90, RFC 8259,
DOI 10.17487/RFC8259, December 2017,
<https://www.rfc-editor.org/info/rfc8259>.
[RFC8785] Rundgren, A., Jordan, B., and S. Erdtman, "JSON
Canonicalization Scheme (JCS)", RFC 8785,
DOI 10.17487/RFC8785, June 2020,
<https://www.rfc-editor.org/info/rfc8785>.
[WEBAUTHN] W3C, "Web Authentication: An API for accessing Public Key
Credentials, Level 2", April 2021,
<https://www.w3.org/TR/webauthn-2/>.
15.2. Informative References
[AUTHZEN-AARP]
OpenID Foundation, "AuthZEN Access Request and Approval
Profile - Draft 1", July 2026,
<https://openid.github.io/authzen/authzen-access-request-
approval-profile-1_0.html>.
Schrock Expires 10 February 2027 [Page 43]
Internet-Draft EP Authorization Receipts August 2026
[EP-BOUNDED-CAP]
Schrock, I., "Bounded Capability Receipts and Durable
Spend Control for Agent Actions", Work in Progress,
Internet-Draft, draft-schrock-ep-bounded-capability-
receipts-01, 3 August 2026,
<https://datatracker.ietf.org/doc/draft-schrock-ep-
bounded-capability-receipts/>.
[EP-QUORUM]
Schrock, I., "Multi-Party Quorum Authorization for High-
Risk Agent Actions (EP-QUORUM)", Work in Progress,
Internet-Draft, draft-schrock-ep-quorum-03, July 2026,
<https://datatracker.ietf.org/doc/draft-schrock-ep-
quorum/>.
[EXTERNAL-RUST-PIN]
EMILIA Protocol, "Time-Pinned External Rust Verifier
Evaluation Record", 11 July 2026,
<https://github.com/emiliaprotocol/emilia-
protocol/blob/main/conformance/external/rust-cleanroom-
jdieselny.v1.json>.
[FIDO-VI] FIDO Alliance, "Building the Trust Layer for Agentic
Payments with AP2 and Verifiable Intent", 26 May 2026,
<https://fidoalliance.org/building-the-trust-layer-for-
agentic-payments-with-ap2-and-verifiable-intent/>.
[FORMAL-STATUS]
EMILIA Protocol, "EMILIA Formal Proof Status and Scope",
10 July 2026, <https://github.com/emiliaprotocol/emilia-
protocol/blob/main/formal/PROOF_STATUS.md>.
[I-D.klrc-aiagent-auth]
Kasselman, P., Lombardo, J., Rosomakho, Y., Campbell, B.,
Steele, N., and A. Parecki, "AI Agent Authentication and
Authorization", Work in Progress, Internet-Draft, draft-
klrc-aiagent-auth-03, 9 July 2026,
<https://datatracker.ietf.org/doc/draft-klrc-aiagent-
auth/>.
[I-D.nelson-agent-delegation-receipts]
Nelson, R., "Delegation Receipt Protocol for AI Agent
Authorization", Work in Progress, Internet-Draft, draft-
nelson-agent-delegation-receipts-10, 13 June 2026,
<https://datatracker.ietf.org/doc/draft-nelson-agent-
delegation-receipts/>.
Schrock Expires 10 February 2027 [Page 44]
Internet-Draft EP Authorization Receipts August 2026
[I-D.rosomakho-oauth-txn-challenge]
Rosomakho, Y., Campbell, B., McGuinness, K., and P.
Kasselman, "OAuth Transaction Authorization Challenge",
Work in Progress, Internet-Draft, draft-rosomakho-oauth-
txn-challenge-00, 25 June 2026,
<https://datatracker.ietf.org/doc/draft-rosomakho-oauth-
txn-challenge/>.
[RFC9396] Lodderstedt, T., Richer, J., and B. Campbell, "OAuth 2.0
Rich Authorization Requests", RFC 9396,
DOI 10.17487/RFC9396, May 2023,
<https://www.rfc-editor.org/info/rfc9396>.
Appendix A. Acknowledgments
Arun Thallapelly's OASNT analysis identified that a requirement to
show a faithful rendering is not retrospectively verifiable unless
the evidence binds the rendered octets. That observation prompted
the presentation-binding profile and the narrowed claim boundary in
this revision.
The public KLRC discussion of multi-party human approval and the
OAuth Transaction Authorization Challenge discussion of externalized
policy decisions exposed the need to define portable approval
evidence without treating that evidence as either an OAuth grant or a
final PDP verdict. Those discussions shaped the Authorization Bundle
and its transport-neutral native-binding extension point in this
revision.
Appendix B. Changes since -10
* Defined the closed EP-AUTHORIZATION-BUNDLE-v1 pre-execution
object, digest, three-state verification result, and ordered
verification algorithm. Removed the undefined pre-execution
"consumption attestation" language.
* Added the missing relying-party audience member to the signed
Authorization Context, correcting the mismatch between the -10
abstract and its wire example.
* Defined a transport-neutral authorization_binding extension point.
Native profiles independently verify and losslessly map their own
artifacts before comparing the signed binding; this document does
not make the Bundle depend on OAuth, AP2, WIMSE, or another trust
model.
Schrock Expires 10 February 2027 [Page 45]
Internet-Draft EP Authorization Receipts August 2026
* Kept OAuth Transaction Authorization Challenge as informative
related work. Its optional OAuth/RAR projection is implemented as
a separate package profile rather than a normative dependency of
this document.
* Required hostile cases for action substitution, actor/subject and
audience confusion, unbound UI confirmation, stale or unavailable
status and policy, presenter-selected approvers, quorum failure,
mapping failure, replay-layer confusion, dynamic-plan expansion,
and indeterminate provider outcomes. Added one TypeScript/
JavaScript reference verifier and 27 generated implementation-
profile cases while stating the absence of external and cross-
language coverage.
* Requested registration of application/ep-authorization-bundle+json
and corrected the KLRC author citation.
Appendix C. Changes since -09
* Replaced the unverifiable assertion that a base receipt proves a
faithful signing-time rendering with a signing-client requirement
and the optional EP-PRESENTATION-BINDING-v1 verification profile.
Added stable display-unbound, display-mismatch, and display-
untrusted refusals; profiled existing mobile display hashes and
detached display attestations; and defined native-first
composition with OASNT dsp.
* Moved CAID to Normative References and required a relying-party-
pinned CAID mapping whenever the receipt's action is compared
across artifact formats. Missing, lossy, failed, or unpinned
mappings remain indeterminate.
* Named the detailed Section 6 receipt profile EP-AUTHORIZATION-
RECEIPT-v1 and explicitly separated it from the pre-existing
generic EP-RECEIPT-v1 envelope.
* Requested registration of application/ep-authorization-
receipt+json.
Appendix D. Changes since -08
* Changed the intended status from Informational to Standards Track;
the wire format, canonicalization, signature inputs, and
consumption rules are unchanged.
Schrock Expires 10 February 2027 [Page 46]
Internet-Draft EP Authorization Receipts August 2026
* Clarified composition with the authorization-server, human-in-the-
loop, transaction-token, and audit requirements in
[I-D.klrc-aiagent-auth] without treating confirmation evidence as
authorization.
Appendix E. Changes since -07
* Added the separate EP-RECEIPT-EXTENSIONS-v1 companion envelope, a
bind-by-digest procedure, and a provisional extension namespace
and registry design. The base Trust Receipt schema, parser,
canonical bytes, signature inputs, consumption rules, and log-
proof verification remain unchanged; a base verifier never strips
or ignores a new receipt member.
* Defined one common base action, base receipt, operation, and
consequence seam for companion artifacts.
* Added informative, non-exhaustive lifecycle examples including
revocation, outcome binding, action remedy, evidence challenge,
Authorization Evidence Chain composition, Authority Program stage
receipts, and staged DTC settlement binding. No implementation,
deployment, or standards-adoption claim is made for an example
merely because it is named here.
Appendix F. Changes since -06
* Narrowed the abstract and introduction from category-wide novelty
claims to the guarantees of the selected EP verification profile.
* Scoped ConsumeOnce to one conforming shared atomic consumption
domain and stated that offline evidence cannot prove global non-
replay across independent executors.
* Replaced legal non-repudiation language with cryptographic
attribution, tamper evidence, and public verifiability; stated the
issuer-equivocation boundary.
* Added reference entries for the Canonical Action Identifier and EP
Quorum companion documents, previously used as terms of art
without citations, and a grouped companion-family paragraph in
Relationship to Other Work.
* Added the CAID Action-Mapping composition boundary without
changing the EP v1 signature input.
* Added Mastercard Verifiable Intent and AuthZEN AARP as adjacent,
composable work.
Schrock Expires 10 February 2027 [Page 47]
Internet-Draft EP Authorization Receipts August 2026
* Clarified that a receipt can authorize and be consumed for
capability issuance, but cannot be reused as per-operation
approval; the capability protocol binds the full issuance-receipt
digest.
Appendix G. Changes since -04
-05 adds the human-authorization-receipt composition frame for the
SCITT agent-action statement cluster (how a WHO receipt is
referenced, by digest, from capsule/record-style statements); updates
the SCITT citation to RFC 9943; adds the key-custody disambiguation
note in Section 5.1 (key classes classify custody, not assurance
levels); corrects the formal-models status (the m-of-n quorum flow is
now Alloy-checked) and states plainly which three normative
mechanisms the reference implementation does not yet cover.
Appendix H. Changes since -00 (through -04)
This summary covers -00 through -04. Section numbering is stable;
all changes are new subsections or in-place additions.
1. New OPTIONAL Authorization Context member initiator_attestation
(new Section 4.2): a REQUIRED escalation_trigger enum
(irreversibility, magnitude, uncertainty, novelty, authority_gap,
policy_rule), an OPTIONAL policy_basis rule identifier, and an
OPTIONAL length-capped (<= 280 character) statement. The member
is OPTIONAL; it is covered by the context hash via the JCS
canonicalization already normative in Section 4, so the
approver's signature covers the stated reason; receipts carrying
it verify under the existing Section 7.3 verifiers unmodified;
and it is a claim by the initiator -- identified but never
trusted -- not proof of the initiator's internal state. A
terminology entry and a step-2 note in Section 7.3 were added
accordingly.
2. Security Considerations additions (new Section 13.9): the
statement is attacker-influenceable text presented to a human
(prompt-injection -> social-engineering surface); conforming
signing clients MUST render it as untrusted content (no markup,
length cap, distinct styling), consistent with the Section 13.3
rendering-faithfulness caveat. Adds privacy guidance for free-
text statements in long-lived receipts (prefer policy_basis
identifiers), the rule that absence of an attestation is not
evidence of non-escalation, the cross-context consistency
requirement, and the prohibition on using attestation content as
a trust input. The formal-models section now lists the Initiator
Attestation among the not-yet-modeled areas.
Schrock Expires 10 February 2027 [Page 48]
Internet-Draft EP Authorization Receipts August 2026
3. Introduction/terminology clarifications (new text in the
Introduction, new Section 1.2, and a sentence in Section 5.1 and
Section 5.2): makes unmistakable that (a) EP's user-verification-
gated Class-A signoff is native to this draft and does not depend
on any other draft's acquiescence/confirmation mechanism, and (b)
proof of a specific natural-person identity is out of scope --
the Approver Directory trust root is the explicit slot where
identity/key-discovery layers bind keys to named persons.
4. New OPTIONAL Authorization Context member agent_binding (new
Section 4.3): an external agent-identity reference (agent_id) and
an OPTIONAL delegation (scheme, ref, OPTIONAL hash, OPTIONAL
observed_at), plus an OPTIONAL length-capped (<= 280 character)
statement. Like initiator_attestation, it is OPTIONAL, covered
by the context hash via the JCS canonicalization already
normative in Section 4, verifies under the existing Section 7.3
verifiers unmodified, and is a claim -- identified but never
trusted -- not proof of the agent's identity or the delegation's
validity. The OPTIONAL delegation.observed_at records when the
upstream identity/delegation (L4) evidence was observed; a
relying party MAY enforce freshness against it fail-closed,
keeping the receipt agnostic to which external identity scheme
prevails while making a stale or unconstrained upstream claim
detectable after the fact.
5. Housekeeping: version and date bumped in the header; this
appendix added; the idnits non-ASCII em-dash / curly-quote
cleanup from -00 carried forward as a build step.
Author's Address
Iman Schrock
EMILIA Protocol, Inc.
United States of America
Email: team@emiliaprotocol.ai
Schrock Expires 10 February 2027 [Page 49]