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
Binary file
@@ -0,0 +1,79 @@
1
+ # Implementation Decisions
2
+
3
+ ## Initial Scaffold
4
+
5
+ - Use plain TypeScript modules with Node 24's native type stripping for the first implementation slice.
6
+ - Use Node's built-in test runner to avoid dependency installation before the crypto-library spike.
7
+ - Keep `package.json` npm-compatible, but run tests with `node --run test` or the raw `node --test --experimental-strip-types` command while `npm` is unavailable in this workspace.
8
+ - Start with token-derived identifiers because they require no third-party dependencies and exercise the spec's exact-byte handling rule.
9
+
10
+ ## Deterministic CBOR
11
+
12
+ - Implement a narrow deterministic CBOR subset locally for early receipt-body and protected-header work.
13
+ - Support only the value types currently needed by the protocol: integers, text strings, byte strings, maps, and tag 0 timestamps.
14
+ - Reject non-minimal length encodings, indefinite lengths, unsupported major types, and maps whose keys are not in deterministic order.
15
+ - Revisit this decision during the library spike before publishing interop vectors; the local helper is intentionally small, not a general-purpose CBOR library.
16
+
17
+ ## Canonical Log URLs
18
+
19
+ - Treat the trusted log identity as an already-normalized URL string.
20
+ - Reject common alternate spellings rather than silently normalizing them: uppercase hostnames, default ports, query strings, fragments, userinfo, dot segments, and non-canonical percent encoding.
21
+ - Compare accepted log identities byte-for-byte so the signed `sello_log_url`, the trusted set, and the returning proof log all use the same identifier.
22
+
23
+ ## COSE Protected Header Bytes
24
+
25
+ - Decode protected headers for validation, but keep the original protected-header byte string attached to the decoded value.
26
+ - Later COSE signature verification and HPKE opening must use those original bytes as the signed bytes and AAD, not a reserialized map.
27
+
28
+ ## HPKE Base Mode
29
+
30
+ - Use Node's built-in X25519, HMAC-SHA256, and ChaCha20-Poly1305 primitives for the first local implementation because this workspace currently lacks npm.
31
+ - Keep the HPKE code limited to the single Sello v0.1 suite: DHKEM(X25519, HKDF-SHA256), HKDF-SHA256, and ChaCha20-Poly1305 in base mode.
32
+ - Pin the helper against RFC 9180 Appendix A.2.1 so implementation mistakes show up as byte-level test failures.
33
+ - Revisit this decision before production use; a maintained HPKE library is still preferable if it keeps the protocol surface smaller and auditable.
34
+
35
+ ## COSE_Sign1 And Ed25519
36
+
37
+ - Implement only the narrow Sello COSE_Sign1 profile locally: protected bstr, empty unprotected map, embedded payload bstr, and Ed25519 signature bstr.
38
+ - Build the RFC 9052 `Sig_structure` with context string `Signature1`, the exact protected-header bytes, empty external AAD, and the embedded HPKE payload.
39
+ - Use Node's built-in Ed25519 signing and verification with raw-key DER wrapping helpers so fixtures and registries can still use raw 32-byte keys.
40
+
41
+ ## Signed JSON Registry
42
+
43
+ - Verify the detached signature over the exact UTF-8 JSON bytes before parsing registry entries.
44
+ - Store registry `kid` keys as lowercase hex strings and resolve from the protected-header `kid` bytes by hex encoding those bytes.
45
+ - Treat revocation as a separate check after lookup: a revoked key is accepted only when the log integrated time is verifiably before `revoked_at`.
46
+ - Fail closed when a key is revoked and the log entry lacks verifiable integrated time.
47
+
48
+ ## Mock Transparency Log
49
+
50
+ - Keep the first log implementation in memory and deterministic enough for tests.
51
+ - Index entries by the protected-header `sello_token_ref` and return `completeness: "complete"` because the mock owns the whole entry set.
52
+ - Bind the mock proof to the canonical log URL, entry index, integrated time, and exact envelope hash. This is not a Merkle proof, but it exercises the same owner-side data dependencies the Rekor adapter will need.
53
+
54
+ ## Owner Verification Outcomes
55
+
56
+ - Return verified receipts and rejected receipts separately so one bad log entry does not prevent owners from seeing other valid receipts.
57
+ - Use stage-specific rejection codes for log binding, proof, registry, revocation, COSE, HPKE, and body-validation failures.
58
+ - Treat exact duplicates as `status: "duplicate"` records pointing at the first valid receipt, not as cryptographic failures.
59
+ - Preserve distinct same-second activity and flag it on both affected records.
60
+
61
+ ## Service Receipt Creation Boundary
62
+
63
+ - `createReceipt` accepts already-verified token claims plus the raw token bytes used for Sello identifier derivation.
64
+ - `createReceiptFromJwsToken` is the service-facing helper for v0.1 compact JWS tokens. It verifies the JWS signature before exposing `owner_hpke_pk` or `sello_logs`.
65
+ - The token-profile module deliberately does not implement token authorization semantics such as scope or expiry; those remain service policy outside Sello.
66
+
67
+ ## JWS Token Profile
68
+
69
+ - Support compact-serialized JWS with JSON protected header and JSON payload.
70
+ - Require `alg: "EdDSA"` and reject `crit` headers in the first implementation.
71
+ - Verify the signature over the exact compact JWS signing input before parsing Sello claims.
72
+ - Validate `owner_hpke_pk` as unpadded base64url encoding of a raw 32-byte X25519 public key.
73
+ - Validate `sello_logs`, when present, as an array of canonical log URL strings.
74
+ - Reject impossible unpadded base64url lengths before relying on Node's decoder behavior.
75
+
76
+ ## Demo Command
77
+
78
+ - Ship a small `sello-demo` binary that runs through Node 24's native TypeScript type stripping.
79
+ - The demo prints success, error, and denied receipts as verified JSON, and `--tamper` appends a deliberately bad entry to show structured rejection output.