sello 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/LICENSE +200 -0
  2. package/README.md +195 -0
  3. package/SPEC.md +738 -0
  4. package/docs/assets/sello-banner.png +0 -0
  5. package/docs/assets/sello-social-preview.png +0 -0
  6. package/docs/decisions.md +79 -0
  7. package/docs/paper/notarized-agents.md +523 -0
  8. package/docs/paper/notarized-agents.pdf +0 -0
  9. package/docs/paper/notarized-agents.tex +1387 -0
  10. package/docs/paper/refs.bib +245 -0
  11. package/docs/performance.md +24 -0
  12. package/docs/release-checklist.md +56 -0
  13. package/docs/sdk-build-plan.md +214 -0
  14. package/docs/sdk-quickstart.md +115 -0
  15. package/docs/sdk-security-audit.md +53 -0
  16. package/docs/security-review.md +54 -0
  17. package/examples/mcp-tool-server.ts +250 -0
  18. package/examples/quickstart-tool.ts +178 -0
  19. package/fixtures/vectors/.gitkeep +1 -0
  20. package/fixtures/vectors/sello-v0.1.json +101 -0
  21. package/package.json +52 -0
  22. package/src/cbor.ts +337 -0
  23. package/src/cli/bench.ts +390 -0
  24. package/src/cli/demo.ts +114 -0
  25. package/src/cli/sello.ts +514 -0
  26. package/src/cose/protected-header.ts +210 -0
  27. package/src/cose/sign1.ts +124 -0
  28. package/src/crypto/ed25519.ts +117 -0
  29. package/src/crypto/identifiers.ts +64 -0
  30. package/src/hpke/base.ts +349 -0
  31. package/src/hpke/receipt.ts +79 -0
  32. package/src/index.ts +15 -0
  33. package/src/log/canonical-url.ts +168 -0
  34. package/src/log/mock-log.ts +170 -0
  35. package/src/log/rekor.ts +147 -0
  36. package/src/log/types.ts +27 -0
  37. package/src/mcp/middleware.ts +198 -0
  38. package/src/owner/verify.ts +276 -0
  39. package/src/receipt/body.ts +210 -0
  40. package/src/registry/json-registry.ts +233 -0
  41. package/src/sdk/index.ts +22 -0
  42. package/src/sdk/keys.ts +191 -0
  43. package/src/sdk/logs.ts +200 -0
  44. package/src/sdk/publisher.ts +145 -0
  45. package/src/sdk/service.ts +562 -0
  46. package/src/service/create-receipt.ts +178 -0
  47. package/src/token/jws-profile.ts +174 -0
