| Internet-Draft | EP Authorization Receipts | June 2026 |
| Schrock | Expires 14 December 2026 | [Page] |
This document defines the EMILIA Protocol (EP) authorization receipt, a cryptographic primitive that binds a named, accountable human approver to one exact high-risk action before that action executes. An approver holding their own signing key produces a signature over a canonical Authorization Context containing the action hash, policy reference, one-time nonce, and validity window. The resulting Trust Receipt is Merkle-anchored and verifiable fully offline: a relying party can confirm that a specific action was approved by an authorized human, exactly once, without network access to any EP operator, log, or API. The protocol additionally enforces separation of duties (an initiator must not approve its own action) and one-time consumption (an authorization, once consumed or refused, is terminally unusable). These invariants are machine-checked in published TLA+ and Alloy models.¶
EP addresses organizational authorization of agent actions (approver-to-action trust). It is complementary to, not a replacement for, user-to-operator delegation work (draft-nelson-agent-delegation-receipts), service-to-service identity (WIMSE), and authentication-layer approval (CIBA).¶
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 14 December 2026.¶
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.¶
Agentic AI systems increasingly hold credentials sufficient to perform irreversible operations: releasing payments, modifying beneficiary records, rotating production credentials, deleting data. Existing controls answer the question "is this actor authenticated and authorized in general?" They do not answer the question that matters at the moment of execution: "should this exact action happen, and which accountable human said yes?"¶
Three structural gaps follow:¶
EP closes these gaps with a small protocol: before an irreversible action executes, a named approver signs the exact action with a key only the approver holds; the signed authorization is consumed exactly once; and the resulting receipt is independently verifiable offline, forever.¶
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 10), that composition is by reference, not dependency.¶
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 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.¶
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, nonce, expiry, and chain binding (Section 4).¶
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.1). 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 6).¶
Verifying Executor. A system of record that verifies a Trust Receipt (or a pre-execution Authorization Bundle) before performing the action. See Section 9.¶
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).¶
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.¶
This section is the core upgrade over server-side approval systems.¶
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.¶
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; 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 11.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.¶
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 non-repudiable and equally
terminal.¶
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:¶
approver != initiator; for m-of-n policies, approvers
are pairwise distinct and each distinct from the
initiator.¶
Upon commitment the orchestrator assembles and logs the Trust Receipt:¶
{
"receipt_id": "ep:receipt:01J...",
"action": { "...": "full Action Object" },
"action_hash": "sha256:9f2c...",
"contexts": [ { "...": "Authorization Context 1" } ],
"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": "..." } ]
}
¶
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:¶
issued_at.¶
required_approvals.¶
signed_at and committed_at fall
within [issued_at, expires_at].¶
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 11.4), which is an online activity; the offline guarantee is 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 11.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.1), where present, is covered by the context hash recomputed in step 2 above; no additional verification step is required for it.¶
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
nonce family but a distinct 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.¶
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.¶
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 Authorization Bundle (receipt-less pre-execution form: action object, contexts, signoffs, consumption attestation) before executing, and refuses otherwise. 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.¶
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 11.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 11.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.¶
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).¶
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 whatever
was rendered; cryptography cannot prove the rendering was
faithful. 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 11.8) — not by mathematics. What
the cryptography does guarantee is exactness of evidence: the
receipt contains the full Action Object actually signed, so any
divergence between what was displayed and what was executed is
detectable after the fact with proof rather than testimony.¶
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.¶
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. The models additionally do not yet cover the WebAuthn challenge binding, the Approver Directory, log checkpoints, the m-of-n flow, or the Initiator Attestation (Section 4.1); those sections are specified, not proven, and extending the models to them is tracked work.¶
SelfApprovalImpossible (Section 6) 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.¶
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.¶
The statement member of an Initiator Attestation
(Section 4.1) 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 11.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 11.3: the approver's decision
input is the rendered Action Object; the statement is commentary
from 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.1) 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.¶
This document has no IANA actions. A future version may register
the application/ep-receipt+json media type.¶
This revision is a focused, additive diff over -00. Section numbering is stable; all changes are new subsections or in-place additions.¶
initiator_attestation (new
Section 4.1): 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 6.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 6.3 were added
accordingly.¶
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 11.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.¶