Network Working Group A. Chueayen Internet-Draft Aqta Technologies Limited Intended status: Informational 24 October 2026 Expires: 27 April 2027 Enforcement Attestation Receipts for AI Inference and Agent Action Decisions draft-chueayen-attestation-receipts-04 Abstract This document specifies two compact JSON records, signed with Ed25519 and verifiable offline under a pinned public key. The first is an attestation receipt for an AI inference decision, binding an outcome to a request hash. The second, added in this revision, is an action record: the decision an enforcement point takes before an agent's proposed tool call or other state-changing action runs, whether that decision is to allow or to refuse. An action record is signed by the enforcement point, never by the agent, and binds the decision to a hash of the exact canonical arguments proposed. The document also describes how a human approval can be bound to exact action values with single use and expiry, how either record could be carried as a COSE_Sign1 Signed Statement and registered with a SCITT Transparency Service, and where the current format does not yet do so. Both formats are intended for settings where an operator-controlled log is not, on its own, sufficient evidence of the decision. 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 27 April 2027. Chueayen Expires 27 April 2027 [Page 1] Internet-Draft AI Attestation Receipts October 2026 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. Table of Contents 1. Introduction . . . . . . . . . . . . . . . . . . . . . . . . 3 1.1. Relationship to Other Work . . . . . . . . . . . . . . . 6 1.2. Record Types and Discrimination . . . . . . . . . . . . . 7 1.3. Key Lifecycle . . . . . . . . . . . . . . . . . . . . . . 8 1.4. Non-Goals . . . . . . . . . . . . . . . . . . . . . . . . 8 1.5. Requirements Language . . . . . . . . . . . . . . . . . . 9 1.6. Terminology . . . . . . . . . . . . . . . . . . . . . . . 9 2. Receipt Structure . . . . . . . . . . . . . . . . . . . . . . 9 2.1. Required Fields . . . . . . . . . . . . . . . . . . . . . 10 2.2. Optional Fields . . . . . . . . . . . . . . . . . . . . . 11 2.3. cost_prevented_eur . . . . . . . . . . . . . . . . . . . 12 3. Outcome Values . . . . . . . . . . . . . . . . . . . . . . . 12 4. What a Verified Receipt Proves . . . . . . . . . . . . . . . 12 5. Canonical Payload and Signing . . . . . . . . . . . . . . . . 13 5.1. Signature Suite and Algorithm Agility . . . . . . . . . . 14 5.2. Request Hash . . . . . . . . . . . . . . . . . . . . . . 14 5.3. String Canonicalisation . . . . . . . . . . . . . . . . . 14 5.4. Ordering . . . . . . . . . . . . . . . . . . . . . . . . 14 6. Verification of a Receipt . . . . . . . . . . . . . . . . . . 15 7. Action Records . . . . . . . . . . . . . . . . . . . . . . . 16 7.1. Action Record Fields . . . . . . . . . . . . . . . . . . 16 7.2. Outcome Values . . . . . . . . . . . . . . . . . . . . . 18 7.3. Canonicalisation . . . . . . . . . . . . . . . . . . . . 19 7.4. Assertion Provenance . . . . . . . . . . . . . . . . . . 19 7.5. Verification of an Action Record . . . . . . . . . . . . 21 7.6. What a Verified Action Record Proves . . . . . . . . . . 21 8. Approval Bound to Exact Values . . . . . . . . . . . . . . . 22 8.1. The Gap Between Scope and Value . . . . . . . . . . . . . 22 8.2. Required Properties . . . . . . . . . . . . . . . . . . . 22 8.3. Relationship to the Version-1 Record . . . . . . . . . . 23 9. Transparency and SCITT . . . . . . . . . . . . . . . . . . . 24 9.1. Current Deployment . . . . . . . . . . . . . . . . . . . 24 9.2. COSE_Sign1 Option . . . . . . . . . . . . . . . . . . . . 24 9.3. Registration and Receipts . . . . . . . . . . . . . . . . 26 9.4. Where This Does Not Yet Compose . . . . . . . . . . . . . 26 Chueayen Expires 27 April 2027 [Page 2] Internet-Draft AI Attestation Receipts October 2026 10. Conformance . . . . . . . . . . . . . . . . . . . . . . . . . 26 11. Implementation Status . . . . . . . . . . . . . . . . . . . . 27 11.1. Seal Enforcement Gateway . . . . . . . . . . . . . . . . 27 11.2. aqta-verify-receipt . . . . . . . . . . . . . . . . . . 28 12. Security Considerations . . . . . . . . . . . . . . . . . . . 29 12.1. What a Record Does and Does Not Prove . . . . . . . . . 31 12.2. Issuer Identity . . . . . . . . . . . . . . . . . . . . 31 12.3. The Issuer as Adversary . . . . . . . . . . . . . . . . 31 12.4. Declaration Gaming . . . . . . . . . . . . . . . . . . . 32 12.5. Approver Deception . . . . . . . . . . . . . . . . . . . 32 12.6. Threshold Splitting and Flooding . . . . . . . . . . . . 32 12.7. Replay . . . . . . . . . . . . . . . . . . . . . . . . . 33 12.8. Key Compromise . . . . . . . . . . . . . . . . . . . . . 33 12.9. Confidentiality of Requests and Arguments . . . . . . . 34 12.10. Integrity Versus Correctness . . . . . . . . . . . . . . 34 12.11. Post-Quantum Considerations . . . . . . . . . . . . . . 34 13. Privacy Considerations . . . . . . . . . . . . . . . . . . . 34 14. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 35 15. References . . . . . . . . . . . . . . . . . . . . . . . . . 35 15.1. Normative References . . . . . . . . . . . . . . . . . . 35 15.2. Informative References . . . . . . . . . . . . . . . . . 35 Appendix A. Example Receipt . . . . . . . . . . . . . . . . . . 39 Appendix B. Example Action Record . . . . . . . . . . . . . . . 39 Appendix C. Conformance Vectors . . . . . . . . . . . . . . . . 41 Appendix D. Changes From draft-chueayen-attestation-receipts-03 . . . . . . . . . 41 Appendix E. Changes From draft-chueayen-attestation-receipts-02 . . . . . . . . . 42 Appendix F. Changes From draft-chueayen-attestation-receipts-00 . . . . . . . . . 43 Acknowledgements . . . . . . . . . . . . . . . . . . . . . . . . 43 Author's Address . . . . . . . . . . . . . . . . . . . . . . . . 43 1. Introduction AI systems that take or influence consequential actions are increasingly deployed in regulated settings. When such a decision is later questioned, the party being questioned is frequently also the party that produced the record of the decision. A log an operator controls does not, on its own, let an independent reviewer confirm what was asked or what was decided. This document defines two records that an issuer signs and that any holder of the issuer's public key can verify offline, without contacting the issuer at verification time: * an attestation receipt for an LLM inference decision (Section 2 to Section 6), unchanged on the wire since -00; and Chueayen Expires 27 April 2027 [Page 3] Internet-Draft AI Attestation Receipts October 2026 * an action record for the authorisation decision taken before an agent's proposed action runs (Section 7), new in this revision as a specification, having been described in -03 only as an externally specified sibling. The second record answers a different question from the first. A receipt answers "what did the issuer decide about this model call?". An action record answers "what did the enforcement point decide this agent was allowed to do, with these exact arguments, before it did it?". As agents move from producing text to changing external state, the second is the question a reviewer asks. Chueayen Expires 27 April 2027 [Page 4] Internet-Draft AI Attestation Receipts October 2026 Request | v +-------------------+ | Issuer | | | | SHA-256 over the | | canonical request| | or arguments | | | | | v | | build record | | | | | v | | canonicalise | | | | | v | | sign, Ed25519 | +---------+---------+ | signed record | v +-------------------+ | Verifier | | | | trusted public | | key, obtained | | out of band | | | | | v | | recompute the | | canonical bytes | | | | | v | | verify signature | +---------+---------+ | v VERIFIED Figure 1: Record generation and verification (informative) The figure is informative. The normative processing rules are in Section 5, Section 6, Section 7.3 and Section 7.5. The verifier obtains the public key out of band; the key carried in a record establishes integrity, not the identity of the issuer. Chueayen Expires 27 April 2027 [Page 5] Internet-Draft AI Attestation Receipts October 2026 1.1. Relationship to Other Work Related Internet-Drafts address neighbouring problems. [I-D.marques-asqav-compliance-receipts] profiles signed action receipts for AI agents. [I-D.farley-acta-signed-receipts] defines signed decision receipts for machine-to-machine access control, using RFC 8785 for canonicalisation. [I-D.tsyrulnikov-rats-attested-inference-receipt] profiles COSE and CWT to bind model identity, input and output hashes and platform attestation evidence into one signed artefact for inference inside a trusted execution environment, and answers a question this document explicitly does not, namely what a TEE-resident workload can assert about the environment that executed a particular inference. [I-D.munoz-scitt-permit-profile] specifies a SCITT profile for pre- execution authorisation records with allow, deny and challenge decisions, bound to the canonical bytes of the authorised request, and composes with separate profiles for human-authority binding. [I-D.izmaylov-agent-permission-receipts] specifies a permission a principal signs with a passkey, with machine-checkable limits, and receipts the agent signs for each action. [I-D.sharif-agent-audit-trail] specifies agent audit records with pre-execution recording, recording independence from the acting component, deny reasons, replay protection and external anchoring. [I-D.das-drip-uas-act-finality] distinguishes a broad permission from whether one exact act against one exact destination is authorised to take effect. Two IETF efforts set the context for the action record. [I-D.ietf-wimse-aims] (formerly draft-klrc-aiagent-auth, now a WIMSE working group document) requires that an agent not treat local UI confirmation alone as sufficient authorisation (Section 10), and that audit records of authorisation decisions be tamper-evident (Section 11), without defining a signed decision record. [I-D.kuehlewind-audit-architecture], the architecture draft for the proposed AUDIT working group, defines Action Records produced at the boundary where an action took effect and Authorization Transition Records for changes in permission state, including step-up approvals. It describes its auditing use case as post-hoc and states that using the same records to drive real-time enforcement is out of scope for that document. The action record here is complementary rather than competing: it is produced at the enforcement point before effect, includes refusals as first-class records, and is the natural place to record an approval bound to exact values rather than to a scope. This document would prefer to become a profile of whatever record model that work settles on than to diverge from it. Chueayen Expires 27 April 2027 [Page 6] Internet-Draft AI Attestation Receipts October 2026 The wider literature has moved quickly and this document does not claim the mechanism. [AFR] records agent actions as canonically serialised, hash-chained events with Merkle batching and external anchoring. [NOTARIZED] has the receiving service sign what it observed rather than relying on the caller's account. [EXECGOV] sets out pre-effect authorisation and authorisation-bound execution for agent tool calls, including a receiver-signed effect receipt and replay blocking. [APPROVEWHAT] and [CONSENT] bind human approval to a canonical digest of the exact action and identify rendering as the place approvals still fail. [OVERSIGHT] models approver fatigue under flooding. Taken together, these works establish substantial prior art for agent audit trails, tamper-evident action histories, act-scoped authority, exact-value approval and execution-bound evidence. This document therefore claims no novelty for signed records, audit trails, transparency mechanisms, pre-execution authorisation or approval binding in isolation. What it contributes is narrower and is stated as such: two small payload formats, each with an explicit verification algorithm, a normative statement of which fields the issuer attests and which it merely records, published conformance vectors, and two separately written reference verifiers that are required to return the same verdict on the same bytes. The value claimed is reproducibility by a third party, not novelty of construction. 1.2. Record Types and Discrimination This document defines two record types. Both are signed by the same issuer key family, verified by the same implementations, and canonicalised by the same rules. They are distinguished by the signed v field: the attestation receipt carries the JSON integer 1, and the action record carries the JSON string "action-1". Both record types carry signature and public_key in the same shape, so a verifier that guesses which type it holds from the shape of the object can misclassify one as the other and skip the checks specific to the type it actually received. Selection of the record type MUST therefore be explicit, supplied by the caller, and a verifier MUST reject a record whose v field does not match the type it was asked to verify. A conformant verifier for the attestation receipt MUST reject an action record, and the reverse. The published action record vectors include a correctly signed receipt in their invalid set; the receipt vectors do not yet include the reverse case, which a later vector release should add. Chueayen Expires 27 April 2027 [Page 7] Internet-Draft AI Attestation Receipts October 2026 A third record type in the same family, ACCEPT-v1 [ACCEPT-V1], records a person accepting, overriding or escalating an existing record. It is a draft, is not supported by the published verifiers, and is not specified here. It is mentioned because its binding construction is relevant to Section 8. 1.3. Key Lifecycle This document assumes the verifier already holds a public key it has reason to trust, and does not define how that key is distributed, rotated, revoked, or evaluated for validity at a past point in time. For evidence retained over years these are load-bearing: a key compromised in a later year casts doubt on records nominally issued before it, and the record format alone provides no way to distinguish them. Addressing that requires mechanisms outside the record, such as key transparency, an append-only log of issuance with externally witnessed heads (Section 9), or third-party witnesses. 1.4. Non-Goals This document does not: * Claim that a decision was correct, safe, lawful, or free of model error. * Claim that an allowed action was executed, or executed with the arguments that were authorised. * Define policy language, agent tool protocols, or model evaluation methods. * Define how an approver is authenticated, or verify any identity a caller asserts. * Require a Trusted Execution Environment, hardware root of trust, or qualified timestamp authority. * Define deployment topology, commercial packaging, or product features beyond the record bytes. * Replace platform attestation documents (for example TEE quotes). A record is application-layer evidence of a decision, not hardware evidence of the runtime. A record that verifies proves only what Section 4 and Section 7.6 state. Chueayen Expires 27 April 2027 [Page 8] Internet-Draft AI Attestation Receipts October 2026 1.5. Requirements Language The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "NOT RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in BCP 14 [RFC2119] [RFC8174] when, and only when, they appear in all capitals, as shown here. 1.6. Terminology Issuer: The system that produces and signs a record. For an action record, the issuer is the enforcement point. Enforcement point: The component that evaluates policy over a proposed action and can prevent that action from proceeding. It holds the signing key; the agent does not. Agent: The autonomous or semi-autonomous system whose proposed action is the subject of an action record. The agent is a claimant, not a trusted party. Subject: The organisation, identified by org_id, for which the decision was made. Argument object: The JSON object of arguments with which the agent proposes to invoke a tool or operation. Approval: A decision by a person, distinct from the agent and from the party requesting the action, that a specific proposed action may proceed. Verifier: Any party that checks a record's signature against a public key it trusts for the issuer. Trusted public key: The Ed25519 public key the verifier has obtained out of band for the issuer. It is not sufficient to trust only the public_key field embedded in a record. 2. Receipt Structure A receipt is a single JSON object [RFC8259]. Version 1 defines the required fields in Section 2.1 and the optional fields in Section 2.2. Unless a field is listed in this document for version 1, it MUST NOT appear at the top level. Verifiers MUST reject receipts that contain unknown top-level fields. This closed set keeps independent verifiers simple and prevents silent semantic drift. Chueayen Expires 27 April 2027 [Page 9] Internet-Draft AI Attestation Receipts October 2026 2.1. Required Fields +====================+=========+====================================+ | Field | Type | Description | +====================+=========+====================================+ | v | integer | Format and suite version. | | | | MUST be 1 for this record | | | | type. | +--------------------+---------+------------------------------------+ | attestation_id | string | UUID string [RFC9562], | | | | unique per receipt. | | | | Production issuers SHOULD | | | | use UUID version 4. | +--------------------+---------+------------------------------------+ | trace_id | string | Issuer-assigned identifier | | | | for the LLM call. | +--------------------+---------+------------------------------------+ | org_id | string | Identifier of the subject | | | | organisation. | +--------------------+---------+------------------------------------+ | request_hash | string | SHA-256 [RFC6234] digest of | | | | the canonicalised request | | | | body, 64 lowercase hex | | | | characters. | +--------------------+---------+------------------------------------+ | model | string | Provider-qualified model | | | | identifier. | +--------------------+---------+------------------------------------+ | outcome | string | One of the values in | | | | Section 3. | +--------------------+---------+------------------------------------+ | policy_applied | array | Array of UTF-8 string | | | | policy identifiers, sorted | | | | lexicographically by UTF-16 | | | | code unit (Section 5.4). | | | | MAY be empty. | +--------------------+---------+------------------------------------+ | cost_prevented_eur | number | Non-negative number. MUST | | | | be 0 when not computed. | | | | See Section 2.3. | +--------------------+---------+------------------------------------+ | timestamp | string | [RFC3339] date-time with an | | | | explicit timezone offset. | +--------------------+---------+------------------------------------+ | public_key | string | base64url-encoded raw | | | | 32-byte Ed25519 public key, | | | | no padding. | +--------------------+---------+------------------------------------+ Chueayen Expires 27 April 2027 [Page 10] Internet-Draft AI Attestation Receipts October 2026 | signature | string | base64url-encoded 64-byte | | | | Ed25519 signature, no | | | | padding. Omitted from the | | | | canonical payload. | +--------------------+---------+------------------------------------+ Table 1 2.2. Optional Fields The following fields MAY appear. If present, they MUST match the types below. They are ignored by signature verification except that they participate in the canonical payload when present (see Section 5). +=======================+========+=================================+ | Field | Type | Description | +=======================+========+=================================+ | prev_attestation_id | string | attestation_id of a prior | | | | receipt in an issuer-defined | | | | chain. | +-----------------------+--------+---------------------------------+ | prev_attestation_hash | string | SHA-256 hex digest binding this | | | | receipt to prior receipt bytes, | | | | as defined by the issuer. | +-----------------------+--------+---------------------------------+ | spec_version | string | If present, MUST be the ASCII | | | | string "ATTESTATION-v1". | +-----------------------+--------+---------------------------------+ Table 2 If prev_attestation_id is present, prev_attestation_hash MUST also be present. Verifiers that do not implement chaining MUST still accept well-formed receipts that include these fields, and MUST still enforce the signature and required field checks. Because these fields are optional and issuer-populated, they make a sequence tamper-evident to a party that follows the whole sequence. They do not make an individual receipt tamper-proof, and they do not constrain an issuer that emits unchained receipts or that omits a decision from the chain entirely. Detecting omission requires evidence outside this format. Chueayen Expires 27 April 2027 [Page 11] Internet-Draft AI Attestation Receipts October 2026 2.3. cost_prevented_eur cost_prevented_eur is retained for wire compatibility with existing version-1 issuers. It is an issuer estimate only. It is not part of the security claim of the receipt. New issuers SHOULD emit 0. Verifiers MUST NOT treat a non-zero value as proof of savings, risk reduction, or policy quality. 3. Outcome Values The outcome field of a receipt MUST be one of: ALLOWED: The request was permitted to proceed to the model provider. BLOCKED: The request was not sent to the model provider. SUPPRESSED: The request was not sent because the issuer detected a runaway or loop condition. PASSED: A synonym of ALLOWED retained for backward compatibility. New issuers SHOULD emit ALLOWED. 4. What a Verified Receipt Proves A receipt that verifies under a trusted public key proves that the holder of the corresponding private key attested to the included fields, including outcome, request_hash and the stated timestamp value. It does not prove that the underlying model output was correct, that the policy identifiers were appropriate, or that the issuer's process was fair. The request_hash is a commitment, not a disclosure. It does not reveal the request, and it does not on its own establish that any particular request was the one presented to the issuer. It lets a verifier that already holds a candidate request test whether that candidate matches the commitment. What was decided is established by the signed outcome field, not by the hash. See Section 12 for the case where the request is low-entropy enough to be recovered by hashing candidates. The receipt does not independently establish when the attestation was made. The timestamp is a field chosen by the issuer and covered by the signature, so a verifying receipt shows that the issuer signed that value, not that signing occurred at that time. Establishing when a receipt existed requires evidence outside this format, such as inclusion in an append-only log observed by a third party, or a timestamp from an authority this document does not define. Chueayen Expires 27 April 2027 [Page 12] Internet-Draft AI Attestation Receipts October 2026 5. Canonical Payload and Signing The canonical payload is produced by: 1. Rejecting the record if the JSON object contains duplicate member names at any level, or if any input byte sequence is not well- formed UTF-8. A verifier MUST decode strictly: it MUST NOT substitute U+FFFD REPLACEMENT CHARACTER for an ill-formed sequence, because a lossy decode turns bytes that were never signed into a payload that verifies. [RFC8259] notes that implementations disagree over which value wins when names repeat, so a record containing them has no single canonical payload and MUST NOT be treated as verifiable. 2. Removing the signature field, if present. 3. Serialising the remaining fields to JSON with all object keys sorted lexicographically by UTF-16 code unit as specified in [RFC8785] Section 3.2.3, and no whitespace between tokens. See Section 5.4: "lexicographic" without a named encoding is not sufficient to make two implementations agree. 4. Encoding the result as UTF-8, with non-ASCII characters emitted literally as UTF-8 and never as \uXXXX escapes (see Section 5.3). 5. Serialising every integer-valued number, including a float such as 1.0, as an integer with no decimal point or trailing zero, and every other number as the shortest decimal representation that round-trips to the same IEEE 754 binary64 value. A number whose shortest representation requires exponential notation, meaning a magnitude below 1e-4 or at or above 1e21, is outside the range that common implementations serialise identically. An issuer MUST NOT sign such a value directly; where one would arise it MUST first be rounded into the safe range (for cost_prevented_eur, to two decimal places). Within that permitted range the rule above is the rule of [RFC8785] Section 3.2.2.3, which is the ECMA-262 Number::toString algorithm: both produce the shortest decimal that round-trips to the same binary64 value. This format differs from RFC 8785 only in forbidding the values RFC 8785 would serialise in exponential notation, rather than in how any permitted value is written. These rules apply to both record types. The action record contains no numbers, so step 4 never applies to it; it does apply to the argument object hashed into an action record (Section 7.3). Chueayen Expires 27 April 2027 [Page 13] Internet-Draft AI Attestation Receipts October 2026 5.1. Signature Suite and Algorithm Agility The version field v identifies the complete cryptographic suite, not only the field layout. For both record types defined here (v equal to the integer 1 and v equal to the string "action-1") the suite is Ed25519 [RFC8032] over the canonical payload. The issuer signs the canonical payload bytes and places the base64url-encoded signature, without padding, in the signature field. A verifier MUST select the signature algorithm from v and MUST NOT infer it from the length or contents of the signature field. A future version MAY define a post-quantum suite. A verifier that does not implement the suite named by v MUST reject the record rather than guess. 5.2. Request Hash The request_hash field is the SHA-256 digest [RFC6234], encoded as 64 lowercase hexadecimal characters, of the request body serialised by applying the same canonicalisation algorithm defined in Section 5 to the request JSON, including its number rule. The algorithm is identical; only the input differs. Request bodies often carry non- integer sampling parameters such as temperature or top_p, so an issuer whose requests can contain numbers in the exponential range SHOULD round them before hashing. The digest is computed over the request body as received from the caller, before any redaction, so that a verifier holding the original request can reproduce it. A verifier that does not hold the original request treats request_hash as an opaque commitment. 5.3. String Canonicalisation Strings MUST be serialised as literal UTF-8. Escaping non-ASCII characters as \uXXXX produces different canonical bytes and MUST NOT be done; only the escapes required by [RFC8259] are permitted. Mainstream JSON serialisers disagree by default on this point. Issuers and verifiers MUST both emit literal UTF-8. 5.4. Ordering Wherever this document requires strings to be in lexicographic order, whether object keys under Section 5 or the members of policy_applied, the comparison MUST be by UTF-16 code unit, as [RFC8785] Section 3.2.3 specifies for object keys. Implementations MUST NOT compare by Unicode code point or by locale. Chueayen Expires 27 April 2027 [Page 14] Internet-Draft AI Attestation Receipts October 2026 The two orderings agree across the whole Basic Multilingual Plane and diverge only when a character outside it is present, because such a character is represented in UTF-16 by a surrogate pair whose leading unit is numerically lower than U+E000. U+E000 therefore sorts after U+1F600 by code unit and before it by code point. This is stated normatively because the ambiguity has already produced a real divergence. Two independently written reference verifiers for this format, one in TypeScript and one in Python, disagreed on signed receipts carrying a non-Basic-Multilingual-Plane policy identifier: the first used its language's native string comparison, which is by UTF-16 code unit, and the second used its language's native comparison, which is by code point. A conformance suite containing only ASCII policy identifiers could not distinguish them. 6. Verification of a Receipt A verifier that holds a trusted public key for the issuer, and has been asked by its caller to verify an attestation receipt: 1. Confirms all required fields are present and well-typed for Section 2.1, including: request_hash is 64 lowercase hex characters; public_key and signature decode as unpadded base64url to 32 and 64 bytes respectively; cost_prevented_eur is a non- negative number; timestamp is an RFC 3339 date-time with an explicit timezone offset; and policy_applied is an array of strings in lexicographic order by UTF-16 code unit (Section 5.4). 2. Confirms no unknown top-level fields exist. 3. Confirms optional fields, if present, satisfy Section 2.2. 4. Confirms outcome is one of the values in Section 3. 5. Confirms the embedded public_key equals the trusted public key. 6. Reconstructs the canonical payload per Section 5. 7. Verifies the signature over the canonical bytes using the suite named by v and the trusted public key. Verifying only against the embedded public_key, without an out-of- band trust decision, proves integrity of the object but not issuer identity. Every format rule in this document matches the whole value, and digits are the ASCII digits 0 to 9. A value with anything before or after the pattern, including a trailing line feed, or with a decimal Chueayen Expires 27 April 2027 [Page 15] Internet-Draft AI Attestation Receipts October 2026 digit from another script, does not conform. Regular expression engines differ on both points by default, so an implementation that relies on its engine's defaults can accept a value that another implementation rejects. The published vectors pin both cases. 7. Action Records An action record is the signed record of an authorisation decision taken by an enforcement point when an agent proposes an action: a tool call, a workflow step, or any operation that changes external state. The record is produced before the action runs, and is produced whether the decision is to allow the action or to refuse it. Three properties define the record and distinguish it from an after- the-fact log entry: * It is signed by the enforcement point. The agent never holds the signing key. The agent is the party whose behaviour is under review and may be acting on injected instructions; a record signed with a key the agent holds is the agent's own account of itself. The signing key MUST NOT be accessible to the agent or to any process the agent controls. * A refusal is a first-class record. A BLOCKED record is signed and logged in the same way as an ALLOWED record, so a reviewer can see decisions to stop alongside decisions to proceed. * It binds the decision to the exact proposed arguments, by a hash over their canonical serialisation, so that a different argument object is a different action. The format is specified in [ACTION-V1], frozen at version 1.0 on 22 August 2026, and is reproduced here so that it can be reviewed in one place. If this section and that specification disagree, the disagreement is a defect to be corrected in whichever is wrong; neither silently prevails. 7.1. Action Record Fields An action record is a single JSON object with exactly the following top-level fields. All are required. +================+========+========================================+ | Field | Type | Description | +================+========+========================================+ | v | string | MUST be the exact string "action-1". | +----------------+--------+----------------------------------------+ | action_id | string | UUID version 4 [RFC9562], unique per | Chueayen Expires 27 April 2027 [Page 16] Internet-Draft AI Attestation Receipts October 2026 | | | record. | +----------------+--------+----------------------------------------+ | org_id | string | Identifier of the subject | | | | organisation. | +----------------+--------+----------------------------------------+ | session_id | string | Issuer-assigned identifier of the | | | | agent session in which the action was | | | | proposed. MUST be "" when the action | | | | was proposed outside a session. | +----------------+--------+----------------------------------------+ | intent_hash | string | SHA-256 hex digest of the session's | | | | registered intent text, UTF-8 encoded. | | | | MUST be "" when the session has no | | | | registered intent or session_id is "". | +----------------+--------+----------------------------------------+ | agent | string | Caller-asserted identity of the | | | | proposing agent, for example "claude- | | | | code/2.1". Recorded, not verified | | | | (Section 7.4). MAY be "". | +----------------+--------+----------------------------------------+ | tool | string | Namespaced identifier of the proposed | | | | action, for example | | | | "github.merge_pull_request". Non- | | | | empty. | +----------------+--------+----------------------------------------+ | args_hash | string | SHA-256 hex digest of the canonical | | | | serialisation of the argument object | | | | (Section 7.3). | +----------------+--------+----------------------------------------+ | outcome | string | "ALLOWED" or "BLOCKED" (Section 7.2). | +----------------+--------+----------------------------------------+ | policy_applied | array | Policy identifier strings, sorted by | | | | UTF-16 code unit (Section 5.4). MAY | | | | be empty. | +----------------+--------+----------------------------------------+ | timestamp | string | [RFC3339] date-time with an explicit | | | | timezone offset. | +----------------+--------+----------------------------------------+ | public_key | string | base64url-encoded raw 32-byte Ed25519 | | | | public key of the issuer, no padding. | +----------------+--------+----------------------------------------+ | signature | string | base64url-encoded 64-byte Ed25519 | | | | signature, no padding. Omitted from | | | | the canonical payload. | +----------------+--------+----------------------------------------+ Table 3 Chueayen Expires 27 April 2027 [Page 17] Internet-Draft AI Attestation Receipts October 2026 Every hex digest is 64 lowercase hexadecimal characters. Records MUST NOT contain any other top-level field, and verifiers MUST reject records that do. Every field is a string or an array of strings. This is deliberate: the cross-language canonicalisation divergences observed in practice for the receipt format arose from number serialisation, and a record with no numbers has no such divergence class. Three things a reader might expect are absent from version 1, and their absence is part of what a version-1 record means: * There is no key identifier field. The issuing key is identified by the public_key field itself, compared byte for byte against the pinned key. The deployment described in Section 11 publishes a key identifier at its key endpoint, outside the record. The COSE option in Section 9.2 would carry a kid header parameter. * There is no approval field. A version-1 record carries the effect of an approval (its outcome, and the identifier of the rule that required the approval in policy_applied) but no reference to the approval itself. See Section 8. * There is no execution result. See Section 7.6. 7.2. Outcome Values The outcome field of an action record MUST be one of: ALLOWED: Every applicable policy permitted the proposed action. BLOCKED: At least one policy refused the proposed action before execution. There is no SUPPRESSED and no execution-result outcome for this record type. An enforcement point that encounters an error while deciding, including unreadable policy, SHOULD record the decision as BLOCKED rather than issue no record. An enforcement point MUST NOT let an action proceed on the basis of an ALLOWED decision for which it has not produced and durably stored a signed record. Without that rule, the set of ALLOWED records would be a sample of permitted actions rather than a record of them. Chueayen Expires 27 April 2027 [Page 18] Internet-Draft AI Attestation Receipts October 2026 7.3. Canonicalisation The canonical payload of an action record is produced by the rules of Section 5. Because the record contains no numbers, the number rule never applies to the record itself. The args_hash field is the SHA-256 digest of the argument object serialised by the same rules of Section 5, including the number rule, since argument objects commonly carry numbers. The issuer MUST hash the canonical serialisation and MUST NOT hash the raw request bytes it received: two issuers given the same argument object MUST produce the same args_hash, and a party holding the argument object MUST be able to reproduce it. Object keys inside the argument object are ordered by UTF-16 code unit (Section 5.4), at every depth. The intent_hash field is the SHA-256 digest of the registered intent text, encoded as UTF-8, with no further canonicalisation. 7.4. Assertion Provenance Not every field in a signed record is evidence of the same kind. The signature proves that the issuer produced these exact bytes; it does not upgrade a claim the issuer could not check into a fact. Verifiers and downstream consumers MUST interpret fields according to the following table, and MUST take the distinction from this table rather than from the presence of a valid signature. Chueayen Expires 27 April 2027 [Page 19] Internet-Draft AI Attestation Receipts October 2026 +================+==================+============================+ | Field | Provenance | What the signature | | | | establishes | +================+==================+============================+ | outcome, | Issuer-attested | The issuer evaluated these | | policy_applied | | policies over the proposed | | | | action and reached this | | | | outcome. | +----------------+------------------+----------------------------+ | timestamp | Issuer-attested, | The issuer's clock read | | | issuer clock | this value. Freshness | | | | requires an external time | | | | reference. | +----------------+------------------+----------------------------+ | org_id, | Issuer-assigned | Identifiers the issuer | | session_id, | | controls and binds to the | | action_id | | decision. | +----------------+------------------+----------------------------+ | intent_hash | Issuer-attested | The session carried a | | | binding | registered intent with | | | | this digest at decision | | | | time. Not that the action | | | | served that intent. | +----------------+------------------+----------------------------+ | tool, | Caller-declared, | The caller declared this | | args_hash | issuer-observed | action with these | | | | arguments, and the issuer | | | | evaluated policy against | | | | exactly this declaration. | +----------------+------------------+----------------------------+ | agent | Caller-asserted, | The caller claimed this | | | recorded only | identity. The issuer does | | | | not verify it. | +----------------+------------------+----------------------------+ Table 4 An issuer MUST NOT populate agent from any source it wishes to present as verified identity. If verified client identity is later supported, it will be a new field with its own provenance row, not a reinterpretation of this one. When the issuer also executes the action (the enforcement point holds the credential the action needs), the declaration and the execution target coincide. When the issuer only authorises, the caller could execute something else. A version-1 record does not distinguish the two deployments. Chueayen Expires 27 April 2027 [Page 20] Internet-Draft AI Attestation Receipts October 2026 7.5. Verification of an Action Record A verifier performing action record verification MUST: 1. Have been explicitly invoked for this record type by its caller. A verifier MUST NOT select a record type by inspecting the input's fields (Section 1.2). 2. Hold a trusted public key for the issuer, obtained out of band. 3. Confirm the record's public_key equals the trusted key byte for byte. 4. Confirm the fields of Section 7.1 are present, well-typed and well-formed, and that no other top-level field is present: v is "action-1"; outcome is ALLOWED or BLOCKED; args_hash is a hex digest; intent_hash is "" or a hex digest, and is "" whenever session_id is ""; tool is non-empty; policy_applied contains only strings in UTF-16 code unit order; timestamp is an RFC 3339 date- time with an explicit offset; and signature decodes as unpadded base64url to 64 bytes. 5. Compute the canonical payload bytes (Section 7.3). 6. Verify the Ed25519 signature over those bytes with the trusted key. 7. Reject on any failure. An integrity-only mode that verifies against the embedded key without a pinned key MAY be offered. It MUST NOT be the default, and its result MUST be labelled as not establishing the issuer. A verifier that also holds the argument object SHOULD offer to recompute args_hash and report the result separately from the signature result. A valid signature over an args_hash that does not match the arguments in hand, and an invalid signature, are different failures with different meanings. 7.6. What a Verified Action Record Proves A valid action record, verified under a pinned key, proves that the holder of that key signed this decision about this declared action, with this argument hash, under these policies, with this timestamp value. Read with Section 7.4, it proves no more than that. It does not prove: Chueayen Expires 27 April 2027 [Page 21] Internet-Draft AI Attestation Receipts October 2026 * that an ALLOWED action was executed, or executed with the arguments that were authorised, or executed only once; * that a BLOCKED action did not run by some route that bypassed the enforcement point; * that the decision was correct, or that the policies were appropriate; * that the agent was who it claimed to be; * that signing happened at the stated time; or * that no other decision went unrecorded. Reconciling what was authorised with what executed requires evidence from outside the issuer, such as a record signed by the receiving service over the same canonical action digest [NOTARIZED]. This document does not define one. 8. Approval Bound to Exact Values This section describes the properties an approval needs for an action record to be read as evidence that a person approved a specific action, and how those properties relate to the version-1 record. Its requirements apply to an enforcement point that makes approval-gated decisions and records them in action records. It does not define an approval record format, nothing in it is checkable by a verifier holding only a version-1 record, and no published verifier for this document implements an approval check. 8.1. The Gap Between Scope and Value An approval of a scope ("this agent may make payments") and an approval of an action ("this agent may pay 4,200.00 EUR to this account for this invoice") are different decisions. The first is what token step-up and the Authorization Transition Record of [I-D.kuehlewind-audit-architecture] capture. The second is what a reviewer of a consequential action usually needs, and what [I-D.ietf-wimse-aims] leaves open for mid-execution confirmation. A scope-level approval followed by a value the approver never saw is the failure that exact-value binding exists to prevent. 8.2. Required Properties An approval mechanism whose effect is recorded in action records SHOULD have all of the following properties. Each is checked by the enforcement point at decision time, not by the agent. Chueayen Expires 27 April 2027 [Page 22] Internet-Draft AI Attestation Receipts October 2026 Binding to exact values: The approval commits to the same digest the enforcement point computes for the proposed action: at least org_id, tool and args_hash as defined in Section 7.3, together with an identifier of the policy version that required the approval. A proposed action whose argument object differs in any member has a different args_hash and MUST NOT be allowed under the approval. Binding to a subset of arguments ("amount and payee only") leaves the remaining arguments unapproved and SHOULD be avoided; where a policy binds only a subset, the approver must be told which arguments are not covered. Single use: An approval is consumed by the first ALLOWED decision made under it. The consumption MUST be atomic with that decision, so that two concurrent proposals cannot both be allowed under one approval. A later proposal citing a consumed approval MUST be refused, and the refusal recorded as BLOCKED. Expiry: An approval carries an expiry, evaluated against the enforcement point's clock at decision time. An expired approval MUST NOT allow an action. The expiry SHOULD be short, measured in minutes rather than days. Policy version: An approval made under one version of a policy MUST NOT allow an action under a changed version of that policy. Independence: The approver MUST NOT be the agent, and SHOULD NOT be the party that requested the action. An agent that can approve its own action has not been approved. Rendering from the canonical action: What the approver is shown MUST be derived by the enforcement point, or a component it trusts, from the canonical argument object whose hash it will check. It MUST NOT include text supplied by the agent as a description of the action. See Section 12.5. How the approver is authenticated, and with what credential, is a deployment matter outside this document. The record does not establish it. 8.3. Relationship to the Version-1 Record A version-1 action record shows the effect of an approval: an ALLOWED outcome under a policy whose identifier appears in policy_applied and which required approval, or a BLOCKED outcome where approval was missing, consumed, expired or did not match. It does not identify the approval, so a verifier holding only the record cannot tell which approval was used or check its binding. Chueayen Expires 27 April 2027 [Page 23] Internet-Draft AI Attestation Receipts October 2026 Closing that gap needs two things this document does not yet define: a signed approval record whose canonical bytes include the binding of the previous subsection, and a field in a future version of the action record carrying the SHA-256 digest of those canonical bytes. Binding by digest rather than by identifier follows the construction of ACCEPT-v1 [ACCEPT-V1], whose subject_hash field commits to the exact signed bytes of the record being responded to, so that a holder of both records can recompute the digest and confirm that the one responded to is the one in hand. ACCEPT-v1 records a different event (a person accepting, overriding or escalating an existing record, after the fact), and is cited only for that construction. A later revision may specify both, and would do so only alongside a published implementation and conformance vectors. Review of the properties above is welcome before then, in particular from participants in the AUDIT and SCITT work, since an approval record is a natural candidate for whatever record model that work adopts. 9. Transparency and SCITT 9.1. Current Deployment The deployment described in Section 11 enters every receipt and every action record, refusals included, as a leaf of one append-only Merkle log using the Merkle Tree Hash of [RFC9162], Section 2.1.1, which is unchanged from its predecessor: a leaf hash is SHA-256(0x00 || entry) and an interior node is SHA-256(0x01 || left || right). The entry encoding prefixes a one-byte record-type tag; it is published with the log's signed tree head and is not specified by this document. Signed tree heads, inclusion proofs and consistency proofs are served without authentication, and the published verifiers check all three offline. The log lets a reviewer who pinned an earlier tree head detect a log that has been rewritten, reordered or forked, and lets a holder of a record confirm that it was logged. It does not show that every decision produced a record. The log is operated by the issuer, and its tree heads are signed with the issuer's key. 9.2. COSE_Sign1 Option This subsection is informative and describes an envelope no published implementation produces. JSON with Ed25519 over the canonical payload remains the format of this document. Chueayen Expires 27 April 2027 [Page 24] Internet-Draft AI Attestation Receipts October 2026 [RFC9943] requires a Signed Statement to be a COSE_Sign1 message [RFC9052] whose protected header carries the CWT Claims header parameter [RFC9597] with Issuer and Subject claims, and a kid when no X.509 header is present. A record defined here could be carried as follows: * payload: the canonical payload bytes of the record exactly as defined in Section 5 or Section 7.3, that is, the bytes the JSON signature covers; * protected header, alg (1): Ed25519 (-19) as defined in [RFC9864], or EdDSA (-8) where a Transparency Service does not yet accept -19; * protected header, content type (3): "application/json", until a media type is registered; * protected header, kid (4): an identifier of the issuer key, resolvable to the same key that appears in the record's public_key field; * protected header, CWT Claims (15): iss (1) identifying the issuer, and sub (2) identifying the subject. A natural sub for an action record is "urn:uuid:" followed by its action_id, and for a receipt the attestation_id; this choice is open for review. 18( / COSE_Sign1 / [ << { 1: -19, / alg: Ed25519 (RFC 9864) / 3: "application/json", / content type / 4: h'...', / kid / 15: { / CWT Claims (RFC 9597) / 1: "https://issuer.example", / iss / 2: "urn:uuid:7c2e4a91-3b58-4f0d-9a67-12de89f04c3b" / sub / } } >>, {}, / unprotected: empty / h'7b22...7d', / canonical payload bytes / h'...' / signature over Sig_structure/ ] ) Figure 2: Illustrative COSE_Sign1 carriage of an action record (informative, not produced by any implementation) Chueayen Expires 27 April 2027 [Page 25] Internet-Draft AI Attestation Receipts October 2026 Two consequences need stating. First, a COSE signature is computed over the COSE Sig_structure, not over the payload bytes alone, so the existing JSON signature cannot be moved into the envelope: the envelope is a second signature by the issuer over the same payload. A verifier holding both forms can confirm they describe the same record by comparing the payload bytes. Second, the JSON record's public_key field remains inside the payload; the trust decision is still made against a key obtained out of band and not against either embedded identifier. 9.3. Registration and Receipts A record so enveloped could be registered as a Signed Statement with a SCITT Transparency Service under [RFC9943]. The Transparency Service would return a Receipt as defined in [RFC9942], for example using the RFC9162_SHA256 verifiable data structure, whose inclusion proof a verifier checks against a signed tree head of that service. Attaching that Receipt in the unprotected header produces a Transparent Statement, which gives a relying party what the issuer- operated log cannot: evidence of registration from a party other than the issuer. 9.4. Where This Does Not Yet Compose As of this revision, and stated so that no reader infers otherwise: * No implementation emits the COSE_Sign1 envelope above. A record defined in this document is not a SCITT Signed Statement and is not SCITT-conformant. * The deployment's log uses the same Merkle tree hashing as [RFC9162], but its signed tree heads and proofs are JSON objects in a deployment-specific form, not RFC 9942 Receipts, and its leaves are not Signed Statements. * No record has been registered with a SCITT Transparency Service. * The word "receipt" in this document's title means an issuer's signature over a decision. In [RFC9943] a Receipt is proof of registration in a Transparency Service. Where the distinction matters, this document says "record" for the former and "Receipt" for the latter. 10. Conformance An implementation claiming conformance to this document for a record type MUST: Chueayen Expires 27 April 2027 [Page 26] Internet-Draft AI Attestation Receipts October 2026 * Produce or accept records matching Section 2 for receipts, or Section 7.1 for action records. * Implement canonicalisation and verification as specified in Section 5 and Section 6, or Section 7.3 and Section 7.5. * Require explicit selection of the record type (Section 1.2). * Reject the invalid cases described by the published conformance vectors referenced in Appendix C. The conformance vectors are informative interoperability artefacts. If a vector and this document disagree, this document prevails and the vector set SHOULD be corrected. 11. Implementation Status Note to the RFC Editor: please remove this section before publication. This section records the status of known implementations of the formats defined by this specification at the time of posting of this Internet-Draft, and is based on a proposal described in [RFC7942]. The description of implementations in this section is intended to assist the IETF in its decision processes in progressing drafts to RFCs. Please note that the listing of any individual implementation here does not imply endorsement by the IETF. Furthermore, no effort has been spent to verify the information presented here that was supplied by IETF contributors. This is not intended as, and must not be construed to be, a catalog of available implementations or their features. Readers are advised to note that other implementations may exist. All implementations listed are the author's organisation's own. No independent implementation is known to the author. 11.1. Seal Enforcement Gateway Organisation: Aqta Technologies Limited. Description: An enforcement gateway that signs a receipt for each model call it evaluates and an action record for each proposed agent action submitted to it, with ALLOWED and BLOCKED outcomes both signed. A decision error is recorded as BLOCKED, and no ALLOWED decision is returned without a signed, stored record. Arguments are hashed and not stored in the record. The issuer public key is published at https://api.aqta.ai/v1/attestation/ public-key. Chueayen Expires 27 April 2027 [Page 27] Internet-Draft AI Attestation Receipts October 2026 Transparency: Every receipt and action record is entered in the public log described in Section 9. The signed tree head, inclusion proofs and consistency proofs are served at https://api.aqta.ai/v1/public/transparency/ without an account. At 2026-10-24T00:14:18Z the published head reported a tree size of 1571. A public repository (https://github.com/Aqta-ai/seal-log- witness) checks each head hourly for consistency with the previous one and countersigns it with Sigstore keyless signing, so the heads are recorded in the public Rekor log. That witness is operated by the author's organisation and is therefore not independent of the issuer. Since 22 October 2026 the gateway also issues signed checkpoint statements hourly over the log; these are described in draft companion specifications in the attestation- spec repository and are not specified by this document. Coverage: Both record types of this document. Not covered: the COSE_Sign1 option of Section 9.2, registration with a SCITT Transparency Service, and any approval record of Section 8. Maturity: In production use by the author's organisation: receipts since April 2026, action records since August 2026. Licensing: Proprietary. Contact: hello@aqta.ai 11.2. aqta-verify-receipt Organisation: Aqta Technologies Limited. Description: Two offline verifiers, one in TypeScript published on the npm registry and one in Python published on the Python Package Index, both as aqta-verify-receipt. They were written separately rather than translated, and a cross-implementation sweep requires them to return the same verdict on every conformance vector. Both require a pinned key by default. A second command, aqta-verify- proof, verifies inclusion proofs, consistency proofs and signed tree heads for the log in Section 9. Version: 1.4.0 on both registries, published 23 October 2026. Coverage: Receipts, and action records when the caller selects that Chueayen Expires 27 April 2027 [Page 28] Internet-Draft AI Attestation Receipts October 2026 record type explicitly. Versions 1.3.0 and 1.4.0 add opt-in profiles (chain, complete, witnessed) for draft companion record types that this document does not specify. On 24 October 2026 the author ran both published 1.4.0 packages over the action record vectors (11 valid, 23 invalid) with the vector key pinned and the action record profile selected explicitly; both returned the expected verdict on all 34. ACCEPT-v1 is not supported. Licensing: Apache-2.0. Source at https://github.com/Aqta-ai/ attestation-spec, which also carries the specifications (CC-BY- 4.0), reference issuers in Python, and the conformance vectors. Contact: hello@aqta.ai 12. Security Considerations The trust boundary these formats establish, and the questions they leave open, are summarised below. The figure is informative. Chueayen Expires 27 April 2027 [Page 29] Internet-Draft AI Attestation Receipts October 2026 +-------------------------+ | Issuer (enforcement | Proposal ------>| point for actions) | | creates the record | | chooses the timestamp | | holds the signing key | +------------+------------+ | signed record | v +-------------------------+ | Verifier | | holds a trusted key | | recomputes the payload | | checks the signature | +------------+------------+ | v the signed fields are authentic and have not been altered NOT ESTABLISHED BY THE RECORD ALONE +-------------------------------------------------------+ | when the record existed -> append-only log, | | witness, or a | | timestamp authority| | that an allowed action ran, -> evidence from the | | ran once, or ran as approved receiving service | | that the claimed model ran -> platform | | attestation | | that no decision was omitted -> reconciliation | | against a record | | the issuer does | | not produce | | that the decision was correct -> outside any | | evidence format | | that a later key compromise -> key transparency, | | does not undermine old revocation, or | | records historical status | +-------------------------------------------------------+ Figure 3: Trust boundary of a verified record (informative) Chueayen Expires 27 April 2027 [Page 30] Internet-Draft AI Attestation Receipts October 2026 12.1. What a Record Does and Does Not Prove A valid record proves that the issuer signed this decision with this timestamp value. It does not prove that the decision was taken at that time, that an allowed action executed as recorded, that it executed at all, or that the decision was correct. Section 4 and Section 7.6 state this field by field. Consumers MUST NOT present a valid record as evidence of more. 12.2. Issuer Identity A record proves that the holder of a private key signed the stated fields. It does not, on its own, prove which organisation that key represents. Verifiers MUST pin the issuer's public key out of band (for example via a published key URL, an enterprise configuration, or a trust list). 12.3. The Issuer as Adversary Every invalid conformance vector models a third party altering a record after signing. A dishonest issuer needs to do none of that: it holds the key and can produce well-formed, correctly signed records that misrepresent what happened. [ISSUER-ADVERSARY] names six classes: equivocation (two different records of one decision shown to different parties), omission (a decision with no record), backdating, retrospective reordering, silent key substitution, and selective disclosure of a consistent subset. Verification of a single record cannot detect any of them, because each is a property of a sequence or of an absence. An append-only log with consistency proofs and externally retained tree heads detects equivocation, reordering and selective disclosure; pinning a published key with an effective date detects key substitution; anchoring narrows backdating. Omission is not detected by any mechanism in this document. An issuer that never writes a record leaves no cryptographic trace of not having written it, and an enforcement point can refuse an action without recording the refusal. Moving the signer from the agent to the enforcement point moves the trust question to the operator of the enforcement point; it does not remove it. The AUDIT architecture likewise states that it does not solve the case of a service that refuses to record what happened at its boundary [I-D.kuehlewind-audit-architecture]. Chueayen Expires 27 April 2027 [Page 31] Internet-Draft AI Attestation Receipts October 2026 12.4. Declaration Gaming Where the enforcement point authorises but does not execute, a malicious caller can declare one action and execute another. The record still proves what was authorised, which is what the issuer can attest. Consumers MUST NOT read an ALLOWED record as proof of what subsequently ran. Deployments that need the stronger property should place the credential the action requires behind the enforcement point, so that the declared action is the only one it can carry out. 12.5. Approver Deception When an approval is involved, the attack moves from the policy to the approver. An agent that composes the text the approver reads can describe one action and submit another, pad the display so the decisive value is not seen, spoof a label, add a decoy recipient, or cancel one amount against another in a summary [APPROVEWHAT] [CONSENT]. Binding the approval to args_hash does not help if the approver was shown something other than the arguments that were hashed. The display therefore needs to be rendered from the canonical argument object by the enforcement point or a component it trusts (Section 8). Rendering needs care of its own: Unicode confusables, bidirectional control characters and zero-width characters can make two different values look identical, and amounts need explicit currency and scale. A renderer SHOULD refuse, or flag prominently, any argument value containing such characters, and SHOULD show every argument the approval binds. 12.6. Threshold Splitting and Flooding A per-action rule with single-use approval does not stop an agent splitting one action that would need approval into many that individually do not, such as one payment into several below a threshold. Detecting this needs a rule that is stateful across actions, evaluated over a window and keyed on the dimension being split (for example counterparty or session), and its refusals recorded as BLOCKED like any other. Because an action record carries a hash of the arguments rather than the arguments, a reviewer cannot sum amounts from records alone; reconstructing a split after the fact requires the argument objects and a complete record set, and omission (Section 12.3) limits the latter. An agent can also flood an approver with requests until one is approved without scrutiny. Human approval rates degrade with volume [OVERSIGHT]. Enforcement points that request approvals SHOULD account for the pending load on each approver, and as that load rises Chueayen Expires 27 April 2027 [Page 32] Internet-Draft AI Attestation Receipts October 2026 SHOULD escalate (to another approver, or to refusal) rather than present further requests to the same approver; a fixed per-agent rate limit alone does not bound the load an approver sees across agents. They SHOULD refuse further requests from an agent while one of its requests is pending, and SHOULD record refusals made on those grounds as BLOCKED with an identifying policy. Approval is most useful when reserved for rare, high-consequence actions with exact values, with routine actions decided by rules. 12.7. Replay A valid record can be presented more than once; it cannot be altered. Re-presentation proves only what the record always proved. Consumers correlating records with events SHOULD de-duplicate on attestation_id or action_id. An action record is evidence, not a capability. A service that accepts an ALLOWED record as authority to act turns a replayable record into a bearer token; a deployment that wants that MUST add single-use enforcement at the executing service, which this document does not define. Approval replay is addressed by the single-use, expiry and exact- value properties of Section 8. Because each property is checked by the enforcement point at decision time, a record shows that the check was made only to the extent that the issuer is trusted (Section 12.3). 12.8. Key Compromise An attacker holding the issuer's private key can forge records of either outcome, including refusals that were never made, and can choose any timestamp. Records whose inclusion is proven under a tree head that a third party retained before the compromise remain distinguishable from records forged after it; records that are not in the log, or whose inclusion is proven only under later heads, do not. A compromised key also signs tree heads in the deployment described in Section 11, which is a further reason to retain heads outside the issuer. The signing key in that deployment is held in service configuration, not in a hardware module. Chueayen Expires 27 April 2027 [Page 33] Internet-Draft AI Attestation Receipts October 2026 12.9. Confidentiality of Requests and Arguments Records contain no plaintext prompt, response or argument object, only hashes. For high-entropy inputs the hash reveals nothing useful by inversion. Where the input is low-entropy or guessable, an attacker can hash candidates and match. Argument objects are often low-entropy (a repository name and a pull request number, an amount and a known account), so args_hash binds the arguments but does not conceal them. Deployments MUST treat request_hash, args_hash and intent_hash as potentially personal data and apply their own data- protection controls. Issuers that require pseudonymity SHOULD hash with a key kept secret from verifiers, at the cost of offline reproducibility by third parties. 12.10. Integrity Versus Correctness Signature verification establishes integrity and issuer attribution under a pinned key. It does not establish that the decision was the right decision. 12.11. Post-Quantum Considerations Ed25519 is not post-quantum secure. An adversary with a cryptographically relevant quantum computer could forge signatures under an issuer key that was active before migration, which matters where long audit retention intersects that horizon. SHA-256 request and argument binding remains useful as a tamper-detection commitment for detecting alteration of past record bytes under known attacks on hashes. Because v selects the whole suite (Section 5.1), a later version can introduce a post-quantum signature suite without changing the field names. This document does not define such a suite. 13. Privacy Considerations An action record carries identifiers chosen by the issuer and the caller: org_id, session_id and agent. Combined with timestamps, these can reveal the working patterns of the people on whose behalf an agent acts, even though no argument values are present. A public log of records extends that exposure to anyone who can read the log. Deployments SHOULD choose identifiers that are not personal data where they can, and SHOULD consider entering only digests of records in any log readable outside the subject organisation. Chueayen Expires 27 April 2027 [Page 34] Internet-Draft AI Attestation Receipts October 2026 14. IANA Considerations This document has no IANA actions. A future revision may request registration of media types for the two record types, which would also give the COSE option of Section 9.2 a content type more specific than application/json. 15. References 15.1. Normative References [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", BCP 14, RFC 2119, DOI 10.17487/RFC2119, March 1997, . [RFC3339] Klyne, G. and C. Newman, "Date and Time on the Internet: Timestamps", RFC 3339, DOI 10.17487/RFC3339, July 2002, . [RFC6234] Eastlake 3rd, D. and T. Hansen, "US Secure Hash Algorithms (SHA and SHA-based HMAC and HKDF)", RFC 6234, DOI 10.17487/RFC6234, May 2011, . [RFC8032] Josefsson, S. and I. Liusvaara, "Edwards-Curve Digital Signature Algorithm (EdDSA)", RFC 8032, DOI 10.17487/RFC8032, January 2017, . [RFC8174] Leiba, B., "Ambiguity of Uppercase vs Lowercase in RFC 2119 Key Words", BCP 14, RFC 8174, DOI 10.17487/RFC8174, May 2017, . [RFC8259] Bray, T., Ed., "The JavaScript Object Notation (JSON) Data Interchange Format", STD 90, RFC 8259, DOI 10.17487/RFC8259, December 2017, . [RFC8785] Rundgren, A., Jordan, B., and S. Erdtman, "JSON Canonicalization Scheme (JCS)", RFC 8785, DOI 10.17487/RFC8785, June 2020, . 15.2. Informative References Chueayen Expires 27 April 2027 [Page 35] Internet-Draft AI Attestation Receipts October 2026 [ACCEPT-V1] Aqta Technologies Limited, "Seal Acceptance Record Format, Version 1 (ACCEPT-v1), draft", August 2026, . [ACTION-V1] Aqta Technologies Limited, "Seal Action Record Format, Version 1 (ACTION-v1)", October 2026, . [AFR] "Agent Flight Recorder: Tamper-Evident Audit Trails with On-Chain Anchoring for Long-Horizon Tool-Using Agents", September 2026, . [APPROVEWHAT] Kodathala, S. V., Pollishetty, P., and J. Cargill, "Approve What, Exactly? Effect Binding and Trusted Rendering for Agent Step-Up Authorization", October 2026, . [CONSENT] Weng, X., "What You Approve Is What Executes: Consent Integrity for Black-Box LLM Agents", June 2026, . [EXECGOV] "Execution Governance 3.0: From Pre-Effect Authorization to Authorization-Bound Execution", August 2026, . [I-D.das-drip-uas-act-finality] Das, S., "Cleared to Fly or Drive Is Not Cleared to Act: Actuator-Level Execution Finality and Compact Act Evidence for UAS and Autonomous Vehicles", Work in Progress, Internet-Draft, draft-das-drip-uas-act-finality-02, 13 October 2026, . [I-D.farley-acta-signed-receipts] Farley, T., "Signed Decision Receipts for Machine-to- Machine Access Control", Work in Progress, Internet-Draft, draft-farley-acta-signed-receipts-03, 3 September 2026, . [I-D.ietf-wimse-aims] Kasselman, P., Lombardo, J., Rosomakho, Y., Campbell, B., Steele, N., and A. Parecki, "AI Identity Management System", Work in Progress, Internet-Draft, draft-ietf- Chueayen Expires 27 April 2027 [Page 36] Internet-Draft AI Attestation Receipts October 2026 wimse-aims-00, 15 September 2026, . [I-D.izmaylov-agent-permission-receipts] Izmaylov, P., "Signed Permissions and Action Receipts for Automated Agents", Work in Progress, Internet-Draft, draft-izmaylov-agent-permission-receipts-00, 7 October 2026, . [I-D.kuehlewind-audit-architecture] Kühlewind, M. and H. Birkholz, "An Architecture for Auditing Agent Delegation and Interactions", Work in Progress, Internet-Draft, draft-kuehlewind-audit- architecture-01, 7 September 2026, . [I-D.marques-asqav-compliance-receipts] Marques, J. A. G., "Compliance Profile of Signed Action Receipts for AI Agents", Work in Progress, Internet-Draft, draft-marques-asqav-compliance-receipts-09, 21 September 2026, . [I-D.munoz-scitt-permit-profile] Munoz, C., "A SCITT Profile for Pre-Execution AI Action Authorization Records", Work in Progress, Internet-Draft, draft-munoz-scitt-permit-profile-01, 19 July 2026, . [I-D.sharif-agent-audit-trail] Sharif, R., "Agent Audit Trail: A Standard Logging Format for Autonomous AI Systems", Work in Progress, Internet- Draft, draft-sharif-agent-audit-trail-08, 13 October 2026, . [I-D.tsyrulnikov-rats-attested-inference-receipt] Tsyrulnikov, B., "Attested Inference Receipt (AIR): A COSE/CWT Profile for Confidential AI Inference", Work in Progress, Internet-Draft, draft-tsyrulnikov-rats-attested- inference-receipt-02, 5 July 2026, . Chueayen Expires 27 April 2027 [Page 37] Internet-Draft AI Attestation Receipts October 2026 [ISSUER-ADVERSARY] Aqta Technologies Limited, "The issuer as adversary", September 2026, . [NOTARIZED] "Notarized Agents: Receiver-Attested Confidential Receipts for AI Agent Actions", June 2026, . [OVERSIGHT] Turan, E., "Oversight Has a Capacity: Calibrating Agent Guards to a Subjective, Fatiguing Human", June 2026, . [RFC7942] Sheffer, Y. and A. Farrel, "Improving Awareness of Running Code: The Implementation Status Section", BCP 205, RFC 7942, DOI 10.17487/RFC7942, July 2016, . [RFC9052] Schaad, J., "CBOR Object Signing and Encryption (COSE): Structures and Process", STD 96, RFC 9052, DOI 10.17487/RFC9052, August 2022, . [RFC9162] Laurie, B., Messeri, E., and R. Stradling, "Certificate Transparency Version 2.0", RFC 9162, DOI 10.17487/RFC9162, December 2021, . [RFC9562] Davis, K., Peabody, B., and P. Leach, "Universally Unique IDentifiers (UUIDs)", RFC 9562, DOI 10.17487/RFC9562, May 2024, . [RFC9597] Looker, T. and M.B. Jones, "CBOR Web Token (CWT) Claims in COSE Headers", RFC 9597, DOI 10.17487/RFC9597, June 2024, . [RFC9864] Jones, M.B. and O. Steele, "Fully-Specified Algorithms for JSON Object Signing and Encryption (JOSE) and CBOR Object Signing and Encryption (COSE)", RFC 9864, DOI 10.17487/RFC9864, October 2025, . [RFC9942] Steele, O., Birkholz, H., Delignat-Lavaud, A., and C. Fournet, "CBOR Object Signing and Encryption (COSE) Receipts", RFC 9942, DOI 10.17487/RFC9942, June 2026, . Chueayen Expires 27 April 2027 [Page 38] Internet-Draft AI Attestation Receipts October 2026 [RFC9943] Birkholz, H., Delignat-Lavaud, A., Fournet, C., Deshpande, Y., and S. Lasker, "An Architecture for Trustworthy and Transparent Digital Supply Chains", RFC 9943, DOI 10.17487/RFC9943, June 2026, . Appendix A. Example Receipt The following informative example is vector valid/001-allowed.json from the receipt conformance set in Appendix C. A verifier that pins the receipt test public key MUST accept it. Field order in this figure is for readability; canonical signing order is defined in Section 5. The signature value is shown on two lines for document formatting only; in the vector file it is a single base64url string with no whitespace. { "v": 1, "attestation_id": "00000000-0000-0000-0000-000000000001", "trace_id": "trace-tv-001", "org_id": "org-test-vectors", "request_hash": "8f3a7e2b9c4d5f6a1b0c9d8e7f6a5b4c3d2e1f0a9b8c7d6e5f4a3b2c1d0e9f8a", "model": "gpt-4o", "outcome": "ALLOWED", "policy_applied": ["budget_guard"], "cost_prevented_eur": 0, "timestamp": "2026-04-23T10:15:30.000000+00:00", "public_key": "alWzEnrA_z9McN9z_MFfQCnH9mVgOwRZ26wrI7oix4E", "signature": "gXA2GNEvACSGDtOk9KMEeHDUQMPUhHJHeLFMbbrwKlEI" "XY9UkvI5gWQ201Lm3Tkh7K3luXwQtqcua6vv4HmAAg" } Pinned test public key for this example and the receipt vector set: alWzEnrA_z9McN9z_MFfQCnH9mVgOwRZ26wrI7oix4E Appendix B. Example Action Record The following informative example is vector action/ valid/002-blocked.json from the action record conformance set in Appendix C: a refusal. On 17 October 2026 both published verifiers, version 1.2.7, accepted it with the action record test key pinned and the action record type selected, and rejected it when asked to verify it as a receipt. Chueayen Expires 27 April 2027 [Page 39] Internet-Draft AI Attestation Receipts October 2026 The proposed argument object, its canonical serialisation, and the resulting args_hash: argument object: {"repo": "example/api", "pr": 41} canonical bytes: {"pr":41,"repo":"example/api"} args_hash: 8195fd1a5f2881870e56f68dac8279d80d5bec6a022bd97755409f31fd2740f9 The registered session intent is the UTF-8 text "fix the failing auth test in repo example/api", whose SHA-256 digest is the intent_hash below. The record. Field order is for readability, and long values are shown on two lines for document formatting only: { "v": "action-1", "action_id": "00000000-0000-0000-0000-000000000002", "org_id": "org-vector", "session_id": "sess-vector-0001", "intent_hash": "d119bff592df7060201aa6f9cf6dd12ba71edd692493baad4535e9d35161e066", "agent": "claude-code/2.1", "tool": "github.merge_pull_request", "args_hash": "8195fd1a5f2881870e56f68dac8279d80d5bec6a022bd97755409f31fd2740f9", "outcome": "BLOCKED", "policy_applied": ["production_change_review", "require_intent"], "timestamp": "2026-08-22T14:03:11.412903+00:00", "public_key": "pOaccW6Csyo1POtxjixPH80oux9--YC1tzzaENT4vQ0", "signature": "HD5uFaIo7UWRweSKBKnLkaOKbm2atE8aYOyiXx0-awPif" "BOtUC6kgdHDva9SVcEM8NSeH0xKlIHydsrqiDbTBg" } Pinned test public key for the action record vector set: pOaccW6Csyo1POtxjixPH80oux9--YC1tzzaENT4vQ0 Read against Section 7.4, this record proves that the holder of that key evaluated the policies production_change_review and require_intent over a proposed github.merge_pull_request with exactly these argument bytes, in a session bound to an intent with this digest, and refused it. It records, without verifying, that the proposer called itself claude-code/2.1. It does not show whether the merge happened by another route. Chueayen Expires 27 April 2027 [Page 40] Internet-Draft AI Attestation Receipts October 2026 Appendix C. Conformance Vectors Informative conformance vectors are published at: https://github.com/Aqta-ai/attestation-spec/tree/main/test-vectors The receipt set (valid/ and invalid/) has its own fixed test key, given in Appendix A. The action record set (action/valid/, 11 records, and action/invalid/, 23 records) has its own fixed test key, given in Appendix B; its invalid set includes a correctly signed receipt, which an action record verifier must reject. Transparency vectors (transparency/) cover inclusion proofs, consistency proofs and signed tree heads, and history bundles for the issuer-adversary classes that a history verifier, as distinct from a record verifier, must detect. A conformant verifier that pins the relevant test key and selects the relevant record type MUST accept every record in the valid set and MUST reject every record in the invalid set. The vectors are generated from fixed seeds documented in that repository so third parties can reproduce the signatures. Appendix D. Changes From draft-chueayen-attestation-receipts-03 No wire format change for the receipt: a receipt that verified under -03 verifies identically under -04, and no v value changes. The action record specified here is the frozen ACTION-v1 format; no byte of it changes either. * The action record, previously described only as an externally specified sibling, is now specified in this document: fields, outcomes, canonicalisation of the record and of the argument object, a normative assertion-provenance table, verification, and what a verified record does and does not prove. The title and abstract now cover both record types. * New requirements on the action record issuer: the signing key is never accessible to the agent, and no action proceeds on an ALLOWED decision without a signed, stored record. * New section on approval bound to exact values, with requirements on the enforcement point and no wire format: binding to the argument hash and policy version, single use, expiry, independence, and rendering from the canonical action; with an explicit statement that the version-1 record does not reference an approval. Chueayen Expires 27 April 2027 [Page 41] Internet-Draft AI Attestation Receipts October 2026 * New informative section on transparency and SCITT: the current log, an illustrative COSE_Sign1 envelope with RFC 9597 claims and RFC 9864 algorithm identifiers, registration under RFC 9943 with RFC 9942 Receipts, and a list of the places where the current format does not yet compose. * Security considerations extended: the issuer as adversary, declaration gaming, approver deception and rendering, threshold splitting and flooding, replay of records and of approvals, key compromise, argument confidentiality, and a consolidated statement of what a record proves. * New Privacy Considerations section. * The Reference Implementations appendix is replaced by an Implementation Status section in the style of RFC 7942, with registry versions and a dated run of both published 1.4.0 verifiers over the action record vectors. * Verification now states that format rules match the whole value in ASCII digits, matching both verifiers since version 1.2.7. * References: RFC 3339 cited normatively for timestamps; RFC 7942, RFC 9052, RFC 9162, RFC 9562, RFC 9597, RFC 9864, RFC 9942, RFC 9943, the AUDIT architecture draft, the munoz and izmaylov drafts, the WIMSE agent identity and authorisation draft (formerly draft- klrc-aiagent-auth), and three papers on approval binding and approver fatigue added as informative. The sentence in the -03 canonicalisation section correcting -02's wording on RFC 8785 number serialisation is removed, the correction itself being retained. Appendix E. Changes From draft-chueayen-attestation-receipts-02 * Lexicographic order defined normatively as UTF-16 code unit, in a new Ordering section. * Strict UTF-8 decoding required; a verifier must not substitute U+FFFD. * Number serialisation stated as RFC 8785 Section 3.2.2.3 within the permitted range, correcting wording that said the format "does not adopt" it. * RFC 8785 moved from informative to normative. * A section recorded the sibling record type for agent actions, ACTION-v1, and the discrimination rule. Chueayen Expires 27 April 2027 [Page 42] Internet-Draft AI Attestation Receipts October 2026 Appendix F. Changes From draft-chueayen-attestation-receipts-00 * Added explicit non-goals and a "what a verified receipt proves" section. * Clarified relationship to related Internet-Drafts without requiring them. * Documented optional chain fields and spec_version for wire clarity. * Clarified that cost_prevented_eur is non-security and SHOULD be 0 for new issuers. * Added conformance language, an example receipt, and a pointer to published test vectors. * Normative reference to SHA-256 via RFC 6234. * Tightened verification steps for issuer identity pinning. * Softened attestation_id to UUID string with version-4 SHOULD. * Clarified policy_applied as UTF-8 strings and tightened verification type checks. Acknowledgements The ordering divergence described in Section 5.4, and further defects in the reference implementations, were reported by people outside the author's organisation during a public review of those implementations between August and September 2026. Each was fixed and added to the published conformance vectors as a regression case. The framing of the issuer as the adversary worth modelling is taken from [NOTARIZED]. Author's Address Anya Chueayen Aqta Technologies Limited Dublin Ireland Email: hello@aqta.ai Chueayen Expires 27 April 2027 [Page 43]