@@ -0,0 +1,1387 @@
1
+ % Options for packages loaded elsewhere
2
+ \PassOptionsToPackage{unicode}{hyperref}
3
+ \PassOptionsToPackage{hyphens}{url}
4
+ \PassOptionsToPackage{dvipsnames,svgnames,x11names}{xcolor}
5
+ %
6
+ \documentclass[
7
+ 11pt,
8
+ ]{article}
9
+ \usepackage{amsmath,amssymb}
10
+ \usepackage{setspace}
11
+ \usepackage{iftex}
12
+ \ifPDFTeX
13
+ \usepackage[T1]{fontenc}
14
+ \usepackage[utf8]{inputenc}
15
+ \usepackage{textcomp} % provide euro and other symbols
16
+ \else % if luatex or xetex
17
+ \usepackage{unicode-math} % this also loads fontspec
18
+ \defaultfontfeatures{Scale=MatchLowercase}
19
+ \defaultfontfeatures[\rmfamily]{Ligatures=TeX,Scale=1}
20
+ \fi
21
+ \usepackage{lmodern}
22
+ \ifPDFTeX\else
23
+ % xetex/luatex font selection
24
+ \fi
25
+ % Use upquote if available, for straight quotes in verbatim environments
26
+ \IfFileExists{upquote.sty}{\usepackage{upquote}}{}
27
+ \IfFileExists{microtype.sty}{% use microtype if available
28
+ \usepackage[]{microtype}
29
+ \UseMicrotypeSet[protrusion]{basicmath} % disable protrusion for tt fonts
30
+ }{}
31
+ \makeatletter
32
+ \@ifundefined{KOMAClassName}{% if non-KOMA class
33
+ \IfFileExists{parskip.sty}{%
34
+ \usepackage{parskip}
35
+ }{% else
36
+ \setlength{\parindent}{0pt}
37
+ \setlength{\parskip}{6pt plus 2pt minus 1pt}}
38
+ }{% if KOMA class
39
+ \KOMAoptions{parskip=half}}
40
+ \makeatother
41
+ \usepackage{xcolor}
42
+ \usepackage[margin=1in]{geometry}
43
+ \usepackage{color}
44
+ \usepackage{fancyvrb}
45
+ \newcommand{\VerbBar}{|}
46
+ \newcommand{\VERB}{\Verb[commandchars=\\\{\}]}
47
+ \DefineVerbatimEnvironment{Highlighting}{Verbatim}{commandchars=\\\{\}}
48
+ % Add ',fontsize=\small' for more characters per line
49
+ \newenvironment{Shaded}{}{}
50
+ \newcommand{\AlertTok}[1]{\textcolor[rgb]{1.00,0.00,0.00}{\textbf{#1}}}
51
+ \newcommand{\AnnotationTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{#1}}}}
52
+ \newcommand{\AttributeTok}[1]{\textcolor[rgb]{0.49,0.56,0.16}{#1}}
53
+ \newcommand{\BaseNTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{#1}}
54
+ \newcommand{\BuiltInTok}[1]{\textcolor[rgb]{0.00,0.50,0.00}{#1}}
55
+ \newcommand{\CharTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{#1}}
56
+ \newcommand{\CommentTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textit{#1}}}
57
+ \newcommand{\CommentVarTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{#1}}}}
58
+ \newcommand{\ConstantTok}[1]{\textcolor[rgb]{0.53,0.00,0.00}{#1}}
59
+ \newcommand{\ControlFlowTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{\textbf{#1}}}
60
+ \newcommand{\DataTypeTok}[1]{\textcolor[rgb]{0.56,0.13,0.00}{#1}}
61
+ \newcommand{\DecValTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{#1}}
62
+ \newcommand{\DocumentationTok}[1]{\textcolor[rgb]{0.73,0.13,0.13}{\textit{#1}}}
63
+ \newcommand{\ErrorTok}[1]{\textcolor[rgb]{1.00,0.00,0.00}{\textbf{#1}}}
64
+ \newcommand{\ExtensionTok}[1]{#1}
65
+ \newcommand{\FloatTok}[1]{\textcolor[rgb]{0.25,0.63,0.44}{#1}}
66
+ \newcommand{\FunctionTok}[1]{\textcolor[rgb]{0.02,0.16,0.49}{#1}}
67
+ \newcommand{\ImportTok}[1]{\textcolor[rgb]{0.00,0.50,0.00}{\textbf{#1}}}
68
+ \newcommand{\InformationTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{#1}}}}
69
+ \newcommand{\KeywordTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{\textbf{#1}}}
70
+ \newcommand{\NormalTok}[1]{#1}
71
+ \newcommand{\OperatorTok}[1]{\textcolor[rgb]{0.40,0.40,0.40}{#1}}
72
+ \newcommand{\OtherTok}[1]{\textcolor[rgb]{0.00,0.44,0.13}{#1}}
73
+ \newcommand{\PreprocessorTok}[1]{\textcolor[rgb]{0.74,0.48,0.00}{#1}}
74
+ \newcommand{\RegionMarkerTok}[1]{#1}
75
+ \newcommand{\SpecialCharTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{#1}}
76
+ \newcommand{\SpecialStringTok}[1]{\textcolor[rgb]{0.73,0.40,0.53}{#1}}
77
+ \newcommand{\StringTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{#1}}
78
+ \newcommand{\VariableTok}[1]{\textcolor[rgb]{0.10,0.09,0.49}{#1}}
79
+ \newcommand{\VerbatimStringTok}[1]{\textcolor[rgb]{0.25,0.44,0.63}{#1}}
80
+ \newcommand{\WarningTok}[1]{\textcolor[rgb]{0.38,0.63,0.69}{\textbf{\textit{#1}}}}
81
+ \usepackage{longtable,booktabs,array}
82
+ \usepackage{calc} % for calculating minipage widths
83
+ % Correct order of tables after \paragraph or \subparagraph
84
+ \usepackage{etoolbox}
85
+ \makeatletter
86
+ \patchcmd\longtable{\par}{\if@noskipsec\mbox{}\fi\par}{}{}
87
+ \makeatother
88
+ % Allow footnotes in longtable head/foot
89
+ \IfFileExists{footnotehyper.sty}{\usepackage{footnotehyper}}{\usepackage{footnote}}
90
+ \makesavenoteenv{longtable}
91
+ \setlength{\emergencystretch}{3em} % prevent overfull lines
92
+ \providecommand{\tightlist}{%
93
+ \setlength{\itemsep}{0pt}\setlength{\parskip}{0pt}}
94
+ \setcounter{secnumdepth}{-\maxdimen} % remove section numbering
95
+ \usepackage{microtype}
96
+ \usepackage{booktabs}
97
+ \usepackage{xurl}
98
+ \ifLuaTeX
99
+ \usepackage{selnolig} % disable illegal ligatures
100
+ \fi
101
+ \usepackage[]{natbib}
102
+ \bibliographystyle{plainnat}
103
+ \IfFileExists{bookmark.sty}{\usepackage{bookmark}}{\usepackage{hyperref}}
104
+ \IfFileExists{xurl.sty}{\usepackage{xurl}}{} % add URL line breaks if available
105
+ \urlstyle{same}
106
+ \hypersetup{
107
+ pdftitle={Notarized Agents: Receiver-Attested Confidential Receipts for AI Agent Actions},
108
+ colorlinks=true,
109
+ linkcolor={Maroon},
110
+ filecolor={Maroon},
111
+ citecolor={Blue},
112
+ urlcolor={Blue},
113
+ pdfcreator={LaTeX via pandoc}}
114
+
115
+ \title{Notarized Agents: Receiver-Attested Confidential Receipts for AI
116
+ Agent Actions}
117
+ \author{Juan Figuera\\
118
+ Independent Researcher, Sello Project\\
119
+ \texttt{juan@figuera.co}}
120
+ \date{Draft of May 30, 2026}
121
+
122
+ \begin{document}
123
+ \maketitle
124
+ \begin{abstract}
125
+ Current AI agent observability is structurally compromised: the entity
126
+ producing the activity log is the same entity whose activity is being
127
+ logged. A compromised or buggy agent can omit, alter, or fabricate its
128
+ own traces, and the operator running the agent has no independent way to
129
+ detect tampering. We propose a class of protocols that resolves this by
130
+ inverting the trust boundary: the service that receives an agent's call
131
+ signs a receipt of what it observed using its own key, encrypts the
132
+ receipt to the agent's owner, and publishes it to a public transparency
133
+ log. The owner reconstructs a tamper-evident trail without trusting the
134
+ agent or its operator. We instantiate the class as Sello, a protocol
135
+ combining four properties absent in any current system: (P1)
136
+ receiver-side signing, (P2) HPKE encryption to an owner public key bound
137
+ to the authorization token via JWS, (P3) publication to a
138
+ witness-cosigned Merkle log, and (P4) owner-side discovery by token
139
+ reference. We describe the protocol, analyze its security under an
140
+ adversary that controls the agent and its operator, present
141
+ microbenchmarks of the cryptographic operations, and situate Sello among
142
+ adjacent receipt-protocol work (Signet, AgentROA, Agent Passport System,
143
+ draft-farley-acta, SCITT). We discuss known limitations including the
144
+ suppression attack, service collusion, and the adoption-incentive
145
+ problem.
146
+ \end{abstract}
147
+
148
+ \setstretch{1.15}
149
+ \hypertarget{introduction}{%
150
+ \subsection{1 Introduction}\label{introduction}}
151
+
152
+ Agents acting on behalf of humans need to be auditable by those humans.
153
+ The agent's owner needs to know not just what the agent claims it did,
154
+ but what it actually did. This requirement is foundational to deploying
155
+ agents in any context where the consequences of agent action are
156
+ non-trivial: financial transactions, healthcare data access, code
157
+ modification, communication on the principal's behalf.
158
+
159
+ The dominant approach to agent observability today is to instrument the
160
+ agent itself, the agent's runtime, or a proxy in the operator's
161
+ infrastructure. Platforms such as Langfuse, LangSmith, Helicone,
162
+ Braintrust, and AgentOps collect traces from inside the agent's process
163
+ and aggregate them for the owner's inspection. This is the model that
164
+ has shipped to production at scale, and the model that every commercial
165
+ agent observability product currently in the market follows.
166
+
167
+ This model fails the threat model that agent deployment actually faces.
168
+ The agent is the actor; the agent is also the source of truth about its
169
+ own behavior. When the agent is compromised (by prompt injection,
170
+ context poisoning, tool-call hijacking, or simply buggy code), the
171
+ traces it produces about its own actions cannot be trusted, because the
172
+ same code path that misbehaves is the code path that writes the trace.
173
+ When the operator running the agent has misaligned incentives, the
174
+ traces can be silently rewritten before they reach the owner. The actor
175
+ is not a reliable narrator of its own actions, and we have known this
176
+ for the entire history of accounting, law, journalism, and science.
177
+ Recent work on AI auditing makes a related argument, that black-box
178
+ query access alone is insufficient for rigorous audits and that auditors
179
+ need richer forms of access to assess a system's behavior
180
+ \citep{casper-blackbox}; receiver-attested receipts are one
181
+ cryptographic answer to that broader question.
182
+
183
+ We can sharpen the requirement concretely. A record of an agent action
184
+ should be:
185
+
186
+ \begin{itemize}
187
+ \tightlist
188
+ \item
189
+ \textbf{unforgeable} by the agent or its operator, even given full
190
+ control of the agent's runtime;
191
+ \item
192
+ \textbf{independently verifiable} by the owner, using only public
193
+ infrastructure and owner-held keys;
194
+ \item
195
+ \textbf{confidential} from the operators of any public infrastructure
196
+ used to store or transmit it;
197
+ \item
198
+ \textbf{attributable} to a party that was actually present when the
199
+ action occurred and is structurally separate from the agent;
200
+ \item
201
+ \textbf{retrievable} by the owner after the interaction is complete,
202
+ even when the agent is unavailable or compromised.
203
+ \end{itemize}
204
+
205
+ No system we surveyed delivers all five.
206
+
207
+ This paper applies a different architectural principle, one with deep
208
+ precedent outside computing. In every legal, scientific, and commercial
209
+ system where the truthfulness of a record matters, the record is written
210
+ by a party who was present at the event but is independent of the
211
+ principal. Mesopotamian commercial contracts circa 3000 BCE were
212
+ impressed into clay tablets witnessed by named third parties whose seals
213
+ were unique to each. Roman notaries inherited the practice. Medieval
214
+ scribes, customs officers, court reporters, lab technicians, and modern
215
+ notarization systems all rest on the same idea. When the recording party
216
+ is structurally separate from the recorded party, the record carries
217
+ weight.
218
+
219
+ Apple's \emph{Find My} network applies this principle in modern
220
+ infrastructure. AirTags do not phone home; they cannot, because they are
221
+ passive Bluetooth devices with no internet connection. Instead, every
222
+ iPhone in the world that walks past an AirTag submits an end-to-end
223
+ encrypted ``I saw tag X near me'' report that only the tag's owner can
224
+ decrypt. The tracked object is dumb. The witnesses, independent iPhones,
225
+ none controlled by the tag's owner, are what produce the verifiable
226
+ record \citep{Heinrich2021}.
227
+
228
+ We port this architectural inversion to AI agent observability. The
229
+ agent is the tracked object. Every service the agent talks to (MCP
230
+ server, API, tool endpoint, A2A peer) is a witness. Each witness signs a
231
+ receipt of the interaction it observed using its own cryptographic key,
232
+ encrypts the receipt to the agent owner's public key, and publishes the
233
+ encrypted receipt to a public transparency log. The owner reconstructs
234
+ the agent's activity by querying the log, verifying signatures against a
235
+ registry of service identities, and decrypting receipts locally. The
236
+ agent never holds any of the signing keys involved. The operator never
237
+ holds the owner's encryption key. A compromised agent cannot fake its
238
+ trail because the trail is signed by parties it does not control.
239
+
240
+ We call this class of protocols \emph{notarization for AI agents}.
241
+ Members of the class can differ in their authorization-token format,
242
+ their choice of transparency log, and their service-identity system,
243
+ while sharing the four defining properties. We instantiate the class as
244
+ \textbf{Sello}, a protocol that combines four properties absent in any
245
+ system we surveyed: receiver-side signing by the called service (P1),
246
+ HPKE encryption to an owner public key cryptographically bound to the
247
+ authorization token (P2), publication to a witness-cosigned Merkle log
248
+ (P3), and owner-side discovery by token reference (P4). The combination
249
+ is the contribution.
250
+
251
+ \hypertarget{contributions}{%
252
+ \subsubsection{Contributions}\label{contributions}}
253
+
254
+ This paper makes four contributions:
255
+
256
+ \begin{enumerate}
257
+ \def\labelenumi{\arabic{enumi}.}
258
+ \item
259
+ We identify the trust-boundary inversion as a structural fix for AI
260
+ agent observability and articulate the four cryptographic properties
261
+ (P1-P4) that distinguish notarized-agent protocols from existing
262
+ approaches.
263
+ \item
264
+ We specify Sello, a concrete instantiation built on standard
265
+ primitives (COSE\_Sign1, HPKE, Ed25519, Merkle transparency logs) and
266
+ define a JWS token profile that cryptographically binds the owner's
267
+ HPKE encryption key to the authorization token presented by the agent.
268
+ \item
269
+ We propose using the transparency log's integrated time as the binding
270
+ clock for key revocation decisions, separating it from the
271
+ service-asserted timestamp in the receipt body. This addresses a class
272
+ of attacks where a compromised service backdates receipts to predate
273
+ its key compromise.
274
+ \item
275
+ We provide a property-by-property comparison of Sello against existing
276
+ receipt-protocol work (Signet, AgentROA, Agent Passport System,
277
+ draft-farley-acta, agentreceipts.ai, Pipelock, Attested Intelligence,
278
+ and the SCITT working group), showing that no current system combines
279
+ all four properties.
280
+ \end{enumerate}
281
+
282
+ We also honestly state what Sello does not solve: the suppression attack
283
+ (the agent simply not calling services produces no receipts), service
284
+ collusion, and the adoption-incentive problem (services must choose to
285
+ emit receipts; today, none have reason to).
286
+
287
+ The remainder of the paper is organized as follows. Section 2 covers
288
+ background and related work. Section 3 specifies the threat model and
289
+ design goals. Section 4 specifies the Sello protocol. Section 5 analyzes
290
+ its security properties under the threat model. Section 6 distinguishes
291
+ per-receipt verifiability from set-completeness and discusses retrieval
292
+ guarantees. Section 7 presents microbenchmarks. Section 8 discusses
293
+ limitations, the adoption-incentive problem, and future extensions.
294
+ Section 9 concludes.
295
+
296
+ \begin{center}\rule{0.5\linewidth}{0.5pt}\end{center}
297
+
298
+ \hypertarget{background-and-related-work}{%
299
+ \subsection{2 Background and Related
300
+ Work}\label{background-and-related-work}}
301
+
302
+ We briefly review the cryptographic primitives Sello composes, then
303
+ survey existing work on cryptographic receipts for AI agent actions.
304
+
305
+ \hypertarget{cryptographic-primitives}{%
306
+ \subsubsection{2.1 Cryptographic
307
+ primitives}\label{cryptographic-primitives}}
308
+
309
+ \textbf{COSE\_Sign1} \citep{RFC9052} is the CBOR Object Signing and
310
+ Encryption single-signer signature structure. It is the binary
311
+ equivalent of JWS for CBOR-encoded payloads. We use COSE\_Sign1 as the
312
+ signing envelope for Sello receipts because it is the format used by the
313
+ IETF SCITT working group for transparency receipts
314
+ \citep{scitt-architecture}, giving Sello a natural alignment path for
315
+ standardization.
316
+
317
+ \textbf{HPKE (Hybrid Public Key Encryption)} \citep{RFC9180} is a
318
+ standardized public-key encryption scheme that combines a Key
319
+ Encapsulation Mechanism (KEM), a Key Derivation Function (KDF), and an
320
+ Authenticated Encryption with Associated Data (AEAD) primitive. Sello
321
+ uses HPKE in single-shot mode with X25519 for the KEM, HKDF-SHA256 for
322
+ the KDF, and ChaCha20-Poly1305 for the AEAD. HPKE is used in TLS
323
+ Encrypted Client Hello and MLS, giving it deep production validation.
324
+
325
+ \textbf{JWS (JSON Web Signature)} \citep{RFC7515} is the JSON
326
+ serialization for signed payloads. Sello defines a JWS-based
327
+ authorization token profile in which the owner's HPKE public key is
328
+ carried as a claim. We use compact serialization. Other token formats
329
+ (UCAN, biscuits, macaroons) would require their own analogous profiles
330
+ in future versions.
331
+
332
+ \textbf{Transparency logs} as we use them are append-only Merkle trees
333
+ with witness cosigning, descending from Certificate Transparency
334
+ \citep{RFC6962, RFC9162}. The witness cosigning idea originates with
335
+ Syta et al.'s CoSi protocol \citep{Syta2016}, which formalized the
336
+ principle that an authoritative statement should be validated and
337
+ publicly logged by a diverse group of witnesses before any client
338
+ accepts it. Modern instances include Sigstore Rekor
339
+ \citep{sigstore-rekor}, which Sello uses as its v0.1 reference log.
340
+
341
+ \hypertarget{receipt-protocols-for-ai-agent-actions}{%
342
+ \subsubsection{2.2 Receipt protocols for AI agent
343
+ actions}\label{receipt-protocols-for-ai-agent-actions}}
344
+
345
+ The ``receipts'' vocabulary for agent actions has emerged across several
346
+ projects in 2024-2026, each making different architectural choices. We
347
+ summarize each and identify which of Sello's four properties they have
348
+ and which they lack. Section 7.4 contains the full comparison table.
349
+
350
+ \textbf{Agent Receipts} \citep{agentreceipts} is an open specification
351
+ maintained by Otto Jongerius defining cryptographically signed agent
352
+ action receipts using Ed25519 and W3C Verifiable Credentials. The author
353
+ frames it as ``C2PA Content Credentials for agent actions.'' The signer
354
+ in Agent Receipts is the agent platform itself, which places the signing
355
+ key on the operator's side of the trust boundary.
356
+
357
+ \textbf{Signet} \citep{signet} is an MCP-focused middleware project
358
+ maintained by William Hou. v0.4 introduced bilateral co-signing in which
359
+ the MCP server holds its own Ed25519 key and signs response receipts.
360
+ v0.10 introduced envelope encryption using XChaCha20-Poly1305 with a key
361
+ derived from the signing identity. Signet is the closest existing system
362
+ to Sello's design, but the encryption key is not separated from the
363
+ signing identity, there is no public transparency log integration, and
364
+ the trust bundle is currently a hand-edited JSON file.
365
+
366
+ \textbf{Pipelock} \citep{pipelock} ships an out-of-process mediator
367
+ signer that runs as a sidecar to the agent's runtime. The architecture
368
+ explicitly distinguishes between in-process signing (the weakest trust
369
+ model), operator-deployed mediator signing (Pipelock's current shipping
370
+ mode), and independent third-party witness signing (listed as roadmap).
371
+ Pipelock has not shipped the third-party variant.
372
+
373
+ \textbf{Agent Passport System (APS)} \citep{aps} by Tymofii Pidlisnyi
374
+ defines Wave 1 accountability primitives consisting of four receipt
375
+ types: ActionReceipt, AuthorityBoundaryReceipt, CustodyReceipt, and
376
+ ContestabilityReceipt. ActionReceipt is signed by the executing agent
377
+ rather than the receiving service, which is a deliberate design choice
378
+ that addresses a different threat model than ours.
379
+
380
+ \textbf{draft-farley-acta-signed-receipts} \citep{farley-acta} is an
381
+ IETF Internet-Draft by Tom Farley at ScopeBlind defining a portable
382
+ signed receipt format for machine-to-machine access control decisions.
383
+ The reference implementation (protect-mcp) is a stdio proxy between
384
+ agent and MCP server, signing decision receipts on behalf of whoever
385
+ operates the proxy. Receipts use deterministic JSON canonicalization
386
+ with Ed25519. The draft does not specify encryption to a recipient and
387
+ does not integrate with a transparency log.
388
+
389
+ \textbf{draft-nivalto-agentroa-route-authorization}
390
+ \citep{nivalto-agentroa} is an IETF Internet-Draft by Joseph Michalak at
391
+ Nivalto defining Agent Enforcement Receipts (AERs) intended for
392
+ submission to SCITT-compatible transparency logs. The signer is the
393
+ egress border gateway operating under the operator's trust domain.
394
+ AgentROA has the SCITT-log piece of Sello's design but signs at
395
+ operator-controlled infrastructure rather than at the receiving service.
396
+
397
+ \textbf{Attested Intelligence} \citep{attestedintelligence} ships an MCP
398
+ governance proxy (\texttt{@attested-intelligence/aga-mcp-server}) that
399
+ emits Ed25519-signed receipts for every MCP tool call, hash-linked into
400
+ a tamper-evident continuity chain, packaged as offline-verifiable
401
+ evidence bundles. The company holds USPTO Patent Application 19/433,835
402
+ (filed December 28, 2025) on the ``Attested Governance Artifacts'' (AGA)
403
+ architecture, which uses standard cryptography (Ed25519, ML-DSA-65,
404
+ SHA-256, Merkle trees) and explicitly does not require Trusted Execution
405
+ Environments. The Portal that signs receipts sits in the operator's
406
+ trust boundary; the agent holds no keys. Receipts are distributed
407
+ point-to-point as evidence bundles rather than published to a
408
+ transparency log, and are not encrypted to an owner public key. Target
409
+ markets include defense, SCADA/ICS, regulated industries (finance,
410
+ healthcare), and enterprise agentic AI governance. The three independent
411
+ patent claims cover the Portal runtime with sealed policy and drift
412
+ detection, a substitution-based privacy mechanism with claims taxonomy,
413
+ and a continuity chain with payload-excluded leaf hashes; Sello uses
414
+ receiver-attested signing, HPKE encryption to owner, and a
415
+ payload-inclusive transparency log, none of which read on these claims.
416
+
417
+ \textbf{SCITT} (Supply Chain Integrity, Transparency, and Trust) is an
418
+ active IETF working group \citep{scitt-architecture, scitt-scrapi}
419
+ standardizing the COSE\_Sign1 transparency receipt framework. No current
420
+ SCITT WG draft applies the framework to AI agent tool calls; existing
421
+ profiles cover supply-chain artifacts (e.g.~CCF \citep{scitt-ccf}) and
422
+ one individual submission on financial trading audit
423
+ (draft-kamimura-scitt-vcp \citep{kamimura-scitt}).
424
+
425
+ \hypertarget{adjacent-academic-work}{%
426
+ \subsubsection{2.3 Adjacent academic
427
+ work}\label{adjacent-academic-work}}
428
+
429
+ Three recent papers are intellectually adjacent to Sello but make
430
+ different architectural choices.
431
+
432
+ \textbf{``Right to History: A Sovereignty Kernel for Verifiable AI Agent
433
+ Execution''} by Jing Zhang \citep{zhang-righttohistory} proposes a
434
+ personal-hardware sovereignty kernel (PunkGo) that produces
435
+ tamper-evident records of agent actions using an RFC 6962 Merkle tree
436
+ audit log local to the owner's machine. The architectural difference is
437
+ fundamental: Right to History assumes the owner has hardware-level
438
+ control of the agent's execution environment and can therefore observe
439
+ every action at the kernel level. Sello assumes the opposite: agents run
440
+ on hosted infrastructure outside the owner's control, and the owner
441
+ relies on the services the agent touches to attest to what they
442
+ observed.
443
+
444
+ \textbf{``Verifiability-First Agents''} by Abhivansh Gupta
445
+ \citep{gupta-verifiabilityfirst} proposes embedded Audit Agents that
446
+ continuously verify intent versus behavior. The verification is
447
+ structural rather than cryptographic: a second agent reads the first
448
+ agent's plans and outputs and checks for divergence. This complements
449
+ Sello (Audit Agents could consume Sello receipts as their ground truth)
450
+ but does not solve the underlying attestation problem.
451
+
452
+ \textbf{``Tool Receipts, Not Zero-Knowledge Proofs''} by Abhinaba Basu
453
+ \citep{basu-toolreceipts} proposes HMAC-signed receipts generated by the
454
+ agent's runtime to detect hallucinations. The architectural difference
455
+ is that the runtime is part of the agent's trust boundary, so the
456
+ receipts cannot defend against a compromised operator.
457
+
458
+ \begin{center}\rule{0.5\linewidth}{0.5pt}\end{center}
459
+
460
+ \hypertarget{threat-model-and-design-goals}{%
461
+ \subsection{3 Threat Model and Design
462
+ Goals}\label{threat-model-and-design-goals}}
463
+
464
+ \hypertarget{system-model}{%
465
+ \subsubsection{3.1 System model}\label{system-model}}
466
+
467
+ A Sello deployment has four actors:
468
+
469
+ \begin{itemize}
470
+ \tightlist
471
+ \item
472
+ An \textbf{owner} who deploys an agent and holds a long-term HPKE key
473
+ pair. The public key is bound to authorization tokens issued for the
474
+ agent's use.
475
+ \item
476
+ An \textbf{agent}, autonomous software acting on the owner's behalf,
477
+ which presents authorization tokens when calling services.
478
+ \item
479
+ A set of \textbf{services} the agent calls. Each service holds its own
480
+ long-term Ed25519 signing key, independent of the owner and the
481
+ operator.
482
+ \item
483
+ A set of public \textbf{transparency logs} that accept signed entries,
484
+ return Merkle inclusion proofs, and are cosigned by independent
485
+ witnesses.
486
+ \end{itemize}
487
+
488
+ \hypertarget{adversary-model}{%
489
+ \subsubsection{3.2 Adversary model}\label{adversary-model}}
490
+
491
+ We assume a powerful adversary who may:
492
+
493
+ \begin{itemize}
494
+ \tightlist
495
+ \item
496
+ Compromise the agent and arbitrarily edit its local logs, traces, and
497
+ outputs.
498
+ \item
499
+ Control the agent's operator infrastructure, including the runtime,
500
+ the network path, and any operator-side telemetry or audit systems.
501
+ \item
502
+ Read the public transparency log in full.
503
+ \item
504
+ Submit arbitrary bytes to the log, including bytes that purport to be
505
+ Sello receipts but cannot pass verification without possession of a
506
+ legitimate service's signing key.
507
+ \end{itemize}
508
+
509
+ We assume the adversary does NOT possess:
510
+
511
+ \begin{itemize}
512
+ \tightlist
513
+ \item
514
+ The Ed25519 signing keys held by legitimate services.
515
+ \item
516
+ The HPKE private key of the agent owner.
517
+ \end{itemize}
518
+
519
+ These assumptions are non-trivial but standard. Service key compromise
520
+ is a known attack class, and the system must degrade gracefully under it
521
+ (we discuss this in Section 5.3). Owner key loss is a known limitation
522
+ of any owner-encrypted system and renders past receipts undecryptable;
523
+ key escrow is out of scope for v0.1.
524
+
525
+ We also assume at least one service the agent calls is honest and
526
+ uncompromised within the relevant time window. If every service colludes
527
+ with the agent operator, Sello cannot detect what they jointly
528
+ fabricate. The system's effectiveness scales with the plurality of
529
+ independent services.
530
+
531
+ \hypertarget{design-goals}{%
532
+ \subsubsection{3.3 Design goals}\label{design-goals}}
533
+
534
+ A protocol meeting our threat model must provide the following
535
+ properties:
536
+
537
+ \textbf{P1. Receiver-side signing.} The signing key is held by the
538
+ service receiving the agent's call. Not the agent, not the operator, not
539
+ any gateway or proxy in the operator's trust boundary. This is the
540
+ inversion that makes the rest possible: it places the signer in the only
541
+ position that observes the call directly while being independent of the
542
+ parties with incentive to misrepresent it.
543
+
544
+ \textbf{P2. Encryption to owner.} Receipt contents are encrypted to the
545
+ agent owner's public key using asymmetric authenticated encryption. The
546
+ owner's public key must be bound to the authorization token by a
547
+ mechanism that cannot be subverted by an adversary substituting a
548
+ different recipient. This property is what makes it safe to publish
549
+ receipts on shared public infrastructure.
550
+
551
+ \textbf{P3. Public transparency log.} Receipts are appended to an
552
+ append-only Merkle log with witness cosigning. The log provides
553
+ tamper-evidence for logged receipts and global verifiability of
554
+ inclusion. Completeness of retrieval is a separate property and depends
555
+ on the query mechanism (Section 6).
556
+
557
+ \textbf{P4. Owner-side discovery.} The owner queries the log by
558
+ authorization-token-derived reference, decrypts receipts locally with
559
+ their private key, and verifies signatures against a registry of service
560
+ identities. No party in the middle reconstructs the trail; no party in
561
+ the middle can see it.
562
+
563
+ A protocol that satisfies P1 alone is ``receiver-attested'' but its
564
+ receipts cannot safely live on public infrastructure (privacy leak). A
565
+ protocol that satisfies P1+P2 can publish to a private log but inherits
566
+ the trust assumptions of that log's operator. A protocol that satisfies
567
+ P1+P2+P3 still requires P4 to be useful to owners who don't control the
568
+ infrastructure agents run on. The four properties together are what
569
+ makes the architecture work.
570
+
571
+ \begin{center}\rule{0.5\linewidth}{0.5pt}\end{center}
572
+
573
+ \hypertarget{the-sello-protocol}{%
574
+ \subsection{4 The Sello Protocol}\label{the-sello-protocol}}
575
+
576
+ \hypertarget{receipt-structure}{%
577
+ \subsubsection{4.1 Receipt structure}\label{receipt-structure}}
578
+
579
+ A Sello receipt is a COSE\_Sign1 envelope wrapping an HPKE-encrypted
580
+ payload. The structure is:
581
+
582
+ \[\text{receipt} = \text{COSE\_Sign1}(\text{HPKE.Seal}_{pk_{\text{owner}}}(\text{body}), \text{sk}_{\text{service}})\]
583
+
584
+ Where:
585
+
586
+ \begin{itemize}
587
+ \tightlist
588
+ \item
589
+ \(pk_{\text{owner}}\) is the owner's X25519 public key, bound to the
590
+ authorization token (Section 4.2)
591
+ \item
592
+ \(sk_{\text{service}}\) is the service's Ed25519 private signing key
593
+ \item
594
+ \(\text{body}\) is a CBOR-encoded structure describing the action
595
+ \end{itemize}
596
+
597
+ The body is defined in CDDL \citep{RFC8610} notation, where \texttt{?}
598
+ denotes an optional field:
599
+
600
+ \begin{verbatim}
601
+ receipt-body = {
602
+ agent-identifier: tstr, ; derived from token hash
603
+ action-type: tstr, ; e.g. "tools/call"
604
+ action-input-hash: bstr, ; SHA-256 over canonicalized input
605
+ action-output-hash: bstr, ; SHA-256 over canonicalized output
606
+ result-status: tstr, ; "success" | "error" | "denied"
607
+ timestamp: tdate, ; RFC 3339 UTC timestamp
608
+ ? service-defined-fields: any
609
+ }
610
+ \end{verbatim}
611
+
612
+ Action inputs and outputs are referenced by SHA-256 hash, not included
613
+ verbatim, to keep receipts small and to limit what the owner can
614
+ reconstruct without independent access to the inputs.
615
+
616
+ The COSE\_Sign1 protected header carries:
617
+
618
+ \begin{itemize}
619
+ \tightlist
620
+ \item
621
+ \texttt{alg\ =\ -8} (EdDSA / Ed25519)
622
+ \item
623
+ \texttt{kid} (binary key identifier for the service's signing key)
624
+ \item
625
+ \texttt{sello\_version\ =\ "0.1.0"}
626
+ \item
627
+ \texttt{sello\_token\_ref\ =\ SHA-256(authorization-token-bytes)}
628
+ \item
629
+ \texttt{sello\_log\_url} (canonical URL of the log this receipt was
630
+ published to)
631
+ \end{itemize}
632
+
633
+ The protected header is what the receiver uses to look up the service's
634
+ public key and the log's identity at verification time.
635
+
636
+ \hypertarget{the-jws-owner-key-binding}{%
637
+ \subsubsection{4.2 The JWS owner-key
638
+ binding}\label{the-jws-owner-key-binding}}
639
+
640
+ The central novel mechanism in Sello is how the receiving service learns
641
+ which public key to encrypt to. The owner cannot publish a static
642
+ directory of public keys (the agent could call any service, and most
643
+ services have no way to look up ``who is this agent's owner''). The
644
+ agent cannot present the owner's pubkey directly without enabling
645
+ substitution attacks.
646
+
647
+ We solve this by carrying the owner's HPKE public key as a signed claim
648
+ inside the agent's authorization token. The v0.1 token profile uses
649
+ compact-serialized JWS \citep{RFC7515} whose payload is a UTF-8-encoded
650
+ JSON object containing the claim:
651
+
652
+ \begin{Shaded}
653
+ \begin{Highlighting}[]
654
+ \FunctionTok{\{}
655
+ \ErrorTok{...}
656
+ \DataTypeTok{"owner\_hpke\_pk"}\FunctionTok{:} \StringTok{"base64url(32{-}byte X25519 public key)"}\FunctionTok{,}
657
+ \DataTypeTok{"sello\_logs"}\FunctionTok{:} \OtherTok{[}\StringTok{"https://log1.example.com"}\OtherTok{,} \ErrorTok{...}\OtherTok{]}
658
+ \FunctionTok{\}}
659
+ \end{Highlighting}
660
+ \end{Shaded}
661
+
662
+ The JWS signature, verifiable against the token issuer's public key,
663
+ cryptographically binds the owner's HPKE public key to the authorization
664
+ token. An adversary who substitutes a different pubkey invalidates the
665
+ JWS. An adversary who reuses a captured token cannot change the
666
+ recipient.
667
+
668
+ When a service receives an agent call, it:
669
+
670
+ \begin{enumerate}
671
+ \def\labelenumi{\arabic{enumi}.}
672
+ \tightlist
673
+ \item
674
+ Verifies the JWS signature against the token issuer's verification
675
+ key.
676
+ \item
677
+ Extracts \texttt{owner\_hpke\_pk} from the verified claims.
678
+ \item
679
+ Uses it as the HPKE recipient key when encrypting the receipt payload.
680
+ \end{enumerate}
681
+
682
+ This mechanism is, as far as we have been able to determine, novel. We
683
+ searched OAuth, JWS, and JWT specifications and extensions for prior art
684
+ on token-bound encryption-recipient public keys and found none. The
685
+ closest existing mechanism is DPoP \citep{RFC9449}, which binds a
686
+ \emph{signing} public key to a token for proof-of-possession. Sello's
687
+ mechanism binds an \emph{encryption} public key for confidential
688
+ receipts; the cryptographic direction is opposite.
689
+
690
+ \hypertarget{protocol-flow}{%
691
+ \subsubsection{4.3 Protocol flow}\label{protocol-flow}}
692
+
693
+ When an agent calls a service:
694
+
695
+ \begin{enumerate}
696
+ \def\labelenumi{\arabic{enumi}.}
697
+ \tightlist
698
+ \item
699
+ The service receives the call and verifies the agent's authorization
700
+ token (JWS signature against the issuer's key).
701
+ \item
702
+ The service performs the requested action (or refuses, if its own
703
+ authorization policy denies).
704
+ \item
705
+ The service constructs a receipt body describing the action.
706
+ \item
707
+ The service encrypts the body to \texttt{owner\_hpke\_pk} using HPKE
708
+ single-shot mode.
709
+ \item
710
+ The service signs the encrypted envelope using COSE\_Sign1 with its
711
+ Ed25519 private key.
712
+ \item
713
+ The service submits the signed envelope to a transparency log listed
714
+ in the token's \texttt{sello\_logs} claim (or by local policy if the
715
+ claim is absent).
716
+ \item
717
+ The log returns an inclusion proof.
718
+ \end{enumerate}
719
+
720
+ When the owner wishes to reconstruct the agent's activity:
721
+
722
+ \begin{enumerate}
723
+ \def\labelenumi{\arabic{enumi}.}
724
+ \tightlist
725
+ \item
726
+ The owner computes \texttt{sello\_token\_ref\ =\ SHA-256(token-bytes)}
727
+ over the same raw token bytes presented by the agent.
728
+ \item
729
+ The owner queries each trusted log for entries matching
730
+ \texttt{sello\_token\_ref} in their protected header.
731
+ \item
732
+ For each returned envelope, the owner verifies that its
733
+ \texttt{sello\_log\_url} matches the log that returned it.
734
+ \item
735
+ The owner verifies the Merkle inclusion proof against the witnessed
736
+ log root.
737
+ \item
738
+ The owner resolves the signing service via the identity registry using
739
+ \texttt{kid} from the protected header, obtaining the service's public
740
+ key.
741
+ \item
742
+ The owner verifies the COSE\_Sign1 signature against that public key.
743
+ \item
744
+ The owner decrypts the HPKE payload using their HPKE private key, with
745
+ the protected header as additional authenticated data.
746
+ \item
747
+ The owner inspects the decrypted receipt body.
748
+ \end{enumerate}
749
+
750
+ A receipt is valid only if all of steps 3 through 7 succeed.
751
+
752
+ \hypertarget{service-identity-and-revocation}{%
753
+ \subsubsection{4.4 Service identity and
754
+ revocation}\label{service-identity-and-revocation}}
755
+
756
+ Sello v0.1 specifies a JSON-file identity registry mapping \texttt{kid}
757
+ to \texttt{(service\_identifier,\ public\_key)}. The registry is signed
758
+ by a trust root operator and served at a stable URL. Owners cache the
759
+ registry with a freshness bound of 24 hours.
760
+
761
+ Rotation is additive: new keys get new \texttt{kid}s; old \texttt{kid}s
762
+ remain valid for verifying receipts signed before rotation.
763
+
764
+ Revocation uses a sibling \texttt{revoked} table mapping each revoked
765
+ \texttt{kid} to a \texttt{revoked\_at} timestamp. \textbf{Receipts are
766
+ rejected if their \texttt{kid} appears in \texttt{revoked} AND the
767
+ transparency log's integrated time for that receipt is at or later than
768
+ \texttt{revoked\_at}.} Receipts whose integrated time precedes
769
+ \texttt{revoked\_at} remain verifiable, preserving the historical record
770
+ for routine key rotation.
771
+
772
+ The use of the transparency log's \emph{integrated time}, the timestamp
773
+ the log itself assigns to the witnessed entry, rather than the service's
774
+ self-asserted timestamp in the receipt body is deliberate. A compromised
775
+ service can backdate its \texttt{timestamp} field arbitrarily; it cannot
776
+ backdate when the log integrated the entry. We propose this as a
777
+ separately defensible novelty: tying revocation decisions to
778
+ log-integrated time rather than signer-asserted time is, to our
779
+ knowledge, not present in current transparency-log deployments or AI
780
+ agent receipt protocols.
781
+
782
+ The JSON-file registry is a v0.1 stopgap, not a production identity
783
+ solution. Section 8 discusses paths forward.
784
+
785
+ \begin{center}\rule{0.5\linewidth}{0.5pt}\end{center}
786
+
787
+ \hypertarget{security-analysis}{%
788
+ \subsection{5 Security Analysis}\label{security-analysis}}
789
+
790
+ We analyze Sello's properties under the adversary model from Section
791
+ 3.2. The analysis is informal but tied to specific protocol mechanisms.
792
+
793
+ \hypertarget{integrity-of-recorded-actions}{%
794
+ \subsubsection{5.1 Integrity of recorded
795
+ actions}\label{integrity-of-recorded-actions}}
796
+
797
+ \textbf{Claim:} A receipt signed by a legitimate service's key cannot be
798
+ modified without detection.
799
+
800
+ \textbf{Argument:} The COSE\_Sign1 signature covers the entire envelope
801
+ including the protected header and the HPKE-encrypted payload. Any
802
+ modification of the protected header, the payload, or the signature
803
+ itself invalidates the signature. Verification against the service's
804
+ public key (resolved via the registry by \texttt{kid}) will fail. This
805
+ property relies on the unforgeability of Ed25519 under the standard
806
+ EUF-CMA assumption, which is well-established
807
+ \citep{bernstein2012ed25519}.
808
+
809
+ \hypertarget{confidentiality-of-receipt-contents}{%
810
+ \subsubsection{5.2 Confidentiality of receipt
811
+ contents}\label{confidentiality-of-receipt-contents}}
812
+
813
+ \textbf{Claim:} A passive observer of the transparency log cannot read
814
+ receipt contents.
815
+
816
+ \textbf{Argument:} Receipt contents are HPKE-sealed to the owner's
817
+ X25519 public key. HPKE single-shot encryption provides IND-CCA2
818
+ security under the standard X25519 and ChaCha20-Poly1305 assumptions
819
+ \citep{RFC9180}. The encapsulated key and ciphertext together reveal
820
+ nothing about the plaintext without possession of the owner's private
821
+ key. The protected header is not encrypted and does reveal metadata: the
822
+ \texttt{kid} (which service signed), the \texttt{sello\_token\_ref} (the
823
+ token-derived identifier the agent presented), and the
824
+ \texttt{sello\_log\_url}. We address this metadata leakage in Section 8.
825
+
826
+ \hypertarget{independence-of-attestation}{%
827
+ \subsubsection{5.3 Independence of
828
+ attestation}\label{independence-of-attestation}}
829
+
830
+ \textbf{Claim:} An adversary that compromises the agent or controls the
831
+ operator cannot forge receipts.
832
+
833
+ \textbf{Argument:} Receipt validity requires a signature by a service's
834
+ private Ed25519 key. By the adversary model, the adversary does not
835
+ possess service signing keys. The adversary can submit arbitrary bytes
836
+ to the log, but those bytes will fail signature verification at step 6
837
+ of the owner's verification flow and be rejected. Forgery requires the
838
+ additional step of compromising at least one service's signing key,
839
+ which is a structurally harder attack than compromising the agent.
840
+
841
+ If a service's key is compromised, the adversary can forge receipts
842
+ signed by that key. The integrated-time revocation rule (Section 4.4)
843
+ bounds the damage to receipts whose log integrated time falls between
844
+ the compromise and the published \texttt{revoked\_at}. Receipts
845
+ predating the compromise remain trustworthy; receipts after
846
+ \texttt{revoked\_at} are rejected. This is weaker than perfect forward
847
+ security but is the best we can do without per-call key rotation, which
848
+ has its own costs.
849
+
850
+ \hypertarget{tamper-evidence-of-the-receipt-set}{%
851
+ \subsubsection{5.4 Tamper-evidence of the receipt
852
+ set}\label{tamper-evidence-of-the-receipt-set}}
853
+
854
+ \textbf{Claim:} Removal or modification of a logged receipt is
855
+ detectable.
856
+
857
+ \textbf{Argument:} The Merkle log structure ensures that any change to a
858
+ previously logged entry alters the Merkle root. Witness cosigning
859
+ ensures the root cannot be silently rewritten by the log operator. The
860
+ owner verifies inclusion proofs against the witnessed root.
861
+
862
+ This is a cryptographic guarantee, but it is a per-receipt guarantee,
863
+ not a set-completeness guarantee. Tamper-evidence applies to receipts
864
+ that are \emph{queried and returned}; it does not apply to receipts that
865
+ the log operator chooses not to return. We treat this distinction as
866
+ important enough to discuss separately, in Section 6.
867
+
868
+ \hypertarget{known-attacks-sello-does-not-prevent}{%
869
+ \subsubsection{5.5 Known attacks Sello does not
870
+ prevent}\label{known-attacks-sello-does-not-prevent}}
871
+
872
+ \textbf{Suppression attack.} The most fundamental limitation. If the
873
+ agent simply does not call any services, no receipts are produced. The
874
+ owner sees an empty log and cannot distinguish ``agent did nothing''
875
+ from ``agent did things off-network.'' Missing receipts are at best an
876
+ indirect signal of misbehavior. We sketch a possible mitigation in
877
+ Section 8 (mandatory heartbeat receipts from a designated anchor set)
878
+ but do not solve it in v0.1.
879
+
880
+ \textbf{Service collusion.} If a service colludes with the agent
881
+ operator to emit false receipts, Sello cannot detect this from a single
882
+ receipt. The mitigation is plurality: if a real action involved calls to
883
+ multiple services, only the genuine action has receipts from all of
884
+ them. A receipt purporting to record an action that no other involved
885
+ service witnessed is at minimum suspicious. We do not formalize this
886
+ mitigation; it is a defense-in-depth, not a cryptographic guarantee.
887
+
888
+ \textbf{Service replay.} A service holding its own signing key can
889
+ re-emit a previously observed event by re-encrypting and re-signing it,
890
+ producing a new envelope that passes verification but represents
891
+ activity that did not occur. HPKE single-shot uses fresh randomness per
892
+ call, so the new envelope is not byte-identical to the original. We
893
+ specify an owner-side deduplication rule based on the tuple
894
+ \texttt{(kid,\ sello\_token\_ref,\ timestamp-truncated-to-seconds,\ action-type,\ action-input-hash,\ action-output-hash)};
895
+ receipts sharing this tuple are treated as a single logical event.
896
+ Replays at higher temporal resolution than seconds are not caught by
897
+ this rule but are flagged as anomalous.
898
+
899
+ \textbf{Token reference enumeration.} The \texttt{sello\_token\_ref} is
900
+ a deterministic hash of the authorization token. Anyone who holds the
901
+ token can compute the same hash and query the log for all receipts
902
+ associated with it. Authorization tokens used with Sello must contain at
903
+ least 128 bits of unpredictable entropy. We discuss PIR-based
904
+ mitigations in Section 8.
905
+
906
+ \textbf{Owner key loss.} If the owner loses their HPKE private key, all
907
+ past receipts become permanently undecryptable. Key escrow and recovery
908
+ are out of scope for v0.1.
909
+
910
+ \begin{center}\rule{0.5\linewidth}{0.5pt}\end{center}
911
+
912
+ \hypertarget{completeness-and-retrieval}{%
913
+ \subsection{6 Completeness and
914
+ Retrieval}\label{completeness-and-retrieval}}
915
+
916
+ The security analysis in Section 5 establishes per-receipt cryptographic
917
+ guarantees: a returned receipt is unforgeable, its contents are
918
+ confidential, its tamper is detectable. These are necessary properties
919
+ for a verifiable record, but they are not sufficient for what an owner
920
+ actually wants, which is the \emph{complete set} of receipts associated
921
+ with a particular agent action or a particular time window. We treat the
922
+ gap between \emph{per-receipt verifiability} and \emph{set-completeness}
923
+ as a distinct concern from cryptographic security and discuss it here.
924
+
925
+ \textbf{The retrieval gap.} An inclusion proof answers ``is this receipt
926
+ in the log?'' It does not answer ``did the log return every matching
927
+ receipt?'' A log operator (or a metadata indexer in front of the log)
928
+ that returns ten receipts when twenty exist passes every cryptographic
929
+ check on each of the ten while withholding the other ten. The owner sees
930
+ a verifiable set; the owner does not see that the set is incomplete.
931
+
932
+ This matters for Sello in particular because owner-side discovery uses
933
+ \texttt{sello\_token\_ref} as the lookup key (Section 4.3). The owner
934
+ asks the log ``give me all receipts with this token reference.'' A
935
+ passive observer cannot tell whether the returned set is complete or
936
+ whether some receipts have been silently omitted. The receipts that are
937
+ returned remain verifiable. The receipts that are missing are missing.
938
+
939
+ \textbf{Sources of incompleteness.} There are three distinct failure
940
+ modes. The first is operator omission: the log operator or metadata
941
+ indexer chooses, accidentally or adversarially, not to return a matching
942
+ entry. The second is index incompleteness: the log's underlying Merkle
943
+ structure contains the entry, but the auxiliary metadata index used to
944
+ satisfy queries does not. Sigstore Rekor, for instance, supports queries
945
+ against indexed fields but does not index arbitrary COSE
946
+ protected-header values, so queries on \texttt{sello\_token\_ref} may
947
+ not be natively supported by Rekor v0 without additional infrastructure.
948
+ The third is owner-side query failure: the owner queries one log when
949
+ receipts exist in another, missing them entirely.
950
+
951
+ \textbf{What completeness requires.} Production deployments that need
952
+ completeness guarantees have three options. First, \emph{authenticated
953
+ query results}: the log can sign a response of the form ``these are the
954
+ entries matching this query, and the matching set is exhaustive as of
955
+ log tree size N.'' The SCITT working group's SCRAPI draft
956
+ \citep{scitt-scrapi} points in this direction. Second, \emph{full log
957
+ audit}: the owner downloads the full log (or relevant subsets) and scans
958
+ it locally, treating the log as a queryable database rather than asking
959
+ the operator for filtered results. This is expensive but defeats
960
+ operator omission entirely. Third, \emph{multi-log redundancy}: receipts
961
+ are submitted to multiple independent logs, and the owner queries all of
962
+ them; a single dishonest log cannot suppress a receipt without colluding
963
+ with every other log it was submitted to.
964
+
965
+ \textbf{What Sello v0.1 provides.} The reference implementation includes
966
+ a Rekor discovery adapter that explicitly documents itself as
967
+ discovery-only, not completeness-proving. The published
968
+ \texttt{sello\_log\_url} in the protected header tells the owner
969
+ \emph{which} log to query, but does not commit the log to returning
970
+ exhaustive results. A future version of Sello may specify an
971
+ authenticated query mechanism profiled against SCITT-SCRAPI; we do not
972
+ solve it in v0.1.
973
+
974
+ \textbf{Position summary.} Sello v0.1 provides strong per-receipt
975
+ security and discovery-aided retrieval. It does not provide
976
+ cryptographic set-completeness. Deployments where set-completeness
977
+ matters (audit reconstruction, regulatory evidence) should plan for one
978
+ of the three completeness mechanisms above.
979
+
980
+ \begin{center}\rule{0.5\linewidth}{0.5pt}\end{center}
981
+
982
+ \hypertarget{evaluation}{%
983
+ \subsection{7 Evaluation}\label{evaluation}}
984
+
985
+ We present first-party microbenchmarks of the cryptographic operations
986
+ Sello performs, measured with the reference implementation against a
987
+ local mock transparency log. The measurements establish steady-state
988
+ per-receipt costs at the service and the owner. Network latency for
989
+ submission to a hosted public log is discussed separately in §7.3
990
+ because it depends on the specific log operator's deployment rather than
991
+ on the Sello protocol itself.
992
+
993
+ \hypertarget{methodology}{%
994
+ \subsubsection{7.1 Methodology}\label{methodology}}
995
+
996
+ The reference implementation \citep{sello-repo} ships with a benchmark
997
+ tool (\texttt{src/cli/bench.ts}) that exercises the full receipt
998
+ lifecycle. For each iteration the bench: (1) constructs a verified
999
+ compact JWS authorization token, (2) creates a Sello receipt at the
1000
+ service side (HPKE seal of the CBOR-encoded receipt body to the owner's
1001
+ X25519 public key, followed by COSE\_Sign1 signing with the service's
1002
+ Ed25519 private key), (3) submits the signed envelope to an in-process
1003
+ mock transparency log that returns an inclusion proof, and (4) performs
1004
+ full owner-side verification (proof verification, registry resolution,
1005
+ COSE\_Sign1 signature verification, HPKE open, and receipt body
1006
+ validation). The mock log replaces network submission with deterministic
1007
+ in-process bookkeeping; this isolates the cryptographic costs from
1008
+ log-operator-specific network latency. Log submission latency to a
1009
+ hosted public log is discussed separately in §7.3.
1010
+
1011
+ The cryptographic primitives are Node.js bindings to the system OpenSSL:
1012
+ X25519 key agreement and Ed25519 signing via \texttt{node:crypto},
1013
+ ChaCha20-Poly1305 AEAD via \texttt{createCipheriv}, HKDF-SHA256 via
1014
+ \texttt{createHmac}, and SHA-256 via \texttt{createHash}. HPKE is
1015
+ implemented per RFC 9180 base mode with the suite specified in §2.1; the
1016
+ implementation is pinned to RFC 9180 Appendix A.2.1 test vectors and
1017
+ validated in the test suite.
1018
+
1019
+ Measurements were taken on an Apple M2 (8 physical cores, arm64), 24 GB
1020
+ RAM, macOS 26.2 (Darwin kernel 25.2.0), Node v24.16.0 with V8
1021
+ 13.6.233.17 and OpenSSL 3.5.6, plugged into AC power. The repository
1022
+ state was pinned to commit \texttt{8b0da95} at the time of measurement.
1023
+ System thermal pressure was ``Nominal'' throughout the run (Apple
1024
+ Silicon does not expose absolute CPU die temperature through
1025
+ \texttt{powermetrics}; thermal pressure is the first-party signal). The
1026
+ machine was a development laptop with 29 days of uptime and load
1027
+ averages of 6-10 during the run, representative of a working environment
1028
+ rather than a dedicated benchmark host; production deployments on
1029
+ lightly loaded hardware should see equal or tighter tails.
1030
+
1031
+ The bench prepends a 500-iteration warmup phase before any timed
1032
+ measurements to amortize JIT compilation and instruction-cache warmup,
1033
+ and invokes \texttt{global.gc()} once before warmup with the
1034
+ \texttt{-\/-expose-gc} flag to start each run from a clean
1035
+ garbage-collection state. We attempted to disable Spotlight indexing for
1036
+ the measurement window via \texttt{mdutil\ -a\ -i\ off} but this did not
1037
+ take effect on macOS 26 (likely due to System Integrity Protection
1038
+ policy); indexing remained enabled throughout. The tail-latency
1039
+ improvements over an earlier methodology iteration are therefore
1040
+ attributable to the warmup and GC controls rather than to Spotlight
1041
+ isolation.
1042
+
1043
+ For each iteration count \(N \in \{10, 100, 1000\}\), we executed the
1044
+ bench multiple times (3 runs at N=10, 5 runs at N=100, 10 runs at
1045
+ N=1000), with a 3-second sleep between runs to allow thermal effects to
1046
+ settle. Per-receipt operations (receipt creation, single-receipt
1047
+ verification) record every individual iteration duration using
1048
+ \texttt{performance.now()}. From each run we compute the per-run median,
1049
+ p95, and p99 over the iteration samples. We then take the median across
1050
+ runs of each statistic to be robust to outliers. Batch verification is
1051
+ one timed event per run, so we report the median across runs of the
1052
+ per-run total and the per-run per-receipt average.
1053
+
1054
+ \hypertarget{results}{%
1055
+ \subsubsection{7.2 Results}\label{results}}
1056
+
1057
+ The reference implementation produces fixed-size receipts independent of
1058
+ action input or output (which are referenced by SHA-256 hash, not
1059
+ included verbatim). Table 1 reports the wire-format sizes for the v0.1
1060
+ envelope.
1061
+
1062
+ \textbf{Table 1: Wire-format sizes.}
1063
+
1064
+ \begin{longtable}[]{@{}ll@{}}
1065
+ \toprule\noalign{}
1066
+ Component & Size \\
1067
+ \midrule\noalign{}
1068
+ \endhead
1069
+ \bottomrule\noalign{}
1070
+ \endlastfoot
1071
+ CBOR-encoded receipt body & 234 bytes \\
1072
+ COSE\_Sign1 protected header & 112 bytes \\
1073
+ HPKE payload (enc \textbar\textbar{} ciphertext) & 282 bytes \\
1074
+ Full COSE\_Sign1 envelope & 467 bytes \\
1075
+ Mock log proof (JSON) & 253 bytes \\
1076
+ \end{longtable}
1077
+
1078
+ A complete Sello envelope on the wire is just under half a kilobyte;
1079
+ this is independent of action size because action inputs and outputs are
1080
+ referenced only by their SHA-256 digests inside the receipt body.
1081
+
1082
+ Table 2 reports per-receipt cryptographic latency at three iteration
1083
+ counts. Each cell is the median across runs of the corresponding per-run
1084
+ statistic.
1085
+
1086
+ \textbf{Table 2: Per-receipt cryptographic latency (milliseconds).}
1087
+
1088
+ \begin{longtable}[]{@{}
1089
+ >{\raggedright\arraybackslash}p{(\columnwidth - 8\tabcolsep) * \real{0.2000}}
1090
+ >{\raggedright\arraybackslash}p{(\columnwidth - 8\tabcolsep) * \real{0.2000}}
1091
+ >{\raggedright\arraybackslash}p{(\columnwidth - 8\tabcolsep) * \real{0.2000}}
1092
+ >{\raggedright\arraybackslash}p{(\columnwidth - 8\tabcolsep) * \real{0.2000}}
1093
+ >{\raggedright\arraybackslash}p{(\columnwidth - 8\tabcolsep) * \real{0.2000}}@{}}
1094
+ \toprule\noalign{}
1095
+ \begin{minipage}[b]{\linewidth}\raggedright
1096
+ Operation
1097
+ \end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright
1098
+ N
1099
+ \end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright
1100
+ median (p50)
1101
+ \end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright
1102
+ p95
1103
+ \end{minipage} & \begin{minipage}[b]{\linewidth}\raggedright
1104
+ p99
1105
+ \end{minipage} \\
1106
+ \midrule\noalign{}
1107
+ \endhead
1108
+ \bottomrule\noalign{}
1109
+ \endlastfoot
1110
+ Receipt creation (service) & 10 & 0.496 & 0.741 & 0.770 \\
1111
+ Receipt creation (service) & 100 & 0.471 & 1.016 & 2.243 \\
1112
+ Receipt creation (service) & 1000 & \textbf{0.454} & \textbf{0.954} &
1113
+ \textbf{1.534} \\
1114
+ Verification, single (owner) & 10 & 0.393 & 1.072 & 1.245 \\
1115
+ Verification, single (owner) & 100 & 0.305 & 0.656 & 0.854 \\
1116
+ Verification, single (owner) & 1000 & \textbf{0.281} & \textbf{0.573} &
1117
+ \textbf{1.034} \\
1118
+ Verification, batch per receipt & 10 & 0.316 & n/a & n/a \\
1119
+ Verification, batch per receipt & 100 & 0.348 & n/a & n/a \\
1120
+ Verification, batch per receipt & 1000 & \textbf{0.320} & n/a & n/a \\
1121
+ \end{longtable}
1122
+
1123
+ We treat the N=1000 row as steady-state and report it as the headline
1124
+ result: a Sello-aware service adds \textbf{approximately 0.45 ms of
1125
+ median CPU work per agent call} (HPKE seal of the receipt body,
1126
+ COSE\_Sign1 signing, in-process log append), and an owner reconstructing
1127
+ activity does \textbf{approximately 0.28 ms of median CPU work per
1128
+ receipt} (Merkle proof verify, registry lookup, COSE\_Sign1 verify, HPKE
1129
+ open, receipt body decode and validate). A service handling 1000 calls
1130
+ per second per process would spend approximately 0.45 seconds of CPU per
1131
+ second on Sello receipt creation. An owner reconstructing a day of
1132
+ activity from 100,000 receipts can do so in approximately 32 seconds of
1133
+ CPU time using batch verification.
1134
+
1135
+ \textbf{Variance and tail behavior.} Across runs, the per-run median is
1136
+ tight: at N=1000, receipt creation medians range from 0.449 to 0.479 ms
1137
+ across ten runs (a 6.7\% spread), and single-receipt verification
1138
+ medians range from 0.275 to 0.292 ms (a 6.2\% spread). Tail latencies
1139
+ are also stable: across the ten N=1000 runs, all ten verify-one-receipt
1140
+ p99 values fell within 2x of the median p99, and nine of ten
1141
+ create-receipt p99 values fell within 2x of the median p99. The widest
1142
+ p99 observed for any single run was 3.073 ms for receipt creation and
1143
+ 1.487 ms for verification. Production deployments on dedicated hardware
1144
+ should see equal or tighter tails; the measurements here were taken on a
1145
+ working laptop with load averages of 6-10 during the run.
1146
+
1147
+ \textbf{Warmup effect.} Even with a 500-iteration warmup, a residual
1148
+ warmup effect remains visible at low iteration counts: single-receipt
1149
+ verification drops from 0.393 ms median at N=10 to 0.281 ms at N=1000, a
1150
+ 29\% reduction. This is consistent with V8 tiered compilation continuing
1151
+ to optimize hot code paths beyond the warmup window. The N=1000 numbers
1152
+ should be treated as steady-state; the N=10 numbers approximate the
1153
+ cold-start cost a process pays for its first few receipts.
1154
+
1155
+ \hypertarget{log-submission-latency-not-measured-first-party}{%
1156
+ \subsubsection{7.3 Log submission latency (not measured
1157
+ first-party)}\label{log-submission-latency-not-measured-first-party}}
1158
+
1159
+ Submission of a signed envelope to a hosted public transparency log adds
1160
+ a network round-trip and, for batched log designs like Sigstore Rekor
1161
+ v2, additional time for batch integration. The v0.1 reference
1162
+ implementation does not measure log submission latency first-party
1163
+ because it depends on the specific log operator's deployment
1164
+ characteristics rather than on the Sello protocol itself. In a
1165
+ production deployment, services should treat log submission as an
1166
+ asynchronous operation: the service can return the action response to
1167
+ the agent immediately and submit the receipt to the log in the
1168
+ background, optionally including the eventual inclusion proof in a
1169
+ subsequent receipt or an out-of-band channel. The protocol flow (§4.3)
1170
+ is compatible with this: the log-submission step is not on the critical
1171
+ path of the agent call.
1172
+
1173
+ \hypertarget{comparison-with-adjacent-systems}{%
1174
+ \subsubsection{7.4 Comparison with adjacent
1175
+ systems}\label{comparison-with-adjacent-systems}}
1176
+
1177
+ We compare Sello against the seven adjacent receipt protocols surveyed
1178
+ in §2.2, scored against the four design properties P1-P4.
1179
+
1180
+ \textbf{Table 3: Property comparison against adjacent receipt
1181
+ protocols.}
1182
+
1183
+ \begin{longtable}[]{@{}lllll@{}}
1184
+ \toprule\noalign{}
1185
+ System & P1 & P2 & P3 & P4 \\
1186
+ \midrule\noalign{}
1187
+ \endhead
1188
+ \bottomrule\noalign{}
1189
+ \endlastfoot
1190
+ Agent Receipts & no & no & no & no \\
1191
+ Signet (v0.10) & no & partial & no & no \\
1192
+ Pipelock & no & no & no & no \\
1193
+ Agent Passport System & no & no & no & no \\
1194
+ draft-farley-acta & no & no & no & no \\
1195
+ draft-nivalto-agentroa & no & no & yes & no \\
1196
+ Attested Intelligence & no & no & partial & no \\
1197
+ \textbf{Sello} & yes & yes & yes & yes \\
1198
+ \end{longtable}
1199
+
1200
+ Notes: ``no'' indicates the property is not present. ``partial''
1201
+ indicates a partial form of the property is present but does not meet
1202
+ the full design goal as specified in §3.3. Signet's encryption is
1203
+ symmetric and reuses the signing identity, which is not the same as P2's
1204
+ asymmetric encryption to an independent owner key. Attested Intelligence
1205
+ ships tamper-evident logging but the logs are point-to-point evidence
1206
+ bundles rather than public Merkle logs.
1207
+
1208
+ \begin{center}\rule{0.5\linewidth}{0.5pt}\end{center}
1209
+
1210
+ \hypertarget{discussion}{%
1211
+ \subsection{8 Discussion}\label{discussion}}
1212
+
1213
+ \hypertarget{limitations-sello-does-not-address-in-v0.1}{%
1214
+ \subsubsection{8.1 Limitations Sello does not address in
1215
+ v0.1}\label{limitations-sello-does-not-address-in-v0.1}}
1216
+
1217
+ Three known limitations bear emphasizing because they shape what Sello
1218
+ is and isn't useful for.
1219
+
1220
+ \textbf{Adoption-incentive problem.} The most fundamental limitation.
1221
+ Sello requires services to choose to emit receipts. Services have no
1222
+ inherent incentive to do so, especially in v0.1 before any regulatory
1223
+ mandate exists. We discuss possible incentive structures in Section 8.3
1224
+ but do not solve them. Sello is only useful if services adopt it; in
1225
+ 2026, that adoption is zero.
1226
+
1227
+ \textbf{Suppression attack.} Discussed in Section 5.5. The agent simply
1228
+ not calling services produces no receipts. We sketch a
1229
+ mandatory-heartbeat mitigation in Section 8.3 but do not specify it in
1230
+ v0.1.
1231
+
1232
+ \textbf{Server identity bootstrapping.} The JSON-file registry signed by
1233
+ a trust root is a placeholder. Production deployments need either
1234
+ Sigstore-Fulcio-style OIDC keyless identities, DNS-based key publication
1235
+ (DNSSEC or DNS-over-HTTPS with key records), or a Certificate
1236
+ Transparency-style PKI for services. We expect convergence on a
1237
+ Sigstore-Fulcio approach but defer the choice to v0.2.
1238
+
1239
+ \hypertarget{position-relative-to-existing-observability}{%
1240
+ \subsubsection{8.2 Position relative to existing
1241
+ observability}\label{position-relative-to-existing-observability}}
1242
+
1243
+ Sello is not a replacement for existing agent observability tools.
1244
+ Langfuse, LangSmith, and their peers tell the owner what the agent
1245
+ \emph{thought} it was doing: the prompts, the reasoning traces, the tool
1246
+ selection logic. This is essential information for debugging agent
1247
+ behavior and understanding why an agent did what it did.
1248
+
1249
+ Sello tells the owner what the world \emph{saw} the agent do. The two
1250
+ views are complementary. Mature deployments will want both. Sello
1251
+ receipts can serve as ground truth against which agent self-reports are
1252
+ checked; divergence between self-report and witnessed receipts is itself
1253
+ a high-signal anomaly. We discuss this divergence-detection use case in
1254
+ Section 8.3 as a future extension.
1255
+
1256
+ \hypertarget{future-extensions}{%
1257
+ \subsubsection{8.3 Future extensions}\label{future-extensions}}
1258
+
1259
+ We sketch four extensions that build on the v0.1 protocol. None are
1260
+ implemented; we present them as future-work directions and as
1261
+ illustrations of the design space the protocol opens.
1262
+
1263
+ \textbf{Regulator-as-second-recipient.} HPKE supports multi-recipient
1264
+ sealing via COSE\_Encrypt. A receipt could be sealed to two public keys:
1265
+ the owner's, and a regulator's published HPKE pubkey listed in a
1266
+ jurisdiction-bound registry (e.g., an EU AI Act Article 26
1267
+ deployer-registry entry). The regulator could decrypt during an audit
1268
+ without the owner's cooperation, but only with their specific key. This
1269
+ would make Sello a natural compliance primitive for high-risk AI systems
1270
+ under the EU AI Act \citep{euaiact}. We have not seen this mechanism in
1271
+ any existing protocol.
1272
+
1273
+ \textbf{Suppression detection via mandatory heartbeat receipts.} A
1274
+ subset of services designated as an ``anchor set'' in the agent's
1275
+ authorization token could be required to emit heartbeat receipts every
1276
+ \(N\) seconds whether or not the agent called them. Missing heartbeats
1277
+ during a session window would constitute positive evidence of
1278
+ suppression. The hard part is making heartbeats themselves
1279
+ non-suppressible (the operator can drop heartbeat traffic); we propose
1280
+ layered direct-to-owner heartbeats as a partial fix. We are not aware of
1281
+ any agent protocol that addresses suppression cryptographically.
1282
+
1283
+ \textbf{Inverse observability: divergence detection.} Combine Sello
1284
+ receipts with agent-emitted observability traces (Langfuse, LangSmith,
1285
+ etc.) and detect divergence between the two. If the agent's
1286
+ self-reported trace claims a call that no receipt witnesses, either the
1287
+ agent is lying or the service is colluding. The Verifiability-First
1288
+ paper \citep{gupta-verifiabilityfirst} proposes a related concept using
1289
+ a secondary ``Audit Agent'' but does not ground it in cryptographic
1290
+ witnessing. Sello receipts could provide exactly that grounding.
1291
+
1292
+ \textbf{Private information retrieval.} The \texttt{sello\_token\_ref}
1293
+ enumeration attack (Section 5.5) could be mitigated by Private
1294
+ Information Retrieval over the log. PIR over Certificate Transparency
1295
+ logs has been studied \citep{kales-pir-ct}; applying the same techniques
1296
+ to Sello is straightforward but adds significant cost. A PIR mode in
1297
+ v0.2 would be appropriate for high-privacy deployments.
1298
+
1299
+ \hypertarget{the-adoption-incentive-question}{%
1300
+ \subsubsection{8.4 The adoption-incentive
1301
+ question}\label{the-adoption-incentive-question}}
1302
+
1303
+ We close with the most honest question. Why would any service emit Sello
1304
+ receipts? In 2026, the answer is ``they wouldn't.'' There is no
1305
+ regulatory mandate, no commercial pressure, no end-user demand.
1306
+
1307
+ Three incentive structures could change this:
1308
+
1309
+ \begin{enumerate}
1310
+ \def\labelenumi{\arabic{enumi}.}
1311
+ \item
1312
+ \textbf{Regulatory mandate.} EU AI Act Article 12 requires automatic
1313
+ logging for high-risk AI systems; Article 26 places six-month
1314
+ retention obligations on deployers. Sello is a natural primitive for
1315
+ satisfying these obligations cryptographically. If the EU Commission
1316
+ or a similar body specifies a receipt format, Sello (or something like
1317
+ it) becomes mandatory and adoption follows.
1318
+ \item
1319
+ \textbf{Agent-commerce settlement coupling.} Agent payment protocols
1320
+ (Stripe Machine Payments, Skyfire KYAPay, the Cloudflare/Stripe agent
1321
+ commerce protocol) are emerging in 2026. If receipt emission is
1322
+ coupled to settlement, so that services that emit receipts settle and
1323
+ services that don't, don't, adoption is automatic. This is a market
1324
+ design problem more than a protocol design problem.
1325
+ \item
1326
+ \textbf{Trust premium.} Services that emit receipts may command higher
1327
+ trust and therefore higher prices in agent-mediated marketplaces. This
1328
+ requires owners to value receipts enough to pay for them, which
1329
+ requires educated users; bootstrapping is slow but possible.
1330
+ \end{enumerate}
1331
+
1332
+ We do not solve the incentive problem in this paper. We note that all
1333
+ three paths require Sello (or an equivalent protocol) to exist first.
1334
+ The protocol is the precondition; the incentive structure is the next
1335
+ problem.
1336
+
1337
+ \begin{center}\rule{0.5\linewidth}{0.5pt}\end{center}
1338
+
1339
+ \hypertarget{conclusion}{%
1340
+ \subsection{9 Conclusion}\label{conclusion}}
1341
+
1342
+ AI agent observability is structurally compromised when the agent is the
1343
+ source of truth for its own behavior. The fix is the same architectural
1344
+ inversion humans have used since 3000 BCE: the party recording an event
1345
+ should be independent of the party being recorded.
1346
+
1347
+ Sello applies this inversion to AI agent actions through four combined
1348
+ properties: receiver-side signing by the called service, HPKE encryption
1349
+ to an owner public key bound to the authorization token, publication to
1350
+ a witness-cosigned Merkle log, and owner-side discovery by token
1351
+ reference. The combination is novel to our knowledge; no surveyed system
1352
+ combines all four. The cryptographic primitives are standard
1353
+ (COSE\_Sign1, HPKE, Ed25519, transparency logs). The contribution is the
1354
+ architectural composition and the JWS owner-key binding that makes it
1355
+ work.
1356
+
1357
+ We have been explicit about what Sello does not solve: the suppression
1358
+ attack, service collusion, the adoption-incentive problem. The sketched
1359
+ extensions (regulator-recipient mode, heartbeat-based suppression
1360
+ detection, inverse observability for trace verification) are not
1361
+ required for v0.1 to be useful, and we have not built them.
1362
+
1363
+ The protocol and reference implementation are published at
1364
+ https://sello.build under CC BY 4.0. Review, adversarial testing, and
1365
+ pull requests are welcome. Where alignment is natural with adjacent
1366
+ projects (Signet, the SCITT working group, AgentROA), we'll seek
1367
+ collaboration. The architecture matters more than which project ships it
1368
+ first; what matters is that AI agent observability stops trusting the
1369
+ agent to be its own witness.
1370
+
1371
+ The agent is not the right narrator of its own actions. The services it
1372
+ touches are.
1373
+
1374
+ \begin{center}\rule{0.5\linewidth}{0.5pt}\end{center}
1375
+
1376
+ \hypertarget{acknowledgments}{%
1377
+ \subsection{Acknowledgments}\label{acknowledgments}}
1378
+
1379
+ This work benefited from public writing by William Hou (Signet), Tymofii
1380
+ Pidlisnyi (APS), Otto Jongerius (Agent Receipts), Joseph Michalak
1381
+ (AgentROA), and Jing Zhang (Right to History). Any errors are mine.
1382
+
1383
+ \begin{center}\rule{0.5\linewidth}{0.5pt}\end{center}
1384
+
1385
+ \bibliography{refs.bib}
1386
+
1387
+ \end{document}