@treeship/verify 0.10.2 → 0.10.4
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 +1 -1
- package/dist/index.d.ts +32 -7
- package/dist/index.js +26 -9
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -16,7 +16,7 @@ Three functions. Each accepts a parsed object, a JSON string, or a URL.
|
|
|
16
16
|
|
|
17
17
|
### `verifyReceipt(target)`
|
|
18
18
|
|
|
19
|
-
Runs the JSON-level checks a Treeship Session Receipt carries: Merkle root recomputation, inclusion proof verification, leaf-count parity, timeline ordering
|
|
19
|
+
Runs the JSON-level checks a Treeship Session Receipt carries: Merkle root recomputation, inclusion proof verification, leaf-count parity, timeline ordering.
|
|
20
20
|
|
|
21
21
|
```typescript
|
|
22
22
|
import { verifyReceipt } from '@treeship/verify';
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Trust roots input shape. Mirrors the on-disk
|
|
3
|
+
* `~/.treeship/trust_roots.json` so the browser-side verifier sees the
|
|
4
|
+
* same data the CLI does.
|
|
5
|
+
*/
|
|
6
|
+
export interface TrustRootInput {
|
|
7
|
+
key_id: string;
|
|
8
|
+
/** `ed25519:<base64url-no-pad>` */
|
|
9
|
+
public_key: string;
|
|
10
|
+
kind: 'hub_checkpoint' | 'ship' | 'agent_cert';
|
|
11
|
+
label?: string;
|
|
12
|
+
added_at?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface TrustRootsBundle {
|
|
15
|
+
version: 1;
|
|
16
|
+
roots: TrustRootInput[];
|
|
17
|
+
}
|
|
1
18
|
/** Accepted input shapes across all exported functions. */
|
|
2
19
|
export type VerifyTarget = string | URL | Record<string, unknown>;
|
|
3
20
|
export interface VerifyCheck {
|
|
@@ -48,9 +65,9 @@ export interface CrossVerifyResult {
|
|
|
48
65
|
/**
|
|
49
66
|
* Verify a Treeship Session Receipt. Runs the checks derivable from the
|
|
50
67
|
* receipt JSON alone (Merkle root recomputation, inclusion proofs, leaf
|
|
51
|
-
* count, timeline ordering
|
|
52
|
-
*
|
|
53
|
-
*
|
|
68
|
+
* count, timeline ordering). Signature verification on individual envelopes
|
|
69
|
+
* requires the original envelope bytes and is out of scope for URL-fetched
|
|
70
|
+
* receipts; use the `treeship verify` CLI for that.
|
|
54
71
|
*
|
|
55
72
|
* Accepts:
|
|
56
73
|
* - a parsed receipt object (best for callers that already have the JSON)
|
|
@@ -61,13 +78,19 @@ export interface CrossVerifyResult {
|
|
|
61
78
|
export declare function verifyReceipt(target: VerifyTarget): Promise<VerifyReceiptResult>;
|
|
62
79
|
/**
|
|
63
80
|
* Verify an Agent Certificate. Checks the embedded Ed25519 signature
|
|
64
|
-
* against the
|
|
81
|
+
* against a trust root the caller pins via `trustRoots`, then optionally
|
|
65
82
|
* classifies the validity window relative to `now`.
|
|
66
83
|
*
|
|
84
|
+
* `trustRoots` is REQUIRED for the signature to be accepted: as of the
|
|
85
|
+
* v0.10.3 trust-root audit fix, the previous self-signed behavior (trust
|
|
86
|
+
* the embedded pubkey) is gone. Pass the same JSON shape your CLI uses
|
|
87
|
+
* (`~/.treeship/trust_roots.json`) or an array of `TrustRootInput`.
|
|
88
|
+
* Omit it to get a deliberate fail-closed result for diagnostic UIs.
|
|
89
|
+
*
|
|
67
90
|
* Omit `now` (or pass `undefined`) to defer validity classification
|
|
68
91
|
* (signature-only). Pass a `Date` or RFC 3339 string to check expiry.
|
|
69
92
|
*/
|
|
70
|
-
export declare function verifyCertificate(target: VerifyTarget, now?: Date | string): Promise<VerifyCertificateResult>;
|
|
93
|
+
export declare function verifyCertificate(target: VerifyTarget, now?: Date | string, trustRoots?: TrustRootsBundle | TrustRootInput[]): Promise<VerifyCertificateResult>;
|
|
71
94
|
/**
|
|
72
95
|
* Cross-verify a Session Receipt against an Agent Certificate. Answers
|
|
73
96
|
* three questions in one call: do the receipt and certificate reference
|
|
@@ -75,6 +98,8 @@ export declare function verifyCertificate(target: VerifyTarget, now?: Date | str
|
|
|
75
98
|
* session called authorized by the certificate?
|
|
76
99
|
*
|
|
77
100
|
* The `ok` field is the roll-up: true iff all three checks pass. Defaults
|
|
78
|
-
* `now` to `Date.now()` if omitted.
|
|
101
|
+
* `now` to `Date.now()` if omitted. As with `verifyCertificate`,
|
|
102
|
+
* `trustRoots` is required for the certificate's embedded signature to
|
|
103
|
+
* be accepted.
|
|
79
104
|
*/
|
|
80
|
-
export declare function crossVerify(receipt: VerifyTarget, certificate: VerifyTarget, now?: Date | string): Promise<CrossVerifyResult>;
|
|
105
|
+
export declare function crossVerify(receipt: VerifyTarget, certificate: VerifyTarget, now?: Date | string, trustRoots?: TrustRootsBundle | TrustRootInput[]): Promise<CrossVerifyResult>;
|
package/dist/index.js
CHANGED
|
@@ -10,6 +10,15 @@
|
|
|
10
10
|
// Same rules `treeship verify` applies from the CLI, same result shape.
|
|
11
11
|
// If a new schema version lands in core, this package picks it up via
|
|
12
12
|
// core-wasm without an API change here.
|
|
13
|
+
/** Empty bundle is valid input -- the verifier will fail-closed. */
|
|
14
|
+
function serializeTrustRoots(roots) {
|
|
15
|
+
if (!roots)
|
|
16
|
+
return '';
|
|
17
|
+
if (Array.isArray(roots)) {
|
|
18
|
+
return JSON.stringify({ version: 1, roots });
|
|
19
|
+
}
|
|
20
|
+
return JSON.stringify(roots);
|
|
21
|
+
}
|
|
13
22
|
let wasmBindings = null;
|
|
14
23
|
async function loadWasm() {
|
|
15
24
|
if (wasmBindings)
|
|
@@ -36,9 +45,9 @@ async function normalizeToJson(target) {
|
|
|
36
45
|
/**
|
|
37
46
|
* Verify a Treeship Session Receipt. Runs the checks derivable from the
|
|
38
47
|
* receipt JSON alone (Merkle root recomputation, inclusion proofs, leaf
|
|
39
|
-
* count, timeline ordering
|
|
40
|
-
*
|
|
41
|
-
*
|
|
48
|
+
* count, timeline ordering). Signature verification on individual envelopes
|
|
49
|
+
* requires the original envelope bytes and is out of scope for URL-fetched
|
|
50
|
+
* receipts; use the `treeship verify` CLI for that.
|
|
42
51
|
*
|
|
43
52
|
* Accepts:
|
|
44
53
|
* - a parsed receipt object (best for callers that already have the JSON)
|
|
@@ -53,17 +62,23 @@ export async function verifyReceipt(target) {
|
|
|
53
62
|
}
|
|
54
63
|
/**
|
|
55
64
|
* Verify an Agent Certificate. Checks the embedded Ed25519 signature
|
|
56
|
-
* against the
|
|
65
|
+
* against a trust root the caller pins via `trustRoots`, then optionally
|
|
57
66
|
* classifies the validity window relative to `now`.
|
|
58
67
|
*
|
|
68
|
+
* `trustRoots` is REQUIRED for the signature to be accepted: as of the
|
|
69
|
+
* v0.10.3 trust-root audit fix, the previous self-signed behavior (trust
|
|
70
|
+
* the embedded pubkey) is gone. Pass the same JSON shape your CLI uses
|
|
71
|
+
* (`~/.treeship/trust_roots.json`) or an array of `TrustRootInput`.
|
|
72
|
+
* Omit it to get a deliberate fail-closed result for diagnostic UIs.
|
|
73
|
+
*
|
|
59
74
|
* Omit `now` (or pass `undefined`) to defer validity classification
|
|
60
75
|
* (signature-only). Pass a `Date` or RFC 3339 string to check expiry.
|
|
61
76
|
*/
|
|
62
|
-
export async function verifyCertificate(target, now) {
|
|
77
|
+
export async function verifyCertificate(target, now, trustRoots) {
|
|
63
78
|
const json = await normalizeToJson(target);
|
|
64
79
|
const nowStr = now === undefined ? '' : now instanceof Date ? now.toISOString() : now;
|
|
65
80
|
const wasm = await loadWasm();
|
|
66
|
-
return JSON.parse(wasm.verify_certificate(json, nowStr));
|
|
81
|
+
return JSON.parse(wasm.verify_certificate(json, nowStr, serializeTrustRoots(trustRoots)));
|
|
67
82
|
}
|
|
68
83
|
/**
|
|
69
84
|
* Cross-verify a Session Receipt against an Agent Certificate. Answers
|
|
@@ -72,9 +87,11 @@ export async function verifyCertificate(target, now) {
|
|
|
72
87
|
* session called authorized by the certificate?
|
|
73
88
|
*
|
|
74
89
|
* The `ok` field is the roll-up: true iff all three checks pass. Defaults
|
|
75
|
-
* `now` to `Date.now()` if omitted.
|
|
90
|
+
* `now` to `Date.now()` if omitted. As with `verifyCertificate`,
|
|
91
|
+
* `trustRoots` is required for the certificate's embedded signature to
|
|
92
|
+
* be accepted.
|
|
76
93
|
*/
|
|
77
|
-
export async function crossVerify(receipt, certificate, now) {
|
|
94
|
+
export async function crossVerify(receipt, certificate, now, trustRoots) {
|
|
78
95
|
const [receiptJson, certJson] = await Promise.all([
|
|
79
96
|
normalizeToJson(receipt),
|
|
80
97
|
normalizeToJson(certificate),
|
|
@@ -85,5 +102,5 @@ export async function crossVerify(receipt, certificate, now) {
|
|
|
85
102
|
? now.toISOString()
|
|
86
103
|
: now;
|
|
87
104
|
const wasm = await loadWasm();
|
|
88
|
-
return JSON.parse(wasm.cross_verify(receiptJson, certJson, nowStr));
|
|
105
|
+
return JSON.parse(wasm.cross_verify(receiptJson, certJson, nowStr, serializeTrustRoots(trustRoots)));
|
|
89
106
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@treeship/verify",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.4",
|
|
4
4
|
"description": "Zero-dependency cryptographic verification for Treeship receipts and certificates. Runs anywhere WASM runs: Node, browser, Vercel Edge, Cloudflare Workers, AWS Lambda.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"repository": {
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
"test": "vitest run"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@treeship/core-wasm": "0.10.
|
|
43
|
+
"@treeship/core-wasm": "0.10.4"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@types/node": "^25.5.0",
|