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,245 @@
1
+ @techreport{RFC6962,
2
+ author = {Laurie, B. and Langley, A. and Kasper, E.},
3
+ title = {Certificate Transparency},
4
+ institution = {IETF},
5
+ type = {RFC},
6
+ number = {6962},
7
+ year = {2013},
8
+ month = jun
9
+ }
10
+
11
+ @techreport{RFC9162,
12
+ author = {Laurie, B. and Messeri, E. and Stradling, R.},
13
+ title = {Certificate Transparency Version 2.0},
14
+ institution = {IETF},
15
+ type = {RFC},
16
+ number = {9162},
17
+ year = {2021},
18
+ month = dec
19
+ }
20
+
21
+ @techreport{RFC7515,
22
+ author = {Jones, M. and Bradley, J. and Sakimura, N.},
23
+ title = {JSON Web Signature (JWS)},
24
+ institution = {IETF},
25
+ type = {RFC},
26
+ number = {7515},
27
+ year = {2015},
28
+ month = may
29
+ }
30
+
31
+ @techreport{RFC8610,
32
+ author = {Birkholz, H. and Vigano, C. and Bormann, C.},
33
+ title = {Concise {Data} {Definition} {Language} ({CDDL}): {A} {Notational} {Convention} to {Express} {Concise} {Binary} {Object} {Representation} ({CBOR}) and {JSON} {Data} {Structures}},
34
+ institution = {IETF},
35
+ type = {RFC},
36
+ number = {8610},
37
+ year = {2019},
38
+ month = jun
39
+ }
40
+
41
+ @techreport{RFC9052,
42
+ author = {Schaad, J.},
43
+ title = {{CBOR} {Object} {Signing} and {Encryption} ({COSE}): {Structures} and {Process}},
44
+ institution = {IETF},
45
+ type = {RFC},
46
+ number = {9052},
47
+ year = {2022},
48
+ month = aug
49
+ }
50
+
51
+ @techreport{RFC9180,
52
+ author = {Barnes, R. and Bhargavan, K. and Lipp, B. and Wood, C.},
53
+ title = {Hybrid {Public} {Key} {Encryption}},
54
+ institution = {IETF},
55
+ type = {RFC},
56
+ number = {9180},
57
+ year = {2022},
58
+ month = feb
59
+ }
60
+
61
+ @techreport{RFC9449,
62
+ author = {Fett, D. and Campbell, B. and Bradley, J. and Lodderstedt, T. and Jones, M. and Waite, D.},
63
+ title = {{OAuth} 2.0 {Demonstrating} {Proof} of {Possession} ({DPoP})},
64
+ institution = {IETF},
65
+ type = {RFC},
66
+ number = {9449},
67
+ year = {2023},
68
+ month = sep
69
+ }
70
+
71
+ @article{Heinrich2021,
72
+ author = {Heinrich, A. and Stute, M. and Kornhuber, T. and Hollick, M.},
73
+ title = {Who {Can} {Find} {My} {Devices}? {Security} and {Privacy} of {Apple}'s {Crowd}-{Sourced} {Bluetooth} {Location} {Tracking} {System}},
74
+ journal = {Proceedings on Privacy Enhancing Technologies},
75
+ volume = {2021},
76
+ number = {3},
77
+ pages = {227--245},
78
+ year = {2021}
79
+ }
80
+
81
+ @inproceedings{Syta2016,
82
+ author = {Syta, E. and Tamas, I. and Visher, D. and Wolinsky, D. I. and Jovanovic, P. and Gasser, L. and Gailly, N. and Khoffi, I. and Ford, B.},
83
+ title = {Keeping {Authorities} `{Honest} or {Bust}' with {Decentralized} {Witness} {Cosigning}},
84
+ booktitle = {IEEE Symposium on Security and Privacy},
85
+ pages = {526--545},
86
+ year = {2016}
87
+ }
88
+
89
+ @article{bernstein2012ed25519,
90
+ author = {Bernstein, D. J. and Duif, N. and Lange, T. and Schwabe, P. and Yang, B.},
91
+ title = {High-speed high-security signatures},
92
+ journal = {Journal of Cryptographic Engineering},
93
+ volume = {2},
94
+ number = {2},
95
+ year = {2012}
96
+ }
97
+
98
+ @misc{sigstore-rekor,
99
+ author = {{The Sigstore Authors}},
100
+ title = {Rekor: {Software} {Supply} {Chain} {Transparency} {Log}},
101
+ howpublished = {\url{https://github.com/sigstore/rekor}},
102
+ year = {2024}
103
+ }
104
+
105
+ @misc{sello-repo,
106
+ author = {Figuera, J.},
107
+ title = {Sello: {A} protocol for receiver-attested confidential receipts for {AI} agent actions},
108
+ howpublished = {Reference implementation, \url{https://github.com/juanfiguera/sello}},
109
+ year = {2026}
110
+ }
111
+
112
+ @techreport{scitt-architecture,
113
+ author = {Birkholz, H. and Delignat-Lavaud, A. and Fournet, C. and Deshpande, Y. and Lasker, S.},
114
+ title = {An {Architecture} for {Trustworthy} and {Transparent} {Digital} {Supply} {Chains}},
115
+ institution = {IETF},
116
+ type = {Internet-Draft},
117
+ number = {draft-ietf-scitt-architecture},
118
+ year = {2026}
119
+ }
120
+
121
+ @techreport{scitt-scrapi,
122
+ author = {Steele, O. and Birkholz, H.},
123
+ title = {{SCITT} {Reference} {APIs}},
124
+ institution = {IETF},
125
+ type = {Internet-Draft},
126
+ number = {draft-ietf-scitt-scrapi},
127
+ year = {2026}
128
+ }
129
+
130
+ @techreport{scitt-ccf,
131
+ author = {Delignat-Lavaud, A. and others},
132
+ title = {{SCITT} {Receipts}: {CCF} {Profile}},
133
+ institution = {IETF},
134
+ type = {Internet-Draft},
135
+ number = {draft-ietf-scitt-receipts-ccf-profile},
136
+ year = {2026}
137
+ }
138
+
139
+ @misc{agentreceipts,
140
+ author = {Jongerius, O.},
141
+ title = {Agent {Receipts}},
142
+ howpublished = {\url{https://agentreceipts.ai}},
143
+ year = {2025--2026}
144
+ }
145
+
146
+ @misc{signet,
147
+ author = {Hou, W.},
148
+ title = {Signet: {Cryptographic} {Action} {Receipts} for {AI} {Agents}},
149
+ howpublished = {\url{https://github.com/Prismer-AI/signet}},
150
+ year = {2025--2026}
151
+ }
152
+
153
+ @misc{pipelock,
154
+ author = {{PipeLab}},
155
+ title = {Pipelock: {AI} {Agent} {Security} {Gateway}},
156
+ howpublished = {\url{https://pipelab.org}},
157
+ year = {2026}
158
+ }
159
+
160
+ @misc{aps,
161
+ author = {Pidlisnyi, T.},
162
+ title = {Agent {Passport} {System}},
163
+ howpublished = {\url{https://github.com/aeoess/agent-passport-system}},
164
+ year = {2025--2026}
165
+ }
166
+
167
+ @techreport{farley-acta,
168
+ author = {Farley, T.},
169
+ title = {Signed {Decision} {Receipts} for {Machine}-to-{Machine} {Access} {Control}},
170
+ institution = {IETF},
171
+ type = {Internet-Draft},
172
+ number = {draft-farley-acta-signed-receipts},
173
+ year = {2026}
174
+ }
175
+
176
+ @techreport{nivalto-agentroa,
177
+ author = {Michalak, J.},
178
+ title = {Agent {Route} {Origin} {Authorization} ({AgentROA}): {A} {Cryptographic} {Policy} {Enforcement} {Framework} for {AI} {Agent} {Actions}},
179
+ institution = {IETF},
180
+ type = {Internet-Draft},
181
+ number = {draft-nivalto-agentroa-route-authorization},
182
+ year = {2026}
183
+ }
184
+
185
+ @misc{attestedintelligence,
186
+ author = {{Attested Intelligence Holdings LLC}},
187
+ title = {Attested {Governance} {Artifacts}: {Public} {Comment} on {Docket} {NIST}-2025-0035},
188
+ year = {2026},
189
+ month = mar
190
+ }
191
+
192
+ @techreport{kamimura-scitt,
193
+ author = {Kamimura, S.},
194
+ title = {{SCITT} {Profile} for {Financial} {Trading} {Audit} {Trails}},
195
+ institution = {IETF},
196
+ type = {Internet-Draft},
197
+ number = {draft-kamimura-scitt-vcp},
198
+ year = {2026}
199
+ }
200
+
201
+ @article{zhang-righttohistory,
202
+ author = {Zhang, J.},
203
+ title = {Right to {History}: {A} {Sovereignty} {Kernel} for {Verifiable} {AI} {Agent} {Execution}},
204
+ journal = {arXiv preprint arXiv:2602.20214},
205
+ year = {2026},
206
+ month = feb
207
+ }
208
+
209
+ @article{gupta-verifiabilityfirst,
210
+ author = {Gupta, A.},
211
+ title = {Verifiability-{First} {Agents}: {Provable} {Observability} and {Lightweight} {Audit} {Agents} for {Controlling} {Autonomous} {LLM} {Systems}},
212
+ journal = {arXiv preprint arXiv:2512.17259},
213
+ year = {2025},
214
+ month = dec
215
+ }
216
+
217
+ @article{basu-toolreceipts,
218
+ author = {Basu, A.},
219
+ title = {Tool {Receipts}, {Not} {Zero}-{Knowledge} {Proofs}: {Practical} {Hallucination} {Detection} for {AI} {Agents}},
220
+ journal = {arXiv preprint arXiv:2603.10060},
221
+ year = {2026},
222
+ month = mar
223
+ }
224
+
225
+ @inproceedings{casper-blackbox,
226
+ author = {Casper, Stephen and Ezell, Carson and Siegmann, Charlotte and Kolt, Noam and Curtis, Taylor Lynn and Bucknall, Benjamin and Haupt, Andreas and Wei, Kevin and Scheurer, J{\'e}r{\'e}my and Hobbhahn, Marius and Sharkey, Lee and Krishna, Satyapriya and Von Hagen, Marvin and Alberti, Silas and Chan, Alan and Sun, Qinyi and Gerovitch, Michael and Bau, David and Tegmark, Max and Krueger, David and Hadfield-Menell, Dylan},
227
+ title = {Black-Box {Access} is {Insufficient} for {Rigorous} {AI} {Audits}},
228
+ booktitle = {Proceedings of the 2024 ACM Conference on Fairness, Accountability, and Transparency (FAccT)},
229
+ pages = {2254--2272},
230
+ year = {2024}
231
+ }
232
+
233
+ @inproceedings{kales-pir-ct,
234
+ author = {Kales, D. and Omolola, O. and Ramacher, S.},
235
+ title = {Revisiting {User} {Privacy} for {Certificate} {Transparency}},
236
+ booktitle = {IEEE European Symposium on Security and Privacy},
237
+ year = {2019}
238
+ }
239
+
240
+ @misc{euaiact,
241
+ key = {EU AI Act},
242
+ title = {Regulation ({EU}) 2024/1689 of the {European} {Parliament} and of the {Council} laying down harmonised rules on artificial intelligence ({Artificial} {Intelligence} {Act})},
243
+ year = {2024},
244
+ month = jul
245
+ }
@@ -0,0 +1,24 @@
1
+ # Performance And Receipt Size
2
+
3
+ Sello includes a small local benchmark for tracking rough receipt size and implementation performance:
4
+
5
+ ```sh
6
+ node --run bench
7
+ node --run bench -- --iterations 500 --warmup 500 --json
8
+ ```
9
+
10
+ The benchmark uses the reference implementation with fixed local keys and the mock transparency log. By default it runs 500 warmup iterations before measuring. It reports:
11
+
12
+ - CBOR receipt body size.
13
+ - COSE protected-header size.
14
+ - HPKE payload size.
15
+ - Full COSE_Sign1 envelope size.
16
+ - Mock proof JSON size.
17
+ - Average receipt creation time.
18
+ - Average one-receipt verification time.
19
+ - Batch verification time and per-receipt average.
20
+ - Mean, median, p95, p99, and standard deviation for per-receipt creation and one-receipt verification samples.
21
+
22
+ These numbers are useful for local regression tracking and integration planning. They are not formal cryptographic benchmarks: results vary by CPU, Node version, OS, and thermal state, and the mock log is not a live Rekor deployment.
23
+
24
+ For production capacity planning, measure against the real service middleware, real action payload canonicalization, the chosen log adapter, and the deployment's key storage path.
@@ -0,0 +1,56 @@
1
+ # Release Checklist
2
+
3
+ Use this checklist before publishing a Sello npm release.
4
+
5
+ ## Preflight
6
+
7
+ - Confirm `git status --short` is clean.
8
+ - Confirm `node -v` is `v24.0.0` or newer.
9
+ - If multiple Node versions are installed, confirm `PATH` resolves `node` to Node 24 before running package scripts.
10
+ - Confirm `package.json` has the intended version.
11
+ - Confirm `README.md` and `docs/sdk-quickstart.md` match the current CLI and examples.
12
+ - Confirm the paper link and local PDF are current, if the paper changed.
13
+
14
+ ## Local Verification
15
+
16
+ ```bash
17
+ node --run test
18
+ npm pack --dry-run
19
+ ```
20
+
21
+ Fresh clone smoke test:
22
+
23
+ ```bash
24
+ tmpdir=$(mktemp -d)
25
+ git clone https://github.com/juanfiguera/sello.git "$tmpdir/sello"
26
+ cd "$tmpdir/sello"
27
+ node -v # must be v24.0.0 or newer
28
+ node --run test
29
+ npm pack --dry-run
30
+ node --experimental-strip-types src/cli/sello.ts --help
31
+ node --experimental-strip-types src/cli/sello.ts dev --dry-run
32
+ ```
33
+
34
+ ## npm Verification
35
+
36
+ ```bash
37
+ npm whoami
38
+ npm view sello version
39
+ npm publish --dry-run
40
+ ```
41
+
42
+ If the package name is already published, confirm the local version is greater than the registry version before publishing.
43
+
44
+ ## Publish
45
+
46
+ ```bash
47
+ npm publish
48
+ git tag v$(node -p "require('./package.json').version")
49
+ git push origin main --tags
50
+ ```
51
+
52
+ After publishing:
53
+
54
+ - Confirm `npm view sello version` shows the new version.
55
+ - Confirm `npx sello --help` works from a clean temp directory.
56
+ - Confirm GitHub Actions passes on `main`.
@@ -0,0 +1,214 @@
1
+ # Stripe-Style Sello SDK Integration Plan
2
+
3
+ ## Summary
4
+
5
+ Build the first Sello SDK around a complete, Stripe-like loop:
6
+
7
+ 1. Add one import.
8
+ 2. Call `sello.service()`.
9
+ 3. Wrap an existing tool handler.
10
+ 4. Run the tool.
11
+ 5. See verified logged actions.
12
+
13
+ Quickstart service code:
14
+
15
+ ```ts
16
+ import { sello } from "sello";
17
+
18
+ const receipts = sello.service();
19
+
20
+ export const createEvent = receipts.tool("calendar.create_event", async (request) => {
21
+ return calendar.events.create(request);
22
+ });
23
+ ```
24
+
25
+ Quickstart viewing:
26
+
27
+ ```bash
28
+ npx sello actions --token <agent-token>
29
+ ```
30
+
31
+ Local dev can also show:
32
+
33
+ ```text
34
+ http://localhost:8787/actions
35
+ ```
36
+
37
+ Sello must work without `sello.build`. Self-hosting is first-class. Hosted `sello.build` is optional convenience.
38
+
39
+ ## Configuration Model
40
+
41
+ Keep service emission and owner viewing separate.
42
+
43
+ ### Service Runtime Env
44
+
45
+ Used by the app/tool server that emits receipts.
46
+
47
+ Self-hosted development:
48
+
49
+ ```bash
50
+ SELLO_SERVICE_ID=calendar.example.com/mcp/v1
51
+ SELLO_SERVICE_KEY=sello_dev_...
52
+ SELLO_TOKEN_ISSUER_PUBLIC_KEY=...
53
+ SELLO_LOG_URL=https://localhost:8787/api
54
+ SELLO_LOG_ENDPOINT=http://localhost:8787/api
55
+ SELLO_SUBMIT_MODE=background
56
+ ```
57
+
58
+ Self-hosted production:
59
+
60
+ ```bash
61
+ SELLO_SERVICE_ID=calendar.example.com/mcp/v1
62
+ SELLO_SERVICE_KEY=sello_live_local_...
63
+ SELLO_TOKEN_ISSUER_JWKS=https://auth.example.com/.well-known/jwks.json
64
+ SELLO_LOG_URL=https://logs.example.com/api
65
+ SELLO_SUBMIT_MODE=background
66
+ ```
67
+
68
+ Hosted `sello.build`:
69
+
70
+ ```bash
71
+ SELLO_SECRET_KEY=sello_test_...
72
+ SELLO_SECRET_KEY=sello_live_...
73
+ ```
74
+
75
+ Hosted mode uses one server-side secret to fetch service config and enable local receipt signing by default. Managed remote signing must be a later explicit opt-in because it changes the trust model.
76
+
77
+ ### Viewer Runtime Env
78
+
79
+ Used by the owner CLI, local UI, or hosted dashboard to verify/decrypt actions.
80
+
81
+ ```bash
82
+ SELLO_OWNER_KEY=sello_owner_...
83
+ SELLO_REGISTRY_URL=https://registry.example.com/sello.json
84
+ SELLO_REGISTRY_SIGNATURE=...
85
+ SELLO_REGISTRY_TRUST_ROOT_PUBLIC_KEY=...
86
+ SELLO_LOG_URL=https://logs.example.com/api
87
+ ```
88
+
89
+ The owner key must not be required in the service process.
90
+
91
+ ## Public API
92
+
93
+ ```ts
94
+ const receipts = sello.service();
95
+ const receipts = sello.service("calendar.example.com/mcp/v1");
96
+ const receipts = sello.service({ service, serviceKey, tokenIssuer, log, submit });
97
+ ```
98
+
99
+ ```ts
100
+ const wrapped = receipts.tool(actionType, handler, options);
101
+ await receipts.flush();
102
+ ```
103
+
104
+ Tool behavior:
105
+
106
+ - Verify token before handler execution.
107
+ - Emit `success`, `error`, or `denied` receipts.
108
+ - Return handler response unchanged.
109
+ - Rethrow handler errors.
110
+ - Use canonical JSON hashing by default.
111
+ - Submit in background by default.
112
+ - Support `submit.mode: "await"` for strict durability.
113
+ - Support explicit custom log adapters for self-hosting.
114
+
115
+ ## Logged Actions UX
116
+
117
+ ```bash
118
+ npx sello actions --token <agent-token>
119
+ ```
120
+
121
+ Behavior:
122
+
123
+ - Loads viewer config, not service config.
124
+ - Computes `sello_token_ref`.
125
+ - Queries trusted logs.
126
+ - Verifies inclusion, service signature, revocation, HPKE decryption, and receipt body shape.
127
+ - Prints verified actions and rejected receipts.
128
+
129
+ Local dev:
130
+
131
+ ```bash
132
+ npx sello dev
133
+ npx sello actions
134
+ ```
135
+
136
+ In dev mode, `sello dev` remembers the latest dev token and owner key in ignored local state so `npx sello actions` works without extra flags.
137
+
138
+ Privacy rule:
139
+
140
+ - Public logs store encrypted receipts.
141
+ - Viewing action details requires the owner private key or delegated viewer key.
142
+ - Self-hosted CLI decrypts locally.
143
+ - Hosted dashboard must use client-side decryption or explicit delegated viewer keys.
144
+
145
+ ## Phase Plan
146
+
147
+ ### Phase 0: Baseline And SDK Contract
148
+
149
+ - Write SDK examples into docs first.
150
+ - Define env names, config precedence, and friendly errors.
151
+ - Document service env versus viewer env.
152
+ - Record deferred items: production Rekor proof verification, hosted dashboard, managed signing, durable queue.
153
+ - Run `node --run test` and `node --run pack:check`.
154
+ - Security audit: check the SDK contract does not weaken receiver-side signing or owner-side decryption.
155
+
156
+ ### Phase 1: Env-First SDK Facade
157
+
158
+ - Add `sello.service()`.
159
+ - Add env config loader.
160
+ - Add key normalization for `Uint8Array` and encoded string inputs.
161
+ - Add explicit config override path.
162
+ - Add friendly missing-config errors.
163
+ - Tests: env loading, service id override, explicit config override, hosted config selection, no owner key required for service emission.
164
+ - Security audit: check secret handling, env precedence, errors, logging, and hosted/self-hosted boundaries.
165
+
166
+ ### Phase 2: Receipt Build/Submit Split And Background Publisher
167
+
168
+ - Refactor receipt creation into build/encrypt/sign first, append second.
169
+ - Keep existing `createReceipt()` behavior by composing build + append.
170
+ - Add bounded background publisher with concurrency, `flush()`, `onSubmitError`, and `onDrop`.
171
+ - Default to background submission.
172
+ - Support `submit.mode: "await"`.
173
+ - Tests: existing receipt tests, built envelope verification, background latency, `flush()`, overflow, failures, await mode, concurrency.
174
+ - Security audit: check durability wording, queue bounds, memory pressure, failure handling, and unchanged cryptography.
175
+
176
+ ### Phase 3: Tool Wrapper MVP
177
+
178
+ - Implement `receipts.tool(actionType, handler, options)`.
179
+ - Default token extraction, input hashing, output hashing, and error hashing.
180
+ - Support custom token extraction and canonicalizers.
181
+ - Preserve handler semantics exactly.
182
+ - Tests: success, error, denied, invalid token, custom extraction, custom canonicalizers, unchanged response, MCP compatibility.
183
+ - Security audit: check token verification ordering, plaintext leakage, and service identity binding.
184
+
185
+ ### Phase 4: Logs And Action Viewing
186
+
187
+ - Add `sello.logs.memory(url)` for local tests/dev.
188
+ - Add `sello.logs.http(url, options?)` for self-hosted Sello-compatible log servers.
189
+ - Add `npx sello actions --token <token>`.
190
+ - Add local dev `/actions` page.
191
+ - Action viewing uses owner-side verification and decryption.
192
+ - Tests: memory log, HTTP append/query, CLI output, dev-mode token fallback, rejected reason codes, `/actions` states, no action details without owner/delegated key.
193
+ - Security audit: check owner-side decryption, no plaintext in public logs, and safe rejected-receipt display.
194
+
195
+ ### Phase 5: Docs Polish And First-Run Flow
196
+
197
+ - Add README section: **Add Sello in a Few Lines**.
198
+ - Add `docs/sdk-quickstart.md`.
199
+ - Document self-hosted development, self-hosted production, `sello.build` development, and `sello.build` production.
200
+ - Document action viewing, token requirement, and privacy model.
201
+ - Keep advanced explicit config separate from quickstart.
202
+ - Tests: `node --run test`, `node --run pack:check`, manual quickstart run, docs do not require `sello.build`.
203
+ - Security audit: review README, quickstart, CLI help, and examples with the full plan in hand.
204
+
205
+ ## Assumptions
206
+
207
+ - MVP ships inside the current `sello` package.
208
+ - One excellent generic tool wrapper beats many shallow adapters.
209
+ - Testing is required for every phase before the next phase starts.
210
+ - A security audit is required after every phase before the next phase starts.
211
+ - Each auditor receives the full plan, current phase scope, deferred-item list, and threat model.
212
+ - The service process emits receipts but does not need the owner private key.
213
+ - Local/self-hosted usage is first-class.
214
+ - `sello.build` is optional convenience, not a protocol requirement.
@@ -0,0 +1,115 @@
1
+ # Sello SDK Quickstart
2
+
3
+ Sello's SDK is designed to make the first receipt easy: wrap a tool handler, run it, and inspect verified actions.
4
+
5
+ ```ts
6
+ import { sello } from "sello";
7
+
8
+ const receipts = sello.service();
9
+
10
+ export const createEvent = receipts.tool("calendar.create_event", async (request) => {
11
+ return calendar.events.create(request);
12
+ });
13
+ ```
14
+
15
+ The service process emits receipts. It does not need the owner private key.
16
+
17
+ ## Local Development
18
+
19
+ Inside this repo, start the local log and action viewer:
20
+
21
+ ```bash
22
+ node --run dev
23
+ ```
24
+
25
+ In another terminal, run the repo's wrapped tool example:
26
+
27
+ ```bash
28
+ node --run example:tool
29
+ node --run actions
30
+ ```
31
+
32
+ For an MCP-shaped `tools/call` boundary, run:
33
+
34
+ ```bash
35
+ node --run example:mcp
36
+ node --run actions
37
+ ```
38
+
39
+ or open:
40
+
41
+ ```text
42
+ http://localhost:8787/actions
43
+ ```
44
+
45
+ Both examples read `.sello/dev.json`, wrap a fake calendar handler, submit one encrypted receipt, and let the owner verify it locally.
46
+
47
+ For your own tool server, copy the printed service env:
48
+
49
+ ```bash
50
+ SELLO_SERVICE_ID=calendar.example.com/mcp/v1
51
+ SELLO_SERVICE_KEY=sello_dev_...
52
+ SELLO_TOKEN_ISSUER_PUBLIC_KEY=...
53
+ SELLO_LOG_URL=https://localhost:8787/api
54
+ SELLO_LOG_ENDPOINT=http://localhost:8787/api
55
+ SELLO_SUBMIT_MODE=background
56
+ ```
57
+
58
+ Call your wrapped tool with the printed dev token. Then view actions:
59
+
60
+ ```bash
61
+ npx sello actions
62
+ ```
63
+
64
+ ## Self-Hosted Production
65
+
66
+ Use your own Sello-compatible log server:
67
+
68
+ ```bash
69
+ SELLO_SERVICE_ID=calendar.example.com/mcp/v1
70
+ SELLO_SERVICE_KEY=sello_live_local_...
71
+ SELLO_TOKEN_ISSUER_JWKS=https://auth.example.com/.well-known/jwks.json
72
+ SELLO_LOG_URL=https://logs.example.com/api
73
+ SELLO_SUBMIT_MODE=background
74
+ ```
75
+
76
+ View actions from an owner-controlled environment:
77
+
78
+ ```bash
79
+ SELLO_OWNER_KEY=sello_owner_live_...
80
+ SELLO_REGISTRY_URL=https://registry.example.com/sello.json
81
+ SELLO_REGISTRY_SIGNATURE=...
82
+ SELLO_REGISTRY_TRUST_ROOT_PUBLIC_KEY=...
83
+ SELLO_LOG_URL=https://logs.example.com/api
84
+ npx sello actions --token <agent-token>
85
+ ```
86
+
87
+ ## Hosted Sello
88
+
89
+ Hosted mode keeps the application code the same:
90
+
91
+ ```bash
92
+ SELLO_SECRET_KEY=sello_test_...
93
+ ```
94
+
95
+ The secret is server-side only. Hosted mode is optional; Sello does not require `sello.build`.
96
+
97
+ ## Advanced Explicit Config
98
+
99
+ You can bypass env config entirely:
100
+
101
+ ```ts
102
+ const receipts = sello.service({
103
+ service: "calendar.example.com/mcp/v1",
104
+ serviceKey: { kid, privateKey },
105
+ tokenIssuer: tokenIssuerPublicKey,
106
+ log: sello.logs.memory("https://localhost:8787/api"),
107
+ submit: { mode: "await" },
108
+ });
109
+ ```
110
+
111
+ Use explicit config for tests, embedded runtimes, or custom self-hosted deployments.
112
+
113
+ ## Privacy
114
+
115
+ Public logs store encrypted receipts. Viewing action details requires the owner private key or an explicitly delegated viewer key. The CLI decrypts locally; hosted dashboards must use client-side decryption or delegated viewer keys.