sello 0.1.10 → 0.1.12
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.
- package/README.md +83 -130
- package/docs/paper/notarized-agents.md +1 -1
- package/docs/paper/notarized-agents.tex +1 -1
- package/docs/protocol-walkthrough.md +74 -0
- package/docs/release-checklist.md +19 -3
- package/docs/sdk-quickstart.md +33 -3
- package/docs/sdk-security-audit.md +1 -1
- package/package.json +17 -17
- package/sdks/README.md +17 -0
- package/docs/sdk-build-plan.md +0 -214
- /package/{examples → sdks/typescript/examples}/mcp-minimal-server.ts +0 -0
- /package/{examples → sdks/typescript/examples}/mcp-tool-server.ts +0 -0
- /package/{examples → sdks/typescript/examples}/quickstart-tool.ts +0 -0
- /package/{fixtures → sdks/typescript/fixtures}/vectors/.gitkeep +0 -0
- /package/{fixtures → sdks/typescript/fixtures}/vectors/sello-v0.1.json +0 -0
- /package/{src → sdks/typescript/src}/cbor.ts +0 -0
- /package/{src → sdks/typescript/src}/cli/bench.ts +0 -0
- /package/{src → sdks/typescript/src}/cli/demo.ts +0 -0
- /package/{src → sdks/typescript/src}/cli/sello.ts +0 -0
- /package/{src → sdks/typescript/src}/cose/protected-header.ts +0 -0
- /package/{src → sdks/typescript/src}/cose/sign1.ts +0 -0
- /package/{src → sdks/typescript/src}/crypto/ed25519.ts +0 -0
- /package/{src → sdks/typescript/src}/crypto/identifiers.ts +0 -0
- /package/{src → sdks/typescript/src}/hpke/base.ts +0 -0
- /package/{src → sdks/typescript/src}/hpke/receipt.ts +0 -0
- /package/{src → sdks/typescript/src}/index.ts +0 -0
- /package/{src → sdks/typescript/src}/log/canonical-url.ts +0 -0
- /package/{src → sdks/typescript/src}/log/mock-log.ts +0 -0
- /package/{src → sdks/typescript/src}/log/rekor.ts +0 -0
- /package/{src → sdks/typescript/src}/log/types.ts +0 -0
- /package/{src → sdks/typescript/src}/mcp/middleware.ts +0 -0
- /package/{src → sdks/typescript/src}/owner/verify.ts +0 -0
- /package/{src → sdks/typescript/src}/receipt/body.ts +0 -0
- /package/{src → sdks/typescript/src}/registry/json-registry.ts +0 -0
- /package/{src → sdks/typescript/src}/sdk/index.ts +0 -0
- /package/{src → sdks/typescript/src}/sdk/keys.ts +0 -0
- /package/{src → sdks/typescript/src}/sdk/logs.ts +0 -0
- /package/{src → sdks/typescript/src}/sdk/publisher.ts +0 -0
- /package/{src → sdks/typescript/src}/sdk/service.ts +0 -0
- /package/{src → sdks/typescript/src}/service/create-receipt.ts +0 -0
- /package/{src → sdks/typescript/src}/token/jws-profile.ts +0 -0
package/README.md
CHANGED
|
@@ -1,6 +1,31 @@
|
|
|
1
|
-

|
|
2
|
-
|
|
3
|
-
|
|
1
|
+

|
|
2
|
+
|
|
3
|
+
<h1 align="center">Sello</h1>
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<a href="https://github.com/juanfiguera/sello/actions/workflows/ci.yml"><img alt="build status" src="https://img.shields.io/github/actions/workflow/status/juanfiguera/sello/ci.yml?branch=main&style=flat-square&label=build&labelColor=0b1011&color=e8f7ef"></a>
|
|
7
|
+
<a href="https://www.npmjs.com/package/sello"><img alt="npm version" src="https://img.shields.io/npm/v/sello?style=flat-square&label=npm&labelColor=0b1011&color=e8f7ef"></a>
|
|
8
|
+
<a href="https://pypi.org/project/sello/"><img alt="PyPI version" src="https://img.shields.io/pypi/v/sello?style=flat-square&label=pypi&labelColor=0b1011&color=e8f7ef"></a>
|
|
9
|
+
<a href="https://www.npmjs.com/package/sello"><img alt="npm downloads" src="https://img.shields.io/npm/dm/sello?style=flat-square&label=downloads&labelColor=0b1011&color=e8f7ef"></a>
|
|
10
|
+
<a href="LICENSE"><img alt="license Apache-2.0" src="https://img.shields.io/npm/l/sello?style=flat-square&label=license&labelColor=0b1011&color=e8f7ef"></a>
|
|
11
|
+
<a href="package.json"><img alt="Node.js 22.7 or newer" src="https://img.shields.io/badge/node-%3E%3D22.7-e8f7ef?style=flat-square&labelColor=0b1011"></a>
|
|
12
|
+
<a href="sdks/python/pyproject.toml"><img alt="Python 3.9 or newer" src="https://img.shields.io/badge/python-%3E%3D3.9-e8f7ef?style=flat-square&labelColor=0b1011"></a>
|
|
13
|
+
<a href="https://arxiv.org/abs/2606.04193"><img alt="arXiv 2606.04193" src="https://img.shields.io/badge/arXiv-2606.04193-e8f7ef?style=flat-square&labelColor=0b1011"></a>
|
|
14
|
+
</p>
|
|
15
|
+
|
|
16
|
+
<p align="center">
|
|
17
|
+
<a href="#try-it">Quickstart</a> ·
|
|
18
|
+
<a href="#add-sello-to-a-tool">Add Sello</a> ·
|
|
19
|
+
<a href="sdks/README.md">SDKs</a> ·
|
|
20
|
+
<a href="#see-logged-actions">Actions</a> ·
|
|
21
|
+
<a href="#how-it-works">How It Works</a> ·
|
|
22
|
+
<a href="#learn-more">Learn More</a> ·
|
|
23
|
+
<a href="SPEC.md">Protocol</a> ·
|
|
24
|
+
<a href="https://arxiv.org/abs/2606.04193">Paper</a> ·
|
|
25
|
+
<a href="SECURITY.md">Security</a> ·
|
|
26
|
+
<a href="CONTRIBUTING.md">Contributing</a> ·
|
|
27
|
+
<a href="#license">License</a>
|
|
28
|
+
</p>
|
|
4
29
|
|
|
5
30
|
Sello is a protocol for independently-verifiable records of AI agent actions.
|
|
6
31
|
|
|
@@ -36,76 +61,16 @@ Then open:
|
|
|
36
61
|
http://localhost:8787/actions
|
|
37
62
|
```
|
|
38
63
|
|
|
39
|
-
|
|
64
|
+
`sello dev` creates local keys, a demo token, a service registry, and a local transparency log under `.sello/`. The log stores encrypted receipt entries, not plaintext action details.
|
|
40
65
|
|
|
41
|
-
|
|
42
|
-
npx --yes sello init-demo
|
|
43
|
-
```
|
|
66
|
+
## Add Sello to a Tool
|
|
44
67
|
|
|
45
|
-
|
|
68
|
+
TypeScript:
|
|
46
69
|
|
|
47
70
|
```bash
|
|
48
|
-
|
|
49
|
-
npx --yes sello call-http-demo
|
|
71
|
+
npm install sello
|
|
50
72
|
```
|
|
51
73
|
|
|
52
|
-
## What Just Happened?
|
|
53
|
-
|
|
54
|
-
`sello dev` created a local owner key, service key, token, registry, and transparency log. The demo tool or route verified the token before running the handler. After the handler ran, the service signed an encrypted receipt for the action it observed. The local log stored the encrypted receipt, not plaintext action details. `sello actions` fetched the receipt, verified the log entry and service signature, decrypted it with the owner key, and printed the owner's view.
|
|
55
|
-
|
|
56
|
-
Local dev state lives under `.sello/`. The dev log is stored as encrypted receipt entries in `.sello/dev-log.jsonl`, so receipts survive restarting `sello dev` while staying out of git.
|
|
57
|
-
|
|
58
|
-
## Why Sello?
|
|
59
|
-
|
|
60
|
-
Most agent logs are written by the same system whose behavior they describe. If the agent, runtime, or operator is compromised, those logs can be incomplete or false.
|
|
61
|
-
|
|
62
|
-
Sello moves receipt-writing to the services the agent calls. The service was present for the action, but it is outside the agent's own logging path. The architectural inversion is simple: the signer is not the agent or its operator, but the receiver that observed the action.
|
|
63
|
-
|
|
64
|
-
## What Sello Gives You
|
|
65
|
-
|
|
66
|
-
Sello helps an owner verify that:
|
|
67
|
-
|
|
68
|
-
- A specific service signed a specific receipt.
|
|
69
|
-
- The receipt was encrypted for the owner.
|
|
70
|
-
- The receipt was included in a trusted transparency log.
|
|
71
|
-
- The receipt body was not modified after signing.
|
|
72
|
-
|
|
73
|
-
Sello does not prove that the agent called every service it should have called, that every service is honest, or that unauthenticated log indexes returned complete results. Those limits are intentional and documented in the spec.
|
|
74
|
-
|
|
75
|
-
## Repository Status
|
|
76
|
-
|
|
77
|
-
This repository currently contains:
|
|
78
|
-
|
|
79
|
-
- [SPEC.md](SPEC.md): the Sello protocol draft.
|
|
80
|
-
- A TypeScript reference implementation in [`src/`](src/).
|
|
81
|
-
- Implementation-backed v0.1 test vectors in [`fixtures/vectors/sello-v0.1.json`](fixtures/vectors/sello-v0.1.json).
|
|
82
|
-
- Security review notes in [`docs/security-review.md`](docs/security-review.md).
|
|
83
|
-
- SDK security audit notes in [`docs/sdk-security-audit.md`](docs/sdk-security-audit.md).
|
|
84
|
-
|
|
85
|
-
The implementation includes a local end-to-end demo, compact JWS token verification, COSE_Sign1 receipt envelopes, HPKE encryption, a mock transparency log, a Rekor discovery adapter, owner verification, an MCP middleware prototype, security review notes, and a local benchmark. Live Rekor proof verification and production identity operations are still future work.
|
|
86
|
-
|
|
87
|
-
📄 **Paper:** [Notarized Agents: Receiver-Attested Confidential Receipts for AI Agent Actions](https://arxiv.org/abs/2606.04193) (arXiv:2606.04193, submitted June 2026). Local PDF: [docs/paper/notarized-agents.pdf](docs/paper/notarized-agents.pdf).
|
|
88
|
-
|
|
89
|
-
## Start Here
|
|
90
|
-
|
|
91
|
-
| Goal | Read |
|
|
92
|
-
|------|------|
|
|
93
|
-
| Add Sello in a few lines | [SDK Quickstart](docs/sdk-quickstart.md) |
|
|
94
|
-
| Emit your first receipt | `npx --yes sello dev`, then `npx --yes sello emit-demo` |
|
|
95
|
-
| Wrap one HTTP route | `npx --yes sello init-http-demo`, then `npx --yes sello call-http-demo` |
|
|
96
|
-
| Try a wrapped tool locally | `node --run dev`, then `node --run example:tool` |
|
|
97
|
-
| Try an MCP-style tool call | `node --run dev`, then `node --run example:mcp` |
|
|
98
|
-
| See a minimal MCP integration | [examples/mcp-minimal-server.ts](examples/mcp-minimal-server.ts) |
|
|
99
|
-
| Understand the protocol | [SPEC.md](SPEC.md) Quick Start |
|
|
100
|
-
| Run the local demo | `node --run demo` |
|
|
101
|
-
| Run the test suite | `node --run test` |
|
|
102
|
-
| Measure local size/performance | `node --run bench -- --json` |
|
|
103
|
-
| Emit receipts from a service | [SPEC.md](SPEC.md) §§3.1, 4.1, 5, 6.2 |
|
|
104
|
-
| Verify receipts as an owner | [SPEC.md](SPEC.md) §§4.2, 5, 6.2, 7.1 |
|
|
105
|
-
| Build the reference implementation | Start with "The First 10 Minutes" below |
|
|
106
|
-
|
|
107
|
-
## Add Sello in a Few Lines
|
|
108
|
-
|
|
109
74
|
```ts
|
|
110
75
|
import { sello } from "sello";
|
|
111
76
|
|
|
@@ -116,96 +81,84 @@ export const createEvent = receipts.tool("calendar.create_event", async (request
|
|
|
116
81
|
});
|
|
117
82
|
```
|
|
118
83
|
|
|
119
|
-
|
|
84
|
+
Python:
|
|
120
85
|
|
|
121
86
|
```bash
|
|
122
|
-
|
|
87
|
+
pip install sello
|
|
123
88
|
```
|
|
124
89
|
|
|
125
|
-
|
|
90
|
+
```py
|
|
91
|
+
import sello
|
|
126
92
|
|
|
127
|
-
|
|
128
|
-
SELLO_ACTION_TOKEN=eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9...
|
|
129
|
-
```
|
|
130
|
-
|
|
131
|
-
You usually do not need to copy it. `npx sello actions` reads the latest dev token from `.sello/dev.json`. Use `--token` when you want to inspect receipts for a specific agent authorization token from your own system.
|
|
93
|
+
receipts = sello.service()
|
|
132
94
|
|
|
133
|
-
|
|
95
|
+
@receipts.tool("calendar.create_event")
|
|
96
|
+
def create_event(request):
|
|
97
|
+
return calendar.events.create(request)
|
|
98
|
+
```
|
|
134
99
|
|
|
135
|
-
|
|
100
|
+
In local dev, `npx sello dev` supplies the config this snippet needs. In production, configure your service with a service id, service signing key, token issuer, and log URL:
|
|
136
101
|
|
|
137
102
|
```bash
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
node --run actions
|
|
103
|
+
SELLO_SERVICE_ID=calendar.example.com/mcp/v1
|
|
104
|
+
SELLO_SERVICE_KEY=sello_live_local_...
|
|
105
|
+
SELLO_TOKEN_ISSUER_JWKS=https://auth.example.com/.well-known/jwks.json
|
|
106
|
+
SELLO_LOG_URL=https://logs.example.com/api
|
|
107
|
+
SELLO_SUBMIT_MODE=background
|
|
144
108
|
```
|
|
145
109
|
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
For an MCP-shaped `tools/call` boundary, run `node --run example:mcp` instead of `node --run example:tool`.
|
|
110
|
+
Sello works with your own log server. Using `sello.build` is an optional convenience, not a protocol requirement.
|
|
149
111
|
|
|
150
|
-
|
|
112
|
+
To scaffold a tiny emitter or HTTP route:
|
|
151
113
|
|
|
152
|
-
|
|
114
|
+
```bash
|
|
115
|
+
npx --yes sello init-demo
|
|
116
|
+
npx --yes sello init-http-demo
|
|
117
|
+
```
|
|
153
118
|
|
|
154
|
-
##
|
|
119
|
+
## See Logged Actions
|
|
155
120
|
|
|
156
|
-
|
|
121
|
+
```bash
|
|
122
|
+
npx sello actions
|
|
123
|
+
```
|
|
157
124
|
|
|
158
|
-
|
|
159
|
-
2. Generate a fixed service Ed25519 signing key.
|
|
160
|
-
3. Create one mock compact JWS token containing `owner_hpke_pk` and `sello_logs`.
|
|
161
|
-
4. Have the service create one receipt for one fake action.
|
|
162
|
-
5. Store the receipt in a mock log under `sello_token_ref`.
|
|
163
|
-
6. Have the owner fetch, verify, and decrypt the receipt.
|
|
125
|
+
In local dev, `sello actions` reads the latest dev token and owner key from `.sello/dev.json`. To inspect actions for a specific agent token, pass it explicitly:
|
|
164
126
|
|
|
165
|
-
|
|
127
|
+
```bash
|
|
128
|
+
npx sello actions --token <agent-token>
|
|
129
|
+
```
|
|
166
130
|
|
|
167
|
-
|
|
131
|
+
The token is the same authorization token the agent used when it called services. Sello hashes the exact token bytes into `sello_token_ref`, queries trusted logs, verifies matching receipts, and decrypts them with the owner key.
|
|
168
132
|
|
|
169
|
-
|
|
170
|
-
{
|
|
171
|
-
"service": "example.com/tool/v1",
|
|
172
|
-
"action-type": "tools/call",
|
|
173
|
-
"result-status": "success",
|
|
174
|
-
"verified": true
|
|
175
|
-
}
|
|
176
|
-
```
|
|
133
|
+
Public logs store encrypted receipts. Viewing action details requires the owner private key or an explicitly delegated viewer key.
|
|
177
134
|
|
|
178
|
-
##
|
|
135
|
+
## How It Works
|
|
179
136
|
|
|
180
|
-
|
|
137
|
+
Most agent logs are written by the same system whose behavior they describe. If the agent, runtime, or operator is compromised, those logs can be incomplete or false.
|
|
181
138
|
|
|
182
|
-
|
|
183
|
-
2. Read `owner_hpke_pk` and `sello_logs` from the verified token.
|
|
184
|
-
3. Compute `sello_token_ref = SHA-256(raw compact JWS bytes)`.
|
|
185
|
-
4. Build a CBOR receipt body describing the action.
|
|
186
|
-
5. Encrypt the receipt body to the owner with HPKE.
|
|
187
|
-
6. Sign the COSE_Sign1 envelope with the service key.
|
|
188
|
-
7. Publish the envelope to an owner-trusted transparency log.
|
|
139
|
+
Sello moves receipt-writing to the services the agent calls. The service was present for the action, but it is outside the agent's own logging path.
|
|
189
140
|
|
|
190
|
-
|
|
141
|
+
1. The agent calls a service with an authorization token.
|
|
142
|
+
2. The service verifies the token, runs the action, and signs an encrypted receipt for what it observed.
|
|
143
|
+
3. A transparency log stores the encrypted receipt.
|
|
144
|
+
4. The owner later fetches, verifies, and decrypts the receipt.
|
|
191
145
|
|
|
192
|
-
|
|
146
|
+
Sello helps an owner verify that a specific service signed a specific receipt, the receipt was encrypted for the owner, the receipt was included in a trusted transparency log, and the receipt body was not modified after signing.
|
|
193
147
|
|
|
194
|
-
|
|
148
|
+
Sello does not prove that the agent called every service it should have called, that every service is honest, or that unauthenticated log indexes returned complete results. Those limits are intentional and documented in the spec.
|
|
195
149
|
|
|
196
|
-
|
|
150
|
+
## Learn More
|
|
197
151
|
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
9. Validate and display the receipt body.
|
|
152
|
+
- [SDK Quickstart](docs/sdk-quickstart.md): local dev, HTTP demo, self-hosted config, and hosted config.
|
|
153
|
+
- [SDKs](sdks/README.md): TypeScript and Python package layout.
|
|
154
|
+
- [Python SDK](sdks/python/README.md): Python package install command, scope, and test command.
|
|
155
|
+
- [Protocol Walkthrough](docs/protocol-walkthrough.md): the primitive receipt loop for implementers.
|
|
156
|
+
- [SPEC.md](SPEC.md): the Sello protocol draft.
|
|
157
|
+
- [Notarized Agents paper](https://arxiv.org/abs/2606.04193): design rationale, threat model, and prior art.
|
|
158
|
+
- [sdks/typescript/examples/mcp-minimal-server.ts](sdks/typescript/examples/mcp-minimal-server.ts): a small MCP-shaped integration.
|
|
159
|
+
- [docs/security-review.md](docs/security-review.md) and [docs/sdk-security-audit.md](docs/sdk-security-audit.md): current review notes.
|
|
207
160
|
|
|
208
|
-
|
|
161
|
+
The TypeScript SDK is published on [npm](https://www.npmjs.com/package/sello) and lives in [`sdks/typescript/`](sdks/typescript/). The Python SDK is published on [PyPI](https://pypi.org/project/sello/) and lives in [`sdks/python/`](sdks/python/). Live Rekor proof verification and production identity operations are still future work.
|
|
209
162
|
|
|
210
163
|
## Core Terms
|
|
211
164
|
|
|
@@ -235,7 +188,7 @@ Much of this prior work surfaced after Sello's design had already converged on s
|
|
|
235
188
|
|
|
236
189
|
## Feedback
|
|
237
190
|
|
|
238
|
-
Issues and pull requests are welcome. This is an early draft; adversarial review is the point.
|
|
191
|
+
Issues and pull requests are welcome. This is an early draft; adversarial review is the point. See [CONTRIBUTING.md](CONTRIBUTING.md) for contribution notes and [SECURITY.md](SECURITY.md) for sensitive reports.
|
|
239
192
|
|
|
240
193
|
## License
|
|
241
194
|
|
|
@@ -323,7 +323,7 @@ We present first-party microbenchmarks of the cryptographic operations Sello per
|
|
|
323
323
|
|
|
324
324
|
### 7.1 Methodology
|
|
325
325
|
|
|
326
|
-
The reference implementation [@sello-repo] ships with a benchmark tool (`src/cli/bench.ts`) that exercises the full receipt lifecycle. For each iteration the bench: (1) constructs a verified compact JWS authorization token, (2) creates a Sello receipt at the service side (HPKE seal of the CBOR-encoded receipt body to the owner's X25519 public key, followed by COSE_Sign1 signing with the service's Ed25519 private key), (3) submits the signed envelope to an in-process mock transparency log that returns an inclusion proof, and (4) performs full owner-side verification (proof verification, registry resolution, COSE_Sign1 signature verification, HPKE open, and receipt body validation). The mock log replaces network submission with deterministic in-process bookkeeping; this isolates the cryptographic costs from log-operator-specific network latency. Log submission latency to a hosted public log is discussed separately in §7.3.
|
|
326
|
+
The reference implementation [@sello-repo] ships with a benchmark tool (`sdks/typescript/src/cli/bench.ts`) that exercises the full receipt lifecycle. For each iteration the bench: (1) constructs a verified compact JWS authorization token, (2) creates a Sello receipt at the service side (HPKE seal of the CBOR-encoded receipt body to the owner's X25519 public key, followed by COSE_Sign1 signing with the service's Ed25519 private key), (3) submits the signed envelope to an in-process mock transparency log that returns an inclusion proof, and (4) performs full owner-side verification (proof verification, registry resolution, COSE_Sign1 signature verification, HPKE open, and receipt body validation). The mock log replaces network submission with deterministic in-process bookkeeping; this isolates the cryptographic costs from log-operator-specific network latency. Log submission latency to a hosted public log is discussed separately in §7.3.
|
|
327
327
|
|
|
328
328
|
The cryptographic primitives are Node.js bindings to the system OpenSSL: X25519 key agreement and Ed25519 signing via `node:crypto`, ChaCha20-Poly1305 AEAD via `createCipheriv`, HKDF-SHA256 via `createHmac`, and SHA-256 via `createHash`. HPKE is implemented per RFC 9180 base mode with the suite specified in §2.1; the implementation is pinned to RFC 9180 Appendix A.2.1 test vectors and validated in the test suite.
|
|
329
329
|
|
|
@@ -994,7 +994,7 @@ on the Sello protocol itself.
|
|
|
994
994
|
\subsubsection{7.1 Methodology}\label{methodology}}
|
|
995
995
|
|
|
996
996
|
The reference implementation \citep{sello-repo} ships with a benchmark
|
|
997
|
-
tool (\texttt{src/cli/bench.ts}) that exercises the full receipt
|
|
997
|
+
tool (\texttt{sdks/typescript/src/cli/bench.ts}) that exercises the full receipt
|
|
998
998
|
lifecycle. For each iteration the bench: (1) constructs a verified
|
|
999
999
|
compact JWS authorization token, (2) creates a Sello receipt at the
|
|
1000
1000
|
service side (HPKE seal of the CBOR-encoded receipt body to the owner's
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# Protocol Walkthrough
|
|
2
|
+
|
|
3
|
+
This guide is for people implementing Sello itself or studying the receipt flow below the SDK. If you only want to try Sello or add it to a service, start with the README or [`docs/sdk-quickstart.md`](sdk-quickstart.md).
|
|
4
|
+
|
|
5
|
+
## Goal
|
|
6
|
+
|
|
7
|
+
Build the smallest complete Sello loop:
|
|
8
|
+
|
|
9
|
+
1. One mock action happens.
|
|
10
|
+
2. The service creates one encrypted signed receipt.
|
|
11
|
+
3. A mock transparency log stores it under `sello_token_ref`.
|
|
12
|
+
4. The owner fetches, verifies, and decrypts it.
|
|
13
|
+
|
|
14
|
+
Run the complete loop first:
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
node --run demo
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
The runnable source is [`sdks/typescript/src/cli/demo.ts`](../sdks/typescript/src/cli/demo.ts).
|
|
21
|
+
|
|
22
|
+
## Local Pieces
|
|
23
|
+
|
|
24
|
+
The primitive loop needs these pieces:
|
|
25
|
+
|
|
26
|
+
| Piece | Local helper | Why it exists |
|
|
27
|
+
|-------|--------------|---------------|
|
|
28
|
+
| Owner key | `generateHpkeKeyPair()` | The public key goes in the token. The private key decrypts receipts later. |
|
|
29
|
+
| Service key | `generateEd25519KeyPair()` | The service signs receipts for actions it observed. |
|
|
30
|
+
| Token issuer key | `generateEd25519KeyPair()` | The issuer signs the mock agent token. |
|
|
31
|
+
| Transparency log | `new MockTransparencyLog(...)` | The log stores encrypted signed receipts by `sello_token_ref`. |
|
|
32
|
+
| Service registry | `loadSignedRegistry(...)` | The owner uses it to resolve service public keys and revocation status. |
|
|
33
|
+
|
|
34
|
+
Start with the owner key:
|
|
35
|
+
|
|
36
|
+
```ts
|
|
37
|
+
import { base64urlEncode, generateHpkeKeyPair } from "sello";
|
|
38
|
+
|
|
39
|
+
const owner = generateHpkeKeyPair();
|
|
40
|
+
const ownerHpkePk = base64urlEncode(owner.publicKey);
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Put `ownerHpkePk` in the token's `owner_hpke_pk` claim. Keep `owner.privateKey` for the owner verifier.
|
|
44
|
+
|
|
45
|
+
Then create the other local pieces:
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
import { generateEd25519KeyPair, MockTransparencyLog } from "sello";
|
|
49
|
+
|
|
50
|
+
const service = generateEd25519KeyPair();
|
|
51
|
+
const tokenIssuer = generateEd25519KeyPair();
|
|
52
|
+
const trustRoot = generateEd25519KeyPair();
|
|
53
|
+
const log = new MockTransparencyLog("https://rekor.example.com/api");
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## Flow
|
|
57
|
+
|
|
58
|
+
1. Sign a compact JWS token with `signSelloJwsToken(...)`.
|
|
59
|
+
2. Include `owner_hpke_pk` and `sello_logs` in the signed token.
|
|
60
|
+
3. Create a receipt with `createReceiptFromJwsToken(...)`.
|
|
61
|
+
4. Verify with `verifyReceipts(...)` using the same raw token, owner private key, mock log, and service registry.
|
|
62
|
+
|
|
63
|
+
You know the loop works when the owner can print one verified receipt:
|
|
64
|
+
|
|
65
|
+
```json
|
|
66
|
+
{
|
|
67
|
+
"service": "example.com/tool/v1",
|
|
68
|
+
"action-type": "tools/call",
|
|
69
|
+
"result-status": "success",
|
|
70
|
+
"verified": true
|
|
71
|
+
}
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Do not start with Rekor, MCP middleware, distributed identity, or CLI polish. Those become much easier once one local receipt works end to end.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Release Checklist
|
|
2
2
|
|
|
3
|
-
Use this checklist before publishing a Sello
|
|
3
|
+
Use this checklist before publishing a Sello release.
|
|
4
4
|
|
|
5
5
|
## Preflight
|
|
6
6
|
|
|
@@ -8,6 +8,7 @@ Use this checklist before publishing a Sello npm release.
|
|
|
8
8
|
- Confirm `node -v` is `v22.7.0` or newer.
|
|
9
9
|
- If multiple Node versions are installed, confirm `PATH` resolves `node` to Node 22.7 or newer before running package scripts.
|
|
10
10
|
- Confirm `package.json` has the intended version.
|
|
11
|
+
- Confirm `sdks/python/pyproject.toml` has the intended version when publishing Python.
|
|
11
12
|
- Confirm `README.md` and `docs/sdk-quickstart.md` match the current CLI and examples.
|
|
12
13
|
- Confirm the paper link and local PDF are current, if the paper changed.
|
|
13
14
|
|
|
@@ -28,8 +29,8 @@ node -v # must be v22.7.0 or newer
|
|
|
28
29
|
node --run test
|
|
29
30
|
node --run package:test
|
|
30
31
|
npm pack --dry-run
|
|
31
|
-
node --experimental-strip-types src/cli/sello.ts --help
|
|
32
|
-
node --experimental-strip-types src/cli/sello.ts dev --dry-run
|
|
32
|
+
node --experimental-strip-types sdks/typescript/src/cli/sello.ts --help
|
|
33
|
+
node --experimental-strip-types sdks/typescript/src/cli/sello.ts dev --dry-run
|
|
33
34
|
```
|
|
34
35
|
|
|
35
36
|
## npm Verification
|
|
@@ -42,6 +43,19 @@ npm publish --dry-run
|
|
|
42
43
|
|
|
43
44
|
If the package name is already published, confirm the local version is greater than the registry version before publishing.
|
|
44
45
|
|
|
46
|
+
## PyPI Verification
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
python -m pip install --upgrade build twine
|
|
50
|
+
cd sdks/python
|
|
51
|
+
rm -rf dist
|
|
52
|
+
python -m build
|
|
53
|
+
python -m twine check dist/*
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
The PyPI project uses trusted publishing from `.github/workflows/release.yml`.
|
|
57
|
+
Publishing a GitHub Release for a version tag triggers the PyPI publish job. Use the manual workflow dispatch only when you intentionally want to publish Python without creating a GitHub Release; rerunning the same version is safe because the workflow skips files that already exist on PyPI.
|
|
58
|
+
|
|
45
59
|
## Publish
|
|
46
60
|
|
|
47
61
|
```bash
|
|
@@ -53,5 +67,7 @@ git push origin main --tags
|
|
|
53
67
|
After publishing:
|
|
54
68
|
|
|
55
69
|
- Confirm `npm view sello version` shows the new version.
|
|
70
|
+
- Publish a GitHub Release for the pushed tag so PyPI trusted publishing runs.
|
|
71
|
+
- Confirm `python -m pip index versions sello` shows the new version after PyPI publishing.
|
|
56
72
|
- Confirm `npx sello --help` works from a clean temp directory.
|
|
57
73
|
- Confirm GitHub Actions passes on `main`.
|
package/docs/sdk-quickstart.md
CHANGED
|
@@ -2,7 +2,15 @@
|
|
|
2
2
|
|
|
3
3
|
Sello's SDK is designed to make the first receipt easy: wrap a tool handler, run it, and inspect verified actions.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
The local demo CLI and action viewer require Node.js 22.7 or newer. The Python SDK requires Python 3.9 or newer.
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
TypeScript:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm install sello
|
|
13
|
+
```
|
|
6
14
|
|
|
7
15
|
```ts
|
|
8
16
|
import { sello } from "sello";
|
|
@@ -14,6 +22,22 @@ export const createEvent = receipts.tool("calendar.create_event", async (request
|
|
|
14
22
|
});
|
|
15
23
|
```
|
|
16
24
|
|
|
25
|
+
Python:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pip install sello
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
```py
|
|
32
|
+
import sello
|
|
33
|
+
|
|
34
|
+
receipts = sello.service()
|
|
35
|
+
|
|
36
|
+
@receipts.tool("calendar.create_event")
|
|
37
|
+
def create_event(request):
|
|
38
|
+
return calendar.events.create(request)
|
|
39
|
+
```
|
|
40
|
+
|
|
17
41
|
The service process emits receipts. It does not need the owner private key.
|
|
18
42
|
|
|
19
43
|
## Local Development
|
|
@@ -54,6 +78,12 @@ npx --yes sello actions
|
|
|
54
78
|
|
|
55
79
|
Local dev state lives under `.sello/`. The encrypted dev log is stored in `.sello/dev-log.jsonl`, so receipts survive restarting `sello dev` without being committed to git.
|
|
56
80
|
|
|
81
|
+
## Troubleshooting
|
|
82
|
+
|
|
83
|
+
- **Port already in use:** run `npx sello dev --port 8791`.
|
|
84
|
+
- **No actions found:** make sure `sello dev` is running from the same project folder where you emitted the receipt.
|
|
85
|
+
- **Missing token:** run `npx sello dev` first so `.sello/dev.json` exists.
|
|
86
|
+
|
|
57
87
|
Inside this repo, start the local log and action viewer:
|
|
58
88
|
|
|
59
89
|
```bash
|
|
@@ -80,9 +110,9 @@ or open:
|
|
|
80
110
|
http://localhost:8787/actions
|
|
81
111
|
```
|
|
82
112
|
|
|
83
|
-
Both examples read `.sello/dev.json`, wrap a
|
|
113
|
+
Both examples read `.sello/dev.json`, wrap a mock calendar handler, submit one encrypted receipt, and let the owner verify it locally.
|
|
84
114
|
|
|
85
|
-
For the smallest production-shaped MCP boundary, see [`examples/mcp-minimal-server.ts`](../examples/mcp-minimal-server.ts). It wraps one `tools/call` handler with `sello.service()` and leaves unknown tools unreceipted.
|
|
115
|
+
For the smallest production-shaped MCP boundary, see [`sdks/typescript/examples/mcp-minimal-server.ts`](../sdks/typescript/examples/mcp-minimal-server.ts). It wraps one `tools/call` handler with `sello.service()` and leaves unknown tools unreceipted.
|
|
86
116
|
|
|
87
117
|
For your own tool server, copy the printed service env:
|
|
88
118
|
|
|
@@ -7,7 +7,7 @@ These notes cover the first Stripe-style SDK implementation pass. They are writt
|
|
|
7
7
|
- Service emission and owner viewing are documented as separate environments.
|
|
8
8
|
- The service process is not required to hold `SELLO_OWNER_KEY`.
|
|
9
9
|
- Hosted `sello.build` is described as optional convenience, not as a protocol dependency.
|
|
10
|
-
- Deferred production features are named in
|
|
10
|
+
- Deferred production features are named in the README, quickstart, and this audit note.
|
|
11
11
|
|
|
12
12
|
## Phase 1: Env-First Facade
|
|
13
13
|
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sello",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.12",
|
|
4
4
|
"description": "Reference implementation of the Sello protocol for service-signed AI agent receipts.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"sideEffects": false,
|
|
8
8
|
"exports": {
|
|
9
9
|
".": "./dist/index.js",
|
|
10
|
-
"./fixtures/vectors/sello-v0.1.json": "./fixtures/vectors/sello-v0.1.json",
|
|
10
|
+
"./fixtures/vectors/sello-v0.1.json": "./sdks/typescript/fixtures/vectors/sello-v0.1.json",
|
|
11
11
|
"./spec": "./SPEC.md",
|
|
12
12
|
"./package.json": "./package.json"
|
|
13
13
|
},
|
|
@@ -18,27 +18,27 @@
|
|
|
18
18
|
},
|
|
19
19
|
"files": [
|
|
20
20
|
"dist",
|
|
21
|
-
"examples",
|
|
22
|
-
"src",
|
|
23
|
-
"fixtures/vectors",
|
|
21
|
+
"sdks/typescript/examples",
|
|
22
|
+
"sdks/typescript/src",
|
|
23
|
+
"sdks/typescript/fixtures/vectors",
|
|
24
24
|
"docs",
|
|
25
25
|
"SPEC.md",
|
|
26
26
|
"README.md",
|
|
27
27
|
"LICENSE"
|
|
28
28
|
],
|
|
29
29
|
"scripts": {
|
|
30
|
-
"actions": "node --experimental-strip-types src/cli/sello.ts actions",
|
|
31
|
-
"bench": "node --experimental-strip-types src/cli/bench.ts",
|
|
32
|
-
"demo": "node --experimental-strip-types src/cli/demo.ts",
|
|
33
|
-
"dev": "node --experimental-strip-types src/cli/sello.ts dev",
|
|
34
|
-
"example:mcp:minimal": "node --test --experimental-strip-types test/examples/mcp-minimal-server.test.ts",
|
|
35
|
-
"example:mcp": "node --experimental-strip-types examples/mcp-tool-server.ts",
|
|
36
|
-
"example:tool": "node --experimental-strip-types examples/quickstart-tool.ts",
|
|
37
|
-
"build": "node --disable-warning=ExperimentalWarning scripts/build-dist.mjs",
|
|
38
|
-
"package:test": "node scripts/package-smoke.mjs",
|
|
39
|
-
"pack:check": "
|
|
40
|
-
"prepack": "node --disable-warning=ExperimentalWarning scripts/build-dist.mjs",
|
|
41
|
-
"test": "node --test --experimental-strip-types"
|
|
30
|
+
"actions": "node --experimental-strip-types sdks/typescript/src/cli/sello.ts actions",
|
|
31
|
+
"bench": "node --experimental-strip-types sdks/typescript/src/cli/bench.ts",
|
|
32
|
+
"demo": "node --experimental-strip-types sdks/typescript/src/cli/demo.ts",
|
|
33
|
+
"dev": "node --experimental-strip-types sdks/typescript/src/cli/sello.ts dev",
|
|
34
|
+
"example:mcp:minimal": "node --test --experimental-strip-types sdks/typescript/test/examples/mcp-minimal-server.test.ts",
|
|
35
|
+
"example:mcp": "node --experimental-strip-types sdks/typescript/examples/mcp-tool-server.ts",
|
|
36
|
+
"example:tool": "node --experimental-strip-types sdks/typescript/examples/quickstart-tool.ts",
|
|
37
|
+
"build": "node --disable-warning=ExperimentalWarning sdks/typescript/scripts/build-dist.mjs",
|
|
38
|
+
"package:test": "node sdks/typescript/scripts/package-smoke.mjs",
|
|
39
|
+
"pack:check": "node sdks/typescript/scripts/pack-check.mjs",
|
|
40
|
+
"prepack": "node --disable-warning=ExperimentalWarning sdks/typescript/scripts/build-dist.mjs",
|
|
41
|
+
"test": "cd sdks/typescript && node --test --experimental-strip-types"
|
|
42
42
|
},
|
|
43
43
|
"engines": {
|
|
44
44
|
"node": ">=22.7.0"
|
package/sdks/README.md
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Sello SDKs
|
|
2
|
+
|
|
3
|
+
The protocol, paper, and project docs live at the repository root. Language SDKs live here:
|
|
4
|
+
|
|
5
|
+
- [`typescript/`](typescript/): npm package source, CLI, examples, fixtures, and Node tests.
|
|
6
|
+
- [`python/`](python/): Python package source and tests.
|
|
7
|
+
|
|
8
|
+
Root commands still work from the repository top level:
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
node --run test
|
|
12
|
+
node --run package:test
|
|
13
|
+
python -m pip install ./sdks/python
|
|
14
|
+
python -m unittest discover -s sdks/python/tests
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
This keeps the first screen of the repo focused on the protocol while giving each language a predictable home.
|
package/docs/sdk-build-plan.md
DELETED
|
@@ -1,214 +0,0 @@
|
|
|
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.
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|