@treeship/verify 0.19.1 → 0.21.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.
package/dist/index.d.ts CHANGED
@@ -7,7 +7,13 @@ export interface TrustRootInput {
7
7
  key_id: string;
8
8
  /** `ed25519:<base64url-no-pad>` */
9
9
  public_key: string;
10
- kind: 'hub_checkpoint' | 'ship' | 'agent_cert';
10
+ /**
11
+ * The powers a root grants, after the v0.19 trust-split. The single old
12
+ * `ship` kind was split into `hub_org` / `cert_issuer` / `revoker` and is
13
+ * now deprecated and inert (no verifier honors it), so it is intentionally
14
+ * not offered here. See TrustRootKind in packages/core/src/trust/mod.rs.
15
+ */
16
+ kind: 'hub_checkpoint' | 'hub_org' | 'cert_issuer' | 'revoker' | 'agent_cert' | 'session_host';
11
17
  label?: string;
12
18
  added_at?: string;
13
19
  }
@@ -23,7 +29,7 @@ export interface VerifyCheck {
23
29
  detail: string;
24
30
  }
25
31
  export interface VerifyReceiptResult {
26
- outcome: 'pass' | 'fail' | 'error';
32
+ outcome: 'pass' | 'structural-pass' | 'fail' | 'error';
27
33
  checks: VerifyCheck[];
28
34
  session: {
29
35
  id: string;
@@ -131,3 +137,95 @@ export interface CapabilityVerifyResult {
131
137
  * completeness guarantee. It cannot prove the agent took no off-card action.
132
138
  */
133
139
  export declare function verifyCapability(card: VerifyTarget, actions: VerifyTarget[], trustRoots?: TrustRootsBundle | TrustRootInput[]): Promise<CapabilityVerifyResult>;
140
+ /** One certificate in a resolution bundle's chain. */
141
+ export interface ResolutionCert {
142
+ artifact_id: string;
143
+ /** An `agent_cert.v1` DSSE envelope object. */
144
+ envelope: Record<string, unknown>;
145
+ }
146
+ /**
147
+ * A resolution bundle: the signed bytes needed to decide whether an agent's
148
+ * current card is trustworthy. This is the same shape the Hub serves and the
149
+ * CLI re-verifies — assemble it from a `resolve` response.
150
+ */
151
+ export interface ResolutionBundleInput {
152
+ agent: string;
153
+ /** The agent's current `agent_card.v1` DSSE envelope object. */
154
+ card: Record<string, unknown>;
155
+ certs?: ResolutionCert[];
156
+ /** `agent_card_revocation.v1` DSSE envelope objects. */
157
+ revocations?: Record<string, unknown>[];
158
+ }
159
+ /** Result of {@link verifyResolution}. Mirrors the WASM JSON output. */
160
+ export interface ResolutionVerdict {
161
+ /** Card signature verified against your roots (directly or via the chain). */
162
+ sig_ok: boolean;
163
+ /** Card is key-bound: signer pinned under AgentCert, or chain-certified. */
164
+ key_bound: boolean;
165
+ /** If verified via the certificate chain, the cert artifact that vouched. */
166
+ chain_cert_id: string | null;
167
+ /** An authorized, verifying revocation was found. */
168
+ revoked: boolean;
169
+ revocation_reason: string | null;
170
+ error_code?: string;
171
+ message?: string;
172
+ }
173
+ /**
174
+ * Verify an agent resolution bundle in the browser — the same `resolve --hub`
175
+ * trust decision the CLI makes, via shared Rust logic
176
+ * (`treeship_core::verify::resolution`). Verifies the card by direct leaf pin
177
+ * or certificate-chain walk, then honors an authorized revocation.
178
+ *
179
+ * `trustRoots` is required for `key_bound` to be true; with none, the bundle
180
+ * fails closed. `now` defaults to the current time (used for cert validity
181
+ * windows in the chain walk).
182
+ */
183
+ export declare function verifyResolution(bundle: ResolutionBundleInput, trustRoots?: TrustRootsBundle | TrustRootInput[], now?: Date | string): Promise<ResolutionVerdict>;
184
+ /** The challenge-response outcome within a presentation. */
185
+ export interface PresentationChallenge {
186
+ outcome: 'not_requested' | 'present_but_unchecked' | 'no_response' | 'no_established_key' | 'verified' | 'failed';
187
+ /** Bearer-signed timestamp, when `outcome` is `verified`. */
188
+ signed_at: string | null;
189
+ /** Failure reason, when `outcome` is `failed`. */
190
+ reason: string | null;
191
+ }
192
+ /** The staple portion of a presentation verdict. */
193
+ export interface PresentationStaple {
194
+ verified: boolean;
195
+ status: 'no_staple' | 'unparseable' | 'signer_not_trusted' | 'inclusion_invalid' | 'verified';
196
+ checkpoint_index: number | null;
197
+ age_secs: number | null;
198
+ }
199
+ /** Result of {@link verifyPresentation}. Mirrors the WASM JSON output. */
200
+ export interface PresentationVerdict {
201
+ agent: string;
202
+ card_id: string;
203
+ /** Card signature verified against your roots (directly or via the chain). */
204
+ sig_ok: boolean;
205
+ key_bound: boolean;
206
+ via_chain: boolean;
207
+ revoked: string | null;
208
+ challenge: PresentationChallenge;
209
+ challenge_ok: boolean;
210
+ staple: PresentationStaple;
211
+ /** Roll-up: not revoked, key-bound, and (if requested) challenge verified.
212
+ * Freshness (`--max-staple-age`) is your own policy over `staple.age_secs`. */
213
+ ok: boolean;
214
+ error_code?: string;
215
+ message?: string;
216
+ }
217
+ /**
218
+ * Verify an agent presentation in the browser — the same `verify-presentation`
219
+ * trust decision the CLI makes, via shared Rust logic
220
+ * (`treeship_core::verify::presentation`). Verifies the card (direct pin or
221
+ * chain), honors an authorized revocation, checks challenge liveness (when
222
+ * `nonce` is given), and verifies the staple.
223
+ *
224
+ * `trustRoots` is required for `key_bound`; with none, the presentation fails
225
+ * closed. `nonce` is the challenge nonce YOU issued (omit to skip liveness).
226
+ * `now` defaults to the current time.
227
+ */
228
+ export declare function verifyPresentation(presentation: Record<string, unknown>, trustRoots?: TrustRootsBundle | TrustRootInput[], opts?: {
229
+ nonce?: string;
230
+ now?: Date | string;
231
+ }): Promise<PresentationVerdict>;
package/dist/index.js CHANGED
@@ -122,3 +122,43 @@ export async function verifyCapability(card, actions, trustRoots) {
122
122
  const wasm = await loadWasm();
123
123
  return JSON.parse(wasm.verify_capability(cardJson, actionsJson, serializeTrustRoots(trustRoots)));
124
124
  }
125
+ /**
126
+ * Verify an agent resolution bundle in the browser — the same `resolve --hub`
127
+ * trust decision the CLI makes, via shared Rust logic
128
+ * (`treeship_core::verify::resolution`). Verifies the card by direct leaf pin
129
+ * or certificate-chain walk, then honors an authorized revocation.
130
+ *
131
+ * `trustRoots` is required for `key_bound` to be true; with none, the bundle
132
+ * fails closed. `now` defaults to the current time (used for cert validity
133
+ * windows in the chain walk).
134
+ */
135
+ export async function verifyResolution(bundle, trustRoots, now) {
136
+ const nowStr = now === undefined
137
+ ? new Date().toISOString()
138
+ : now instanceof Date
139
+ ? now.toISOString()
140
+ : now;
141
+ const wasm = await loadWasm();
142
+ return JSON.parse(wasm.verify_resolution(JSON.stringify(bundle), serializeTrustRoots(trustRoots), nowStr));
143
+ }
144
+ /**
145
+ * Verify an agent presentation in the browser — the same `verify-presentation`
146
+ * trust decision the CLI makes, via shared Rust logic
147
+ * (`treeship_core::verify::presentation`). Verifies the card (direct pin or
148
+ * chain), honors an authorized revocation, checks challenge liveness (when
149
+ * `nonce` is given), and verifies the staple.
150
+ *
151
+ * `trustRoots` is required for `key_bound`; with none, the presentation fails
152
+ * closed. `nonce` is the challenge nonce YOU issued (omit to skip liveness).
153
+ * `now` defaults to the current time.
154
+ */
155
+ export async function verifyPresentation(presentation, trustRoots, opts) {
156
+ const now = opts?.now;
157
+ const nowStr = now === undefined
158
+ ? new Date().toISOString()
159
+ : now instanceof Date
160
+ ? now.toISOString()
161
+ : now;
162
+ const wasm = await loadWasm();
163
+ return JSON.parse(wasm.verify_presentation(JSON.stringify(presentation), serializeTrustRoots(trustRoots), opts?.nonce ?? '', nowStr));
164
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@treeship/verify",
3
- "version": "0.19.1",
3
+ "version": "0.21.0",
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.19.1"
43
+ "@treeship/core-wasm": "0.21.0"
44
44
  },
45
45
  "devDependencies": {
46
46
  "@types/node": "^25.5.0",