@agentidentitytrustprotocol/aitp 0.2.0 → 0.4.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 (4) hide show
  1. package/README.md +60 -32
  2. package/index.d.ts +126 -59
  3. package/index.js +2 -2
  4. package/package.json +7 -7
package/README.md CHANGED
@@ -15,33 +15,34 @@ the [NAPI-rs CLI](https://napi.rs):
15
15
 
16
16
  ```bash
17
17
  npm install
18
- npm run build:debug # default `.node` (v0.1 surface only)
19
- npm run build:experimental:debug # default + post-v0.1 features
18
+ npm run build:debug # full `.node` (all capabilities)
19
+ npm run build:minimal:debug # minimal `.node` (core surface only)
20
20
  # Release:
21
- npm run build # default release
22
- npm run build:experimental # default + experimental, release
21
+ npm run build # full release (all capabilities)
22
+ npm run build:minimal # minimal release (--no-default-features)
23
23
  ```
24
24
 
25
25
  This produces `aitp.node` and `index.js` in the package root. Generated
26
- TypeScript typings (`index.d.ts`) include the experimental surface only
27
- when the artifact was built with the `experimental` feature.
26
+ TypeScript typings (`index.d.ts`) cover the full surface; a
27
+ `--no-default-features` build narrows it accordingly.
28
28
 
29
29
  ### Cargo features
30
30
 
31
- The default `.node` exposes the v0.1 surface (handshake, TCT, delegation,
32
- manifest verify, revocation-list signing, OIDC identity). Three post-v0.1
33
- capabilities live behind opt-in Cargo features:
31
+ The published `.node` ships the **full** capability surface by default —
32
+ handshake, TCT, delegation, manifest verify, revocation-list signing, OIDC
33
+ identity, **plus** TCT renewal, session bundles, SPKI pinning, and multi-hop
34
+ delegation. Each capability is a named feature (all on by default) so a
35
+ minimal build can opt out with `--no-default-features`:
34
36
 
35
- | Feature | Enables | RFC |
36
- |---------------------------|--------------------------------------------------------------------------|----------------------|
37
- | `experimental-renewal` | `AitpAgent.buildRenewalRequest` / `processRenewalRequest` | RFC-AITP-0005 §10 |
38
- | `experimental-bundle` | `SessionBundleBuilder`, `verifySessionBundle` | RFC-AITP-0010 |
39
- | `experimental-pinning` | `computeSpkiHash`, `SpkiPinVerifier` | HPKP (RFC 7469) |
40
- | `experimental-multihop-delegation` | `verifyDelegationExperimentalMultihop` | RFC-AITP-0011 |
41
- | `experimental` (umbrella) | All four above | |
37
+ | Feature | Enables | RFC |
38
+ |-----------------------|--------------------------------------------------------------------------|----------------------|
39
+ | `renewal` | `AitpAgent.buildRenewalRequest` / `processRenewalRequest` | RFC-AITP-0005 §10 |
40
+ | `session-bundle` | `SessionBundleBuilder`, `verifySessionBundle` | RFC-AITP-0010 |
41
+ | `spki-pinning` | `computeSpkiHash`, `SpkiPinVerifier` | HPKP (RFC 7469) |
42
+ | `multihop-delegation` | `verifyDelegationMultihop` | RFC-AITP-0011 |
42
43
 
43
- Each post-v0.1 capability does **not** promise wire stability until the
44
- underlying RFC graduates.
44
+ Capabilities whose underlying RFC has not yet graduated do not promise wire
45
+ stability across binding versions.
45
46
 
46
47
  ## Usage
47
48
 
@@ -70,11 +71,16 @@ const hello = sess.buildHello(respManifest, ['demo.write']);
70
71
  const { ackJson: helloAck, sessionId } = rsess.processHello(hello);
71
72
  const commit = sess.processHelloAck(helloAck, sessionId);
72
73
  const { ackJson: commitAck } = rsess.processCommit(commit);
73
- const initiatorHeldTct = sess.complete(commitAck);
74
+ const completed = sess.complete(commitAck);
75
+ // completed = { tct, claims, grantVoucher? }
76
+ // `tct` is an opaque compact-JWS string; `claims` is the decoded TCT.
74
77
 
75
78
  // Each peer now holds a TCT the other issued it.
76
- const ident = initiator.verifyTct(initiatorHeldTct, 'demo.write');
79
+ const ident = initiator.verifyTct(completed.tct, 'demo.write');
77
80
  console.log(ident.peerAid, ident.grants);
81
+
82
+ // `completed.grantVoucher` (when present) is what you pass to
83
+ // `buildDelegation(grantVoucher, delegateeAid, scope)` to delegate.
78
84
  ```
79
85
 
80
86
  In a real deployment each message moves over HTTP: `buildHello` returns the
@@ -84,23 +90,45 @@ plus the value for the `X-Aitp-Session-Id` header, and so on.
84
90
  ## API
85
91
 
86
92
  The full public surface is described in the generated `index.d.ts`; below
87
- is a summary. All `*Json` parameters and return values are JSON strings.
93
+ is a summary. Manifests, revocation lists, and handshake envelopes cross
94
+ the boundary as JSON strings; **TCTs, grant vouchers, and delegations are
95
+ opaque compact-JWS token strings** (`header.payload.signature`).
88
96
 
89
97
  | Type | Default? | Notes |
90
98
  |---------------------------|:--------:|----------------------------------------------------------------------------------------------------------------|
91
- | `AitpAgent` | ✅ | `generate(opts?)` / `fromSeed(buffer, opts?)` (`opts.suite = "ed25519" \| "p256"`), `aid`, `buildManifest(opts)`, `newSession(jwks?, opts?)`, `newResponder(jwks?, opts?)`, `verifyTct(...)`, `buildDelegation(...)`, `issueTctForDelegatee(...)`, `signRevocationList(...)` |
92
- | `InitiatorSession` | ✅ | `buildHello(peerManifest, grants, oidcMintJwt?)`, `processHelloAck(...)`, `complete(...)` |
93
- | `ResponderSession` | ✅ | `processHello(hello, oidcMintJwt?)` → `{ ackJson, sessionId }`, `processCommit(commit)` → `{ ackJson, tctJson }` |
94
- | `TctIdentity` | ✅ | `peerAid`, `grants`, `expiresAt`, `jti` |
95
- | `DelegationVerified` | ✅ | `delegator`, `delegatee`, `issuedBy`, `grants`, `expiresAt`, `cnf` |
99
+ | `AitpAgent` | ✅ | `generate(opts?)` / `fromSeed(buffer, opts?)` (`opts.suite = "ed25519" \| "p256"`), `aid`, `buildManifest(opts)`, `newSession(jwks?, opts?)`, `newResponder(jwks?, opts?)`, `verifyTct(token, grant, expectedAudience?, revokedJtis?)`, `buildDelegation(voucherToken, delegateeAid, scope, ttlSecs?)`, `issueTctForDelegatee(...)`, `signRevocationList(...)` |
100
+ | `InitiatorSession` | ✅ | `buildHello(peerManifest, grants, oidcMintJwt?)`, `processHelloAck(...)`, `complete(...)` → `{ tct, claims, grantVoucher? }` |
101
+ | `ResponderSession` | ✅ | `processHello(hello, oidcMintJwt?)` → `{ ackJson, sessionId }`, `processCommit(commit)` → `{ ackJson, completed: { tct, claims, grantVoucher? } }` |
102
+ | `TctIdentity` | ✅ | `peerAid` (issuer), `grants`, `expiresAt`, `jti` |
103
+ | `DelegationVerified` | ✅ | `delegator`, `delegatee`, `issuedBy`, `grants`, `expiresAt`, `cnfJkt` |
96
104
  | `JwksProvider` | ✅ | OIDC JWKS map. `upsert(issuer, keys)`, `remove(issuer)`, `issuers()` |
97
- | `TctStore` / `verifyTctCached()` | ✅ | Hot-path verify cache: skips the signature check for a byte-identical, still-valid TCT (keyed by SHA-256 of the envelope) |
98
- | `verifyDelegation()` | ✅ | RFC-AITP-0006 — strict v0.1 single-hop; rejects any multi-hop `chain` |
105
+ | `TctStore` / `verifyTctCached()` | ✅ | Hot-path verify cache: skips the signature check for a byte-identical, still-valid TCT (keyed by SHA-256 of the token bytes) |
106
+ | `verifyDelegation()` | ✅ | RFC-AITP-0006 — strict single-hop; rejects any multi-hop `chain` |
99
107
  | `verifyManifestJson()` | ✅ | Control-plane manifest enrollment |
100
- | `buildRenewalRequest()` / `processRenewalRequest()` | `experimental-renewal` | RFC-AITP-0005 §10 |
101
- | `SessionBundleBuilder`, `verifySessionBundle()` | `experimental-bundle` | RFC-AITP-0010 |
102
- | `computeSpkiHash()`, `SpkiPinVerifier` | `experimental-pinning` | HPKP outbound pinning |
103
- | `verifyDelegationExperimentalMultihop()` | `experimental-multihop-delegation` | RFC-AITP-0011 (draft) multi-hop opt-in |
108
+ | `buildRenewalRequest()` / `processRenewalRequest()` | `renewal` | RFC-AITP-0005 §10 |
109
+ | `SessionBundleBuilder`, `verifySessionBundle()` | `session-bundle` | RFC-AITP-0010 |
110
+ | `computeSpkiHash()`, `SpkiPinVerifier` | `spki-pinning` | HPKP outbound pinning |
111
+ | `verifyDelegationMultihop()` | `multihop-delegation` | RFC-AITP-0011 (draft) multi-hop opt-in |
112
+
113
+ ### Revocation
114
+
115
+ `verifyTct` / `verifyTctCached` accept an optional final `revokedJtis`
116
+ argument — an array of revoked TCT `jti` strings. Any TCT whose `jti` is in
117
+ the array is rejected even if its signature, audience, and expiry are
118
+ otherwise valid:
119
+
120
+ ```javascript
121
+ const revoked = ['11111111-2222-3333-4444-555555555555'];
122
+ agent.verifyTct(tctToken, 'demo.write', null, revoked); // throws if revoked
123
+ ```
124
+
125
+ **Obligation.** The SDK does **not** fetch or maintain the revoked set for
126
+ you; supplying it is the caller's responsibility. Source it from a
127
+ `RevocationList` you fetched and verified out-of-band (issue one with
128
+ `signRevocationList`). The set is passed up-front (rather than via a JS
129
+ callback invoked per-`jti`) to stay sound under napi threading constraints.
130
+ Omitting the argument leaves the revocation gate **off** — an unexpired but
131
+ revoked TCT will pass, so wire `revokedJtis` in wherever revocation matters.
104
132
 
105
133
  ### OIDC identity (RFC-AITP-0002)
106
134
 
package/index.d.ts CHANGED
@@ -85,57 +85,61 @@ export interface JsBundleOutcome {
85
85
  */
86
86
  export declare function verifySessionBundle(bundleEnvelopeJson: string, verifierAid: string, nowUnixSecs?: number | undefined | null, revocationCheck?: (...args: any[]) => any | undefined | null): JsBundleOutcome
87
87
  /**
88
- * The verified delegation token's salient fields. Returned from
88
+ * The verified delegation's salient fields. Returned from
89
89
  * `verifyDelegation` and consumed by `AitpAgent.issueTctForDelegatee`.
90
90
  */
91
91
  export interface JsDelegationVerified {
92
92
  /**
93
- * AID of the ultimate grantor (the original TCT issuer that gave grants
94
- * to `issuedBy`). The responder side checks this matches its own AID
95
- * before redeeming.
93
+ * AID of the ultimate grantor (the original TCT issuer that gave
94
+ * grants to `issuedBy`). Equal to the delegation's `aud` and to the
95
+ * embedded voucher's `iss`. The responder side checks this matches
96
+ * its own AID before redeeming.
96
97
  */
97
98
  delegator: string
98
- /** AID of the recipient (C) — who will receive a fresh TCT. */
99
+ /** AID of the recipient (C) — who will receive a fresh TCT (`sub`). */
99
100
  delegatee: string
100
- /** AID of the agent that issued this delegation (B in the RFC). */
101
+ /** AID of the agent that issued this delegation (B in the RFC) (`iss`). */
101
102
  issuedBy: string
102
- /** Capabilities being delegated. Always a subset of the source TCT's grants. */
103
+ /**
104
+ * Capabilities being delegated (`scope`). Always a subset of the
105
+ * root voucher's grants.
106
+ */
103
107
  grants: Array<string>
104
- /** Unix-seconds expiry of the delegation token itself. */
108
+ /** Unix-seconds expiry of the delegation token itself (`exp`). */
105
109
  expiresAt: number
106
110
  /**
107
- * Delegatee's raw Ed25519 / P-256 public key, base64url-encoded. This is
108
- * the `cnf` binding — proves which key the issuer should bind to the
109
- * fresh TCT it mints.
111
+ * RFC 7638 JWK thumbprint of the delegatee's key (`cnf.jkt`). In
112
+ * v0.2 this is derived from — and must match — the key encoded in
113
+ * `delegatee`'s AID; the fresh TCT's key binding is taken from the
114
+ * AID, not from this field.
110
115
  */
111
- cnf: string
116
+ cnfJkt: string
112
117
  }
113
118
  /**
114
- * Verify a `DelegationEnvelope` JSON under **strict AITP v0.1**
119
+ * Verify a delegation compact JWS under **strict AITP v0.2**
115
120
  * (RFC-AITP-0006 single-hop). `verifierAid` is the verifier's own AID
116
- * string — verification fails if it doesn't match the token's `delegator`
117
- * field.
121
+ * string — it MUST equal the delegation's `aud` (the root grantor), and
122
+ * the embedded voucher MUST verify under the verifier's own key.
118
123
  *
119
- * Any token carrying a non-empty `chain` (a draft RFC-AITP-0011 multi-hop
124
+ * Any token carrying a non-empty `chain` (an RFC-AITP-0011 multi-hop
120
125
  * delegation) is **rejected** with `DELEGATION_MULTIHOP_NOT_SUPPORTED`,
121
- * matching the Rust core default. To opt into multi-hop, build the SDK with
122
- * the `experimental-multihop-delegation` feature and call
123
- * `verifyDelegationExperimentalMultihop`.
126
+ * matching the Rust core default. To allow multi-hop chains, call
127
+ * `verifyDelegationMultihop` instead.
124
128
  */
125
- export declare function verifyDelegation(envelopeJson: string, verifierAid: string): JsDelegationVerified
129
+ export declare function verifyDelegation(token: string, verifierAid: string): JsDelegationVerified
126
130
  /**
127
- * Verify a `DelegationEnvelope` JSON allowing **draft RFC-AITP-0011
128
- * multi-hop** chains up to `maxHops` total hops (`chain.length + 1`).
131
+ * Verify a delegation compact JWS allowing **RFC-AITP-0011 multi-hop**
132
+ * chains up to `maxHops` total hops (`chain.length + 1`).
129
133
  *
130
- * This opts into behavior that is **not** part of AITP v0.1. It is only
131
- * compiled in under the `experimental-multihop-delegation` feature; a
132
- * default build exposes only the strict `verifyDelegation`.
134
+ * The strict single-hop `verifyDelegation` is the safe default; this
135
+ * function additionally allows multi-hop chains. Present by default (the
136
+ * `multihop-delegation` feature); a `--no-default-features` build omits it.
133
137
  *
134
138
  * `maxHops` defaults to `DEFAULT_MAX_HOPS` (3, the RFC-AITP-0011 §2
135
139
  * recommended ceiling). Pass a smaller value for a tighter bound;
136
- * `maxHops = 0` reverts to strict v0.1 (rejects any non-empty chain).
140
+ * `maxHops = 0` reverts to strict single-hop (rejects any non-empty chain).
137
141
  */
138
- export declare function verifyDelegationExperimentalMultihop(envelopeJson: string, verifierAid: string, maxHops?: number | undefined | null): JsDelegationVerified
142
+ export declare function verifyDelegationMultihop(token: string, verifierAid: string, maxHops?: number | undefined | null): JsDelegationVerified
139
143
  /**
140
144
  * Compute the RFC 7638 JWK thumbprint of the public key embedded in
141
145
  * an AID — the value an OIDC IdP MUST place in the JWT's `cnf.jkt`
@@ -160,20 +164,64 @@ export interface JsHelloAckResult {
160
164
  /** Correlation id — set as the `X-Aitp-Session-Id` response header. */
161
165
  sessionId: string
162
166
  }
163
- /** Result of `processCommit`: response body plus the held TCT. */
167
+ /**
168
+ * The salient claims of a TCT obtained at handshake completion. Mirrors
169
+ * `aitp_tct::TctClaims`; timestamps are Unix seconds as JS `number`s.
170
+ */
171
+ export interface JsHandshakeTctClaims {
172
+ /** Issuer AID (`iss`) — the peer that minted and is bound by the TCT. */
173
+ iss: string
174
+ /** Subject AID (`sub`) — the holder the TCT authorizes. */
175
+ sub: string
176
+ /** Audience AID (`aud`). In v0.2 this equals `sub`. */
177
+ aud: string
178
+ /** Capability grants the TCT authorizes. */
179
+ grants: Array<string>
180
+ /** Issued-at, Unix seconds (`iat`). */
181
+ iat: number
182
+ /** Expiry, Unix seconds (`exp`). */
183
+ exp: number
184
+ /** TCT unique identifier (`jti`, UUID string). */
185
+ jti: string
186
+ }
187
+ /**
188
+ * A completed handshake: the TCT the peer issued to us (as an opaque
189
+ * compact-JWS token plus its decoded claims) and the optional companion
190
+ * grant voucher (`typ: aitp-grant+jwt`) used to mint delegations
191
+ * (RFC-AITP-0005 §8). `grantVoucher` is `null` when the issuing peer's
192
+ * policy forbids us from delegating.
193
+ */
194
+ export interface JsCompletedHandshake {
195
+ /**
196
+ * The TCT as an opaque compact-JWS string. Pass verbatim to
197
+ * `verifyTct` / `verifyTctCached`.
198
+ */
199
+ tct: string
200
+ /** The decoded (already-verified) TCT claims. */
201
+ claims: JsHandshakeTctClaims
202
+ /**
203
+ * The companion grant voucher (compact JWS), or `null`. Pass to
204
+ * `buildDelegation` to delegate the held grants.
205
+ */
206
+ grantVoucher?: string
207
+ }
208
+ /**
209
+ * Result of `processCommit`: response body plus the completed handshake
210
+ * (held TCT token, its claims, and the optional grant voucher).
211
+ */
164
212
  export interface JsCommitAckResult {
165
213
  /** `MUTUAL_COMMIT_ACK` envelope JSON — set as the HTTP response body. */
166
214
  ackJson: string
167
- /** `TctEnvelope` JSON the initiator issued to us. */
168
- tctJson: string
215
+ /** The TCT (and voucher) the initiator issued to us. */
216
+ completed: JsCompletedHandshake
169
217
  }
170
218
  /** The verified peer identity carried by a TCT. */
171
219
  export interface JsTctIdentity {
172
- /** AID of the agent that issued (and is bound by) the TCT. */
220
+ /** AID of the agent that issued (and is bound by) the TCT (`iss`). */
173
221
  peerAid: string
174
222
  /** Capability grants the TCT authorizes. */
175
223
  grants: Array<string>
176
- /** Expiry, Unix seconds. */
224
+ /** Expiry, Unix seconds (`exp`). */
177
225
  expiresAt: number
178
226
  /** TCT unique identifier (`jti`). */
179
227
  jti: string
@@ -235,30 +283,44 @@ export declare class AitpAgent {
235
283
  */
236
284
  newResponder(jwks?: JwksProvider | undefined | null, opts?: SessionOpts | undefined | null): JsResponderSession
237
285
  /**
238
- * Verify a TCT JSON string and require `requiredGrant`. Rejects on
239
- * an invalid, mis-audienced, expired, or under-scoped TCT.
286
+ * Verify a compact-JWS TCT token and require `requiredGrant`.
287
+ * Rejects on an invalid, mis-audienced, expired, revoked, or
288
+ * under-scoped TCT.
240
289
  *
241
290
  * `expectedAudience` defaults to `null`, which means "verify as the
242
291
  * holder" (RFC-AITP-0005 §9 receipt model — `this.aid` is used).
243
292
  * Resource servers verifying a TCT presented by a peer should pass
244
- * the TCT's own `audience` field as `expectedAudience` (in v0.1 this
245
- * equals `subject`).
293
+ * the TCT's own `aud` claim as `expectedAudience` (in v0.2 this
294
+ * equals `sub`).
295
+ *
296
+ * `revokedJtis` (F-1) is an optional list of revoked TCT `jti`
297
+ * strings; any TCT whose `jti` is in the list is rejected even if
298
+ * otherwise valid. Omit (or pass `null`) to disable the revocation
299
+ * gate. The caller is responsible for sourcing the revoked set (e.g.
300
+ * from a `RevocationList` it fetched and verified).
246
301
  */
247
- verifyTct(tctJson: string, requiredGrant: string, expectedAudience?: string | undefined | null): JsTctIdentity
302
+ verifyTct(tctToken: string, requiredGrant: string, expectedAudience?: string | undefined | null, revokedJtis?: Array<string> | undefined | null): JsTctIdentity
248
303
  /**
249
304
  * Like `verifyTct`, but consults a `TctStore` first: a byte-identical,
250
305
  * already-verified, still-valid TCT skips the signature check (the
251
306
  * verification hot path for an agent that sees the same TCT on many
252
- * requests). All cheap policy checks (expiry, audience, required grant)
253
- * still run on every call; only the signature check is elided.
307
+ * requests). All cheap policy checks (expiry, audience, required grant,
308
+ * and the optional `revokedJtis` gate) still run on every call; only the
309
+ * signature check is elided.
310
+ */
311
+ verifyTctCached(tctToken: string, requiredGrant: string, store: JsTctStore, expectedAudience?: string | undefined | null, revokedJtis?: Array<string> | undefined | null): JsTctIdentity
312
+ /**
313
+ * Build a delegation compact-JWS token from a held **grant voucher**
314
+ * (RFC-AITP-0006). `voucherToken` is the `grantVoucher` surfaced by
315
+ * `complete()` / `processCommit()`. The delegatee's key binding is
316
+ * derived from `delegateeAid` itself, so no separate public-key
317
+ * argument is needed in v0.2.
254
318
  */
255
- verifyTctCached(tctJson: string, requiredGrant: string, store: JsTctStore, expectedAudience?: string | undefined | null): JsTctIdentity
256
- /** Build a `DelegationEnvelope` JSON from a held TCT (RFC-AITP-0006). */
257
- buildDelegation(heldTctEnvelopeJson: string, delegateeAid: string, delegateePubkeyB64U: string, scope: Array<string>, ttlSecs?: number | undefined | null): string
319
+ buildDelegation(voucherToken: string, delegateeAid: string, scope: Array<string>, ttlSecs?: number | undefined | null): string
258
320
  /**
259
- * Mint a fresh `TctEnvelope` JSON for a delegatee after the verifier has
260
- * confirmed the delegation. The subject_pubkey binding is taken from the
261
- * verified token's `cnf` field.
321
+ * Mint a fresh compact-JWS TCT for a delegatee after the verifier has
322
+ * confirmed the delegation. The subject-key binding is derived from
323
+ * the verified delegation's `delegatee` AID.
262
324
  */
263
325
  issueTctForDelegatee(verified: JsDelegationVerified, ttlSecs?: number | undefined | null): string
264
326
  /**
@@ -269,18 +331,18 @@ export declare class AitpAgent {
269
331
  signRevocationList(entries: Array<RevocationEntryInput>, expiresInSecs?: number | undefined | null): string
270
332
  /**
271
333
  * Holder side: build a `TctRenewalPayload` JSON for an in-band
272
- * renewal of `currentTctEnvelopeJson` (RFC-AITP-0005 §10).
334
+ * renewal of `currentTctToken` — the holder's current TCT as a
335
+ * compact-JWS string (RFC-AITP-0005 §10).
273
336
  *
274
- * **Gated by the `experimental-renewal` Cargo feature.** Off in
275
- * the default `.node` artifact; build with
276
- * `napi build --release -- --features experimental-renewal`.
337
+ * Behind the `renewal` Cargo feature, which is **on by default**; a
338
+ * `--no-default-features` build omits it.
277
339
  */
278
- buildRenewalRequest(currentTctEnvelopeJson: string): string
340
+ buildRenewalRequest(currentTctToken: string): string
279
341
  /**
280
342
  * Issuer side: verify a `TctRenewalPayload` JSON request and mint a
281
- * fresh `TctEnvelope` JSON.
343
+ * fresh TCT, returned as a compact-JWS token string.
282
344
  *
283
- * **Gated by the `experimental-renewal` Cargo feature.**
345
+ * Behind the `renewal` Cargo feature (on by default).
284
346
  */
285
347
  processRenewalRequest(requestPayloadJson: string, manifestExpUnixSecs: number, newTtlSecs: number): string
286
348
  }
@@ -301,8 +363,12 @@ export declare class SessionBundleBuilder {
301
363
  sessionId(uuidStr: string): this
302
364
  /** Override `issued_at` (unix seconds). Defaults to "now" at build. */
303
365
  issuedAt(unixSecs: number): this
304
- /** Add a participant entry. `tctEnvelopeJson` is a TctEnvelope JSON. */
305
- participant(aid: string, tctEnvelopeJson: string): this
366
+ /**
367
+ * Add a participant entry. `tctToken` is the participant's TCT as an
368
+ * opaque compact-JWS string (the `tct` field returned by `complete()`
369
+ * / `processCommit()`), carried into the bundle verbatim.
370
+ */
371
+ participant(aid: string, tctToken: string): this
306
372
  /** Construct, sign, and return the `SessionBundleEnvelope` JSON. */
307
373
  build(): string
308
374
  }
@@ -358,10 +424,11 @@ export declare class JsInitiatorSession {
358
424
  /** Step 2 — process `MUTUAL_HELLO_ACK`, produce `MUTUAL_COMMIT`. */
359
425
  processHelloAck(helloAckJson: string, sessionId: string): string
360
426
  /**
361
- * Step 3 — process `MUTUAL_COMMIT_ACK`. Returns the `TctEnvelope`
362
- * JSON the peer issued to us.
427
+ * Step 3 — process `MUTUAL_COMMIT_ACK`. Returns the completed
428
+ * handshake: the TCT the peer issued to us (opaque compact-JWS
429
+ * token plus its decoded claims) and the optional grant voucher.
363
430
  */
364
- complete(commitAckJson: string): string
431
+ complete(commitAckJson: string): JsCompletedHandshake
365
432
  }
366
433
  /** Inbound handshake session — drives the responder side. */
367
434
  export declare class JsResponderSession {
@@ -377,14 +444,14 @@ export declare class JsResponderSession {
377
444
  export type JsTctStore = TctStore
378
445
  /**
379
446
  * A bounded, in-memory cache of **successful** TCT verifications, keyed by
380
- * the SHA-256 of the exact TCT envelope JSON bytes.
447
+ * the SHA-256 of the exact compact-JWS TCT token bytes.
381
448
  *
382
449
  * Purpose: a high-throughput verifier (e.g. a writer agent checking a
383
450
  * capability on every request) that repeatedly sees the *same* TCT can skip
384
451
  * the Ed25519/P-256 signature verification after the first time.
385
452
  *
386
453
  * **Safety.** The key is a cryptographic hash of the exact signed bytes, so
387
- * only a byte-identical envelope — whose signature was already verified once
454
+ * only a byte-identical token — whose signature was already verified once
388
455
  * — can hit. A tampered token hashes differently, misses, and is fully
389
456
  * verified. The cheap policy checks (expiry, audience, required grant) are
390
457
  * re-run on **every** hit; only the signature check is elided. Eviction is
package/index.js CHANGED
@@ -310,13 +310,13 @@ if (!nativeBinding) {
310
310
  throw new Error(`Failed to load native binding`)
311
311
  }
312
312
 
313
- const { AitpAgent, SessionBundleBuilder, verifySessionBundle, verifyDelegation, verifyDelegationExperimentalMultihop, computeAidJkt, JwksProvider, computeSpkiHash, SpkiPinVerifier, JsInitiatorSession, JsResponderSession, TctStore, verifyManifestJson } = nativeBinding
313
+ const { AitpAgent, SessionBundleBuilder, verifySessionBundle, verifyDelegation, verifyDelegationMultihop, computeAidJkt, JwksProvider, computeSpkiHash, SpkiPinVerifier, JsInitiatorSession, JsResponderSession, TctStore, verifyManifestJson } = nativeBinding
314
314
 
315
315
  module.exports.AitpAgent = AitpAgent
316
316
  module.exports.SessionBundleBuilder = SessionBundleBuilder
317
317
  module.exports.verifySessionBundle = verifySessionBundle
318
318
  module.exports.verifyDelegation = verifyDelegation
319
- module.exports.verifyDelegationExperimentalMultihop = verifyDelegationExperimentalMultihop
319
+ module.exports.verifyDelegationMultihop = verifyDelegationMultihop
320
320
  module.exports.computeAidJkt = computeAidJkt
321
321
  module.exports.JwksProvider = JwksProvider
322
322
  module.exports.computeSpkiHash = computeSpkiHash
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@agentidentitytrustprotocol/aitp",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "description": "Agent Identity Trust Protocol — Node.js SDK",
5
5
  "license": "MIT OR Apache-2.0",
6
6
  "repository": {
@@ -31,8 +31,8 @@
31
31
  "scripts": {
32
32
  "build": "napi build --platform --release",
33
33
  "build:debug": "napi build --platform",
34
- "build:experimental": "napi build --platform --release --features experimental",
35
- "build:experimental:debug": "napi build --platform --features experimental",
34
+ "build:minimal": "napi build --platform --release --no-default-features",
35
+ "build:minimal:debug": "napi build --platform --no-default-features",
36
36
  "artifacts": "napi artifacts",
37
37
  "prepublishOnly": "napi prepublish -t npm",
38
38
  "version": "napi version",
@@ -53,9 +53,9 @@
53
53
  "registry": "https://registry.npmjs.org/"
54
54
  },
55
55
  "optionalDependencies": {
56
- "@agentidentitytrustprotocol/aitp-darwin-x64": "0.2.0",
57
- "@agentidentitytrustprotocol/aitp-darwin-arm64": "0.2.0",
58
- "@agentidentitytrustprotocol/aitp-linux-x64-gnu": "0.2.0",
59
- "@agentidentitytrustprotocol/aitp-linux-arm64-gnu": "0.2.0"
56
+ "@agentidentitytrustprotocol/aitp-darwin-x64": "0.4.0",
57
+ "@agentidentitytrustprotocol/aitp-darwin-arm64": "0.4.0",
58
+ "@agentidentitytrustprotocol/aitp-linux-x64-gnu": "0.4.0",
59
+ "@agentidentitytrustprotocol/aitp-linux-arm64-gnu": "0.4.0"
60
60
  }
61
61
  }