@vess-id/ai-identity 0.0.0-dev-20260902121045

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 (173) hide show
  1. package/README.md +265 -0
  2. package/dist/agent/agent-did-manager.d.ts +97 -0
  3. package/dist/agent/agent-did-manager.d.ts.map +1 -0
  4. package/dist/auth/auth-provider.d.ts +51 -0
  5. package/dist/auth/auth-provider.d.ts.map +1 -0
  6. package/dist/auth/index.d.ts +2 -0
  7. package/dist/auth/index.d.ts.map +1 -0
  8. package/dist/client.d.ts +63 -0
  9. package/dist/client.d.ts.map +1 -0
  10. package/dist/config/index.d.ts +84 -0
  11. package/dist/config/index.d.ts.map +1 -0
  12. package/dist/constraint/constraint-evaluator.d.ts +103 -0
  13. package/dist/constraint/constraint-evaluator.d.ts.map +1 -0
  14. package/dist/constraint/index.d.ts +5 -0
  15. package/dist/constraint/index.d.ts.map +1 -0
  16. package/dist/did/agent.d.ts +58 -0
  17. package/dist/did/agent.d.ts.map +1 -0
  18. package/dist/did/did-utils.d.ts +82 -0
  19. package/dist/did/did-utils.d.ts.map +1 -0
  20. package/dist/did/key-manager.d.ts +19 -0
  21. package/dist/did/key-manager.d.ts.map +1 -0
  22. package/dist/gateway/gateway-client.d.ts +103 -0
  23. package/dist/gateway/gateway-client.d.ts.map +1 -0
  24. package/dist/gateway/index.d.ts +2 -0
  25. package/dist/gateway/index.d.ts.map +1 -0
  26. package/dist/grant/grant-manager.d.ts +140 -0
  27. package/dist/grant/grant-manager.d.ts.map +1 -0
  28. package/dist/grant/index.d.ts +2 -0
  29. package/dist/grant/index.d.ts.map +1 -0
  30. package/dist/identity/device-enroll-manager.d.ts +117 -0
  31. package/dist/identity/device-enroll-manager.d.ts.map +1 -0
  32. package/dist/identity/user-identity-manager.d.ts +123 -0
  33. package/dist/identity/user-identity-manager.d.ts.map +1 -0
  34. package/dist/identity/user-key-pair-manager.d.ts +22 -0
  35. package/dist/identity/user-key-pair-manager.d.ts.map +1 -0
  36. package/dist/index.d.mts +42685 -0
  37. package/dist/index.d.ts +57 -0
  38. package/dist/index.d.ts.map +1 -0
  39. package/dist/index.js +19534 -0
  40. package/dist/index.js.map +1 -0
  41. package/dist/index.mjs +19347 -0
  42. package/dist/index.mjs.map +1 -0
  43. package/dist/internal-signature/canonical.d.ts +80 -0
  44. package/dist/internal-signature/canonical.d.ts.map +1 -0
  45. package/dist/internal-signature/index.d.ts +17 -0
  46. package/dist/internal-signature/index.d.ts.map +1 -0
  47. package/dist/internal-signature/signer.d.ts +76 -0
  48. package/dist/internal-signature/signer.d.ts.map +1 -0
  49. package/dist/policy/cedar-engine.d.ts +334 -0
  50. package/dist/policy/cedar-engine.d.ts.map +1 -0
  51. package/dist/policy/cedar-entities.d.ts +59 -0
  52. package/dist/policy/cedar-entities.d.ts.map +1 -0
  53. package/dist/policy/decision.d.ts +46 -0
  54. package/dist/policy/decision.d.ts.map +1 -0
  55. package/dist/policy/index.d.ts +15 -0
  56. package/dist/policy/index.d.ts.map +1 -0
  57. package/dist/registry/access-orchestrator.d.ts +184 -0
  58. package/dist/registry/access-orchestrator.d.ts.map +1 -0
  59. package/dist/registry/action-aliases.d.ts +37 -0
  60. package/dist/registry/action-aliases.d.ts.map +1 -0
  61. package/dist/registry/action-input-validator.d.ts +19 -0
  62. package/dist/registry/action-input-validator.d.ts.map +1 -0
  63. package/dist/registry/action-normalizer.d.ts +47 -0
  64. package/dist/registry/action-normalizer.d.ts.map +1 -0
  65. package/dist/registry/action-registry-json.d.ts +35897 -0
  66. package/dist/registry/action-registry-json.d.ts.map +1 -0
  67. package/dist/registry/action-registry.d.ts +101 -0
  68. package/dist/registry/action-registry.d.ts.map +1 -0
  69. package/dist/registry/action-risk.d.ts +109 -0
  70. package/dist/registry/action-risk.d.ts.map +1 -0
  71. package/dist/registry/action-summary.d.ts +16 -0
  72. package/dist/registry/action-summary.d.ts.map +1 -0
  73. package/dist/registry/index.d.ts +14 -0
  74. package/dist/registry/index.d.ts.map +1 -0
  75. package/dist/registry/providers.d.ts +32 -0
  76. package/dist/registry/providers.d.ts.map +1 -0
  77. package/dist/registry/reauth-constants.d.ts +56 -0
  78. package/dist/registry/reauth-constants.d.ts.map +1 -0
  79. package/dist/registry/resource-type-labels.d.ts +15 -0
  80. package/dist/registry/resource-type-labels.d.ts.map +1 -0
  81. package/dist/registry/resource-types.d.ts +47 -0
  82. package/dist/registry/resource-types.d.ts.map +1 -0
  83. package/dist/resolver/approval-time-resolution.d.ts +72 -0
  84. package/dist/resolver/approval-time-resolution.d.ts.map +1 -0
  85. package/dist/resolver/canonical-resource-id.d.ts +37 -0
  86. package/dist/resolver/canonical-resource-id.d.ts.map +1 -0
  87. package/dist/resolver/compare-resource-id.d.ts +37 -0
  88. package/dist/resolver/compare-resource-id.d.ts.map +1 -0
  89. package/dist/resolver/salient-digest.d.ts +48 -0
  90. package/dist/resolver/salient-digest.d.ts.map +1 -0
  91. package/dist/resolver/target-resolver.d.ts +28 -0
  92. package/dist/resolver/target-resolver.d.ts.map +1 -0
  93. package/dist/state/index.d.ts +3 -0
  94. package/dist/state/index.d.ts.map +1 -0
  95. package/dist/state/json-state-store.d.ts +24 -0
  96. package/dist/state/json-state-store.d.ts.map +1 -0
  97. package/dist/state/state-store.interface.d.ts +37 -0
  98. package/dist/state/state-store.interface.d.ts.map +1 -0
  99. package/dist/storage/filesystem-key-storage.d.ts +16 -0
  100. package/dist/storage/filesystem-key-storage.d.ts.map +1 -0
  101. package/dist/storage/index.d.ts +4 -0
  102. package/dist/storage/index.d.ts.map +1 -0
  103. package/dist/storage/key-storage.interface.d.ts +42 -0
  104. package/dist/storage/key-storage.interface.d.ts.map +1 -0
  105. package/dist/storage/memory-key-storage.d.ts +17 -0
  106. package/dist/storage/memory-key-storage.d.ts.map +1 -0
  107. package/dist/tool/tool-manager.d.ts +44 -0
  108. package/dist/tool/tool-manager.d.ts.map +1 -0
  109. package/dist/types/agent.d.ts +139 -0
  110. package/dist/types/agent.d.ts.map +1 -0
  111. package/dist/types/audit.d.ts +23 -0
  112. package/dist/types/audit.d.ts.map +1 -0
  113. package/dist/types/cedar-policy.d.ts +60 -0
  114. package/dist/types/cedar-policy.d.ts.map +1 -0
  115. package/dist/types/connector-plugin.d.ts +252 -0
  116. package/dist/types/connector-plugin.d.ts.map +1 -0
  117. package/dist/types/connectors.d.ts +39 -0
  118. package/dist/types/connectors.d.ts.map +1 -0
  119. package/dist/types/context.d.ts +152 -0
  120. package/dist/types/context.d.ts.map +1 -0
  121. package/dist/types/did.d.ts +18 -0
  122. package/dist/types/did.d.ts.map +1 -0
  123. package/dist/types/errors.d.ts +24 -0
  124. package/dist/types/errors.d.ts.map +1 -0
  125. package/dist/types/grant.d.ts +522 -0
  126. package/dist/types/grant.d.ts.map +1 -0
  127. package/dist/types/index.d.ts +22 -0
  128. package/dist/types/index.d.ts.map +1 -0
  129. package/dist/types/intent.d.ts +133 -0
  130. package/dist/types/intent.d.ts.map +1 -0
  131. package/dist/types/invitation.d.ts +97 -0
  132. package/dist/types/invitation.d.ts.map +1 -0
  133. package/dist/types/jira.d.ts +348 -0
  134. package/dist/types/jira.d.ts.map +1 -0
  135. package/dist/types/oauth.d.ts +72 -0
  136. package/dist/types/oauth.d.ts.map +1 -0
  137. package/dist/types/organization.d.ts +77 -0
  138. package/dist/types/organization.d.ts.map +1 -0
  139. package/dist/types/permission-mode.d.ts +138 -0
  140. package/dist/types/permission-mode.d.ts.map +1 -0
  141. package/dist/types/permission-vc.d.ts +800 -0
  142. package/dist/types/permission-vc.d.ts.map +1 -0
  143. package/dist/types/receipt.d.ts +133 -0
  144. package/dist/types/receipt.d.ts.map +1 -0
  145. package/dist/types/target-binding.d.ts +163 -0
  146. package/dist/types/target-binding.d.ts.map +1 -0
  147. package/dist/types/tier.d.ts +13 -0
  148. package/dist/types/tier.d.ts.map +1 -0
  149. package/dist/types/vc.d.ts +213 -0
  150. package/dist/types/vc.d.ts.map +1 -0
  151. package/dist/types/vp.d.ts +25 -0
  152. package/dist/types/vp.d.ts.map +1 -0
  153. package/dist/utils/action-classifier.d.ts +13 -0
  154. package/dist/utils/action-classifier.d.ts.map +1 -0
  155. package/dist/utils/crypto.d.ts +22 -0
  156. package/dist/utils/crypto.d.ts.map +1 -0
  157. package/dist/utils/freemail-domains.d.ts +13 -0
  158. package/dist/utils/freemail-domains.d.ts.map +1 -0
  159. package/dist/utils/sdjwt-client.d.ts +415 -0
  160. package/dist/utils/sdjwt-client.d.ts.map +1 -0
  161. package/dist/utils/sdjwt-disclosure.d.ts +13 -0
  162. package/dist/utils/sdjwt-disclosure.d.ts.map +1 -0
  163. package/dist/utils/tier-utils.d.ts +15 -0
  164. package/dist/utils/tier-utils.d.ts.map +1 -0
  165. package/dist/vc/api-vc-manager.d.ts +43 -0
  166. package/dist/vc/api-vc-manager.d.ts.map +1 -0
  167. package/dist/vc/vc-manager.d.ts +55 -0
  168. package/dist/vc/vc-manager.d.ts.map +1 -0
  169. package/dist/vp/kb-jwt-builder.d.ts +89 -0
  170. package/dist/vp/kb-jwt-builder.d.ts.map +1 -0
  171. package/dist/vp/vp-manager.d.ts +75 -0
  172. package/dist/vp/vp-manager.d.ts.map +1 -0
  173. package/package.json +66 -0
@@ -0,0 +1,415 @@
1
+ import { SDJwtVcInstance } from '@sd-jwt/sd-jwt-vc';
2
+ import { KeyManager } from '../did/key-manager';
3
+ import type { DisclosureFrame } from '@sd-jwt/types';
4
+ import type { JWK } from 'jose';
5
+ export declare class SDJwtClient {
6
+ /**
7
+ * 🔴 Keyed by DID **and** by the identity of the key that was resolved.
8
+ *
9
+ * The instance holds a signer built from a private key the KeyManager
10
+ * handed over, so two stores holding *different* keys for one DID must not
11
+ * share an instance. Keying on the DID alone returned whichever one was
12
+ * built first — and since `setKeyManager` replaces a static field,
13
+ * constructing a second VPManager silently repointed every later lookup at
14
+ * a store that did not have the key. Measured: an agent that generated its
15
+ * DID through one manager could not present with another, failing as
16
+ * `Private key not found for holder` with the key sitting in the first
17
+ * manager's store the whole time.
18
+ *
19
+ * 🔴 The discriminator is the KEY, not the KeyManager object. Keying on
20
+ * object identity (a WeakMap-assigned `km0`/`km1`/…) fixed the mix-up and
21
+ * broke two other things, because the api builds a throwaway KeyManager
22
+ * per request — `new APIVCManager(new KeyManager(ephemeral))` at
23
+ * grant/services/remote-vc-issuer.service.ts:2234, which runs on every
24
+ * tool-invoke auto-issue, plus five more sites:
25
+ *
26
+ * 1. Same key material, new object, new id — so a long-lived issuer
27
+ * (user/services/sdjwt-credential.service.ts:69) could not read back
28
+ * its own warm entry once a per-request manager had replaced the
29
+ * static. It failed outright rather than falling back. Measured:
30
+ * `{"resolved":false,"msg":"Private key not found for issuer: … km1"}`
31
+ * where the DID-only key gave `{"resolved":true}` — by accident, by
32
+ * returning the wrong signer on a cache hit.
33
+ *
34
+ * 2. Entries accumulated without bound. `keyManagerIds` is a WeakMap, so
35
+ * a collected manager releases its id — but the Map entry keyed by
36
+ * that id string stays, and a signer closes over a DECRYPTED PRIVATE
37
+ * KEY. Nothing in the api calls `clearIssuerCache`. Measured over 25
38
+ * issuances of one DID: `{"instanceCount":25,"signerCount":25}` where
39
+ * the DID-only key gave 1.
40
+ *
41
+ * A thumbprint (RFC 7638) is the right granularity for both: same key ⇒
42
+ * same entry whoever holds it, different key ⇒ different entry. It is
43
+ * computed over the public members only (`crv`/`kty`/`x`/`y` — `d`, `kid`
44
+ * and `alg` are excluded by the spec), which is what makes two stores
45
+ * holding the same keypair agree. Two *different* private keys sharing a
46
+ * public half is not a case that exists for a valid EC pair, so nothing is
47
+ * conflated that should not be. Measured at ~1.7µs per call, against an
48
+ * ECDSA signature that follows it.
49
+ */
50
+ private static instances;
51
+ /**
52
+ * 🔴 Only ever read as a fallback — when a call arrives without a KeyManager.
53
+ *
54
+ * `VCManager`, `VPManager` and `APIVCManager` used to assign it in their
55
+ * constructors. They no longer do — every one of them passes its own
56
+ * KeyManager to each call — so within the SDK this field holds whatever an
57
+ * external consumer set via the deprecated {@link setKeyManager}, and
58
+ * otherwise a default `new KeyManager()` that {@link resolveKey} creates the
59
+ * first time it actually has to fall back. Nothing else writes it, and a
60
+ * call that carries its own store never causes that default to exist.
61
+ *
62
+ * It stays because `SDJwtClient` is a public export and a consumer pairing
63
+ * `setKeyManager` with {@link getSDJwtInstance} would otherwise break on a
64
+ * minor release. Removal belongs to the next major.
65
+ */
66
+ private static keyManager;
67
+ private static signerCache;
68
+ private static verifierCache;
69
+ /**
70
+ * A stable identifier for the key itself, shared by every store holding it.
71
+ *
72
+ * 🔴 Falls back to a per-call unique value rather than to a constant when
73
+ * the thumbprint cannot be computed. A constant would make two unrelated
74
+ * malformed keys collide on one cache entry, which is the mix-up this whole
75
+ * scheme exists to prevent — the safe direction of failure is "cache
76
+ * nothing", never "share an entry". In practice this is unreachable for a
77
+ * key that got through `getKey`; it is here so a future JWK shape degrades
78
+ * into a slow path instead of a wrong one.
79
+ */
80
+ private static keyId;
81
+ private static nextFallbackKeyId;
82
+ /**
83
+ * 🔴 Cache keys are built here and nowhere else.
84
+ *
85
+ * Three maps, three key shapes. When they were assembled inline at each
86
+ * call site, `clearIssuerCache` wrote its own third version from memory and
87
+ * matched only one of them: it deleted `issuerDid` where the instance was
88
+ * stored as `${did}:issuer:${kmId}`, and `signer:${did}` where the signer
89
+ * was stored as `signer:${did}:${kmId}`. Measured before the fix — one
90
+ * issuer cached, then cleared:
91
+ *
92
+ * BEFORE {"instanceCount":1,"signerCount":1,"verifierCount":1}
93
+ * AFTER {"instanceCount":1,"signerCount":1,"verifierCount":0}
94
+ *
95
+ * The signer closes over a decrypted private key, so the two that survived
96
+ * were the two that mattered. Keeping writers and the eraser on one
97
+ * definition is what stops that from drifting apart again.
98
+ */
99
+ private static instanceKey;
100
+ private static signerKey;
101
+ /**
102
+ * The part of a key that identifies the DID, up to and including the
103
+ * delimiter before the key-identity segment.
104
+ *
105
+ * 🔴 `clearIssuerCache` matches on these rather than rebuilding prefixes of
106
+ * its own — writing the shape a second time is the mistake being fixed. The
107
+ * trailing `:` is load-bearing: matching a bare DID would make
108
+ * `did:key:abc` also evict `did:key:abcd`.
109
+ */
110
+ private static instancePrefix;
111
+ private static signerPrefix;
112
+ /**
113
+ * 🔴 Carries the key identity too, symmetrically with {@link signerKey}.
114
+ *
115
+ * It used to be keyed by DID alone, on the reasoning that "a verifier is
116
+ * built from the public half, which is the same value no matter which store
117
+ * the private key came out of". That holds for the case the caches were
118
+ * built for — one keypair, several stores — and fails for the exact case
119
+ * the key segment exists to separate: two stores holding *different* keys
120
+ * under one DID. There the second caller reused the first's verifier and so
121
+ * checked signatures against a public key that was not its own.
122
+ *
123
+ * Costs nothing now that the segment is the key's own thumbprint rather
124
+ * than a per-object id: the same keypair still yields one entry however
125
+ * many managers hold it, which is what the old comment actually wanted.
126
+ */
127
+ private static verifierKey;
128
+ private static verifierPrefix;
129
+ private constructor();
130
+ /**
131
+ * Initialize with KeyManager for DID-based key management
132
+ *
133
+ * @deprecated Pass the KeyManager to the call instead:
134
+ * {@link getIssuerInstance}`(did, keyManager)`,
135
+ * {@link getHolderInstance}`(did, keyManager)`, {@link issueSDJWT} and
136
+ * {@link verifySDJWT} all take one. This setter writes a **static** field,
137
+ * so every manager an application constructs repoints key resolution for
138
+ * every other one — construction order decides which store is searched.
139
+ *
140
+ * 🔴 Not a style preference; it caused a production failure. A long-lived
141
+ * issuer and a per-request `new APIVCManager(new KeyManager(ephemeral))`
142
+ * coexist in the api, and whichever ran last won: the long-lived one then
143
+ * signed with a store that was not its own or failed outright with
144
+ * `Private key not found for issuer: …`. See PR #1441.
145
+ *
146
+ * Retained for external SDK consumers that pair it with
147
+ * {@link getSDJwtInstance}; scheduled for removal in the next major.
148
+ */
149
+ static setKeyManager(keyManager: KeyManager): void;
150
+ /**
151
+ * Get SDJwtVcInstance for issuer role (VC issuance)
152
+ */
153
+ static getIssuerInstance(issuerDid: string, keyManager?: KeyManager): Promise<SDJwtVcInstance>;
154
+ /**
155
+ * Get SDJwtVcInstance for holder role (VP presentation)
156
+ */
157
+ static getHolderInstance(holderDid: string, keyManager?: KeyManager): Promise<SDJwtVcInstance>;
158
+ /**
159
+ * Resolve the key, then look in the cache — in that order.
160
+ *
161
+ * 🔴 The order is the fix, not an implementation detail. The cache key
162
+ * names the key that was resolved, so it cannot be built before resolving,
163
+ * and the store must therefore be consulted on a hit as well as a miss.
164
+ * That is what makes a warm entry reachable from any manager holding the
165
+ * same key: with the KeyManager object in the key, the caller whose store
166
+ * DID hold the key looked under a name nobody had written to and got
167
+ * `Private key not found` — the store had it the whole time.
168
+ *
169
+ * The extra work on a hit is one `getKey` (an in-memory or DB read the
170
+ * caller would owe anyway on a miss) plus a ~1.7µs thumbprint. What is
171
+ * saved is the SDJwtVcInstance and, more to the point, re-importing the
172
+ * key material into a signer.
173
+ */
174
+ private static getInstance;
175
+ /**
176
+ * Fetch the DID's private key from the given store (or the static one) and
177
+ * derive the identity the caches key on.
178
+ */
179
+ private static resolveKey;
180
+ /**
181
+ * Get SDJwtVcInstance with specified role (backward compatibility)
182
+ *
183
+ * @deprecated Call {@link getIssuerInstance}`(did, keyManager)` or
184
+ * {@link getHolderInstance}`(did, keyManager)` directly — this wrapper adds
185
+ * nothing but the role switch, and the role is known at every call site.
186
+ *
187
+ * 🔴 `keyManager` was added here because omitting it was the defect: with no
188
+ * way to name a store, every caller of this wrapper fell through to the
189
+ * static field and so was the one path that could not benefit from the
190
+ * PR #1441 fix. Callers that still omit it keep the old static behaviour, so
191
+ * existing external code is unaffected.
192
+ */
193
+ static getSDJwtInstance(did: string, options?: {
194
+ role?: 'issuer' | 'holder';
195
+ keyManager?: KeyManager;
196
+ }): Promise<SDJwtVcInstance>;
197
+ /**
198
+ * Create a new SDJwtVcInstance with DID-based keys and role
199
+ */
200
+ private static createInstance;
201
+ /**
202
+ * Claims that MUST NOT be selectively disclosable.
203
+ *
204
+ * - cnf: Proof of Possession binding (RFC 7800). If disclosable, Holder can
205
+ * hide cnf to bypass PoP verification and transfer VC to another party.
206
+ * - Standard JWT registered claims (iss, sub, exp, iat, nbf, jti) must
207
+ * always be visible for signature verification and expiry checks.
208
+ * - vct: SD-JWT VC credential type discriminator.
209
+ */
210
+ private static readonly NEVER_DISCLOSE;
211
+ /**
212
+ * Claims that decide whether an action is PERMITTED, and so must not be
213
+ * withholdable by the party they constrain.
214
+ *
215
+ * 🔴 Separate from NEVER_DISCLOSE on purpose. That set is about structural
216
+ * integrity — hide `cnf` and Proof of Possession cannot be checked at all.
217
+ * This set is about authorisation: these fields are readable, they simply
218
+ * must not be OPTIONAL, because SD-JWT makes an undisclosed field
219
+ * physically absent rather than merely hidden. A holder who omits the
220
+ * disclosure presents a credential with no constraints on it.
221
+ *
222
+ * The harm is not theoretical. Gate-2 permits when the delegate list is
223
+ * empty (tool-executor.service.ts) — deliberate backward compatibility for
224
+ * two credential shapes that genuinely carry no `delegates` — and a
225
+ * withheld disclosure lands in that same branch. Cedar Gate-1 backstops
226
+ * high-risk actions, but only where the Cedar default policy is
227
+ * bootstrapped; that early return's own comment records that a non-Cedar
228
+ * deployment's flat-permission fallback does not risk-gate, making the
229
+ * withholding an unconditional allow there.
230
+ *
231
+ * 🔴 Enforced here rather than by curating each caller's field list. Four
232
+ * issuance paths pass their own arrays — remote-vc-issuer.service.ts,
233
+ * user/services/sdjwt-credential.service.ts (a hardcoded switch that
234
+ * duplicates the SDK config), sdk/src/vc/api-vc-manager.ts, and
235
+ * oauth.service.ts in two places — so fixing one leaves three standing,
236
+ * and a fifth added later would inherit the defect. This function is the
237
+ * single point all of them flow through.
238
+ *
239
+ * It is also the only place that can stop the NESTED case: the recursion
240
+ * below passes every key of a nested object as disclosable regardless of
241
+ * what was requested, which no call-site list can reach.
242
+ *
243
+ * What is NOT here: `approval` and `intent_description`. Those are
244
+ * selective for privacy — an approver's identity, free text — and no gate
245
+ * reads them to decide anything. The line being drawn is "authorisation
246
+ * input", not "sensitive".
247
+ *
248
+ * Field-by-field, with where each is read:
249
+ * - delegates: carries actions/effect/resource (tool-auth.service.ts)
250
+ * - actions: what a delegate may do
251
+ * - tool: prefixes bare actions into the permission string that
252
+ * gates the decision; withheld, `message.post` is emitted
253
+ * instead of `slack.message.post` — a different string
254
+ * - resourceScope: gates the scope match (tool-manager.ts)
255
+ * - permissions: the flat-permission path (tool-auth.service.ts)
256
+ * - effect: whether a delegate rule allows or denies
257
+ * - resource: what a rule applies to
258
+ */
259
+ private static readonly NEVER_SELECTIVE;
260
+ /**
261
+ * Create disclosure frame for selective disclosure
262
+ */
263
+ static createDisclosureFrame<T extends Record<string, any>>(claims: T, selectivelyDisclosable?: string[]): DisclosureFrame<T>;
264
+ /**
265
+ * Issue an SD-JWT with selective disclosure
266
+ */
267
+ static issueSDJWT(payload: Record<string, any>, _privateKey: any, // Not used since we get key from KeyManager based on issuer DID
268
+ selectiveDisclosureFields?: string[], keyManager?: KeyManager): Promise<string>;
269
+ /**
270
+ * Verify an SD-JWT
271
+ */
272
+ static verifySDJWT(credential: string, keyManager?: KeyManager): Promise<{
273
+ valid: boolean;
274
+ payload?: any;
275
+ error?: string;
276
+ }>;
277
+ /**
278
+ * Legacy methods for backward compatibility
279
+ */
280
+ static createSignerVerifier(): Promise<{
281
+ signer: (data: string) => Promise<string>;
282
+ verifier: (data: string, signatureBase64url: string) => Promise<boolean>;
283
+ }>;
284
+ static generateKeyPair(): Promise<import("./crypto").KeyPair>;
285
+ /**
286
+ * Clear caches for optimization
287
+ */
288
+ static clearCaches(): void;
289
+ /**
290
+ * Drop every cache entry holding key material for one DID.
291
+ *
292
+ * 🔴 Scans rather than deletes by exact key, because the caller cannot
293
+ * build the exact keys. Both the instance and signer keys carry a
294
+ * `keyManagerId`, which is private and WeakMap-derived, and this method
295
+ * takes only a DID. The same DID legitimately has one entry per KeyManager
296
+ * that ever resolved it, so anything short of "all of them" leaves a live
297
+ * signer — and a signer closes over a decrypted private key. The maps hold
298
+ * a handful of entries; a linear pass is not worth optimizing away.
299
+ *
300
+ * 🔴 Clears the holder instance too, despite the `Issuer` in the name.
301
+ * The unit being freed is the DID's key material, not a role: a holder
302
+ * instance is constructed with `kbSigner` set to the very same signer
303
+ * object as the issuer's, so evicting the signer while leaving the holder
304
+ * instance cached would keep the decrypted key reachable through the map
305
+ * we claimed to have cleaned. Roles are not separable here; the DID is the
306
+ * only safe granularity.
307
+ *
308
+ * 🔴 Matches on a delimiter, not a bare prefix. `did:key:abc` and
309
+ * `did:key:abcd` are different DIDs, and `startsWith(did)` would take the
310
+ * second one down with the first.
311
+ */
312
+ static clearIssuerCache(issuerDid: string): void;
313
+ /**
314
+ * Get cache statistics
315
+ */
316
+ static getCacheStats(): {
317
+ instanceCount: number;
318
+ signerCount: number;
319
+ verifierCount: number;
320
+ };
321
+ /**
322
+ * Create a verifier function from an external public key
323
+ * This is used for verifying SD-JWTs when you don't have the private key
324
+ * (e.g., API side verifying credentials issued by MCP)
325
+ */
326
+ private static getVerifierFromPublicKey;
327
+ /**
328
+ * Get SDJwtVcInstance for verification with an external public key
329
+ * Used when verifying credentials without having the issuer's private key
330
+ */
331
+ private static getVerificationInstance;
332
+ /**
333
+ * Get SDJwtVcInstance for decoding without verification
334
+ */
335
+ private static getDecodingInstance;
336
+ /**
337
+ * Verify an SD-JWT with an external public key
338
+ * Use this when you have the issuer's public key but not their private key
339
+ *
340
+ * @param credential - The SD-JWT credential string
341
+ * @param publicKey - The issuer's public key (JWK format)
342
+ * @returns Verification result with valid flag and payload
343
+ *
344
+ * @example
345
+ * ```typescript
346
+ * const publicKey = extractPublicKeyFromDid(issuerDid)
347
+ * const result = await SDJwtClient.verifyWithExternalKey(credential, publicKey)
348
+ * if (result.valid) {
349
+ * console.log('Verified claims:', result.payload.claims)
350
+ * }
351
+ * ```
352
+ */
353
+ static verifyWithExternalKey(credential: string, publicKey: JWK): Promise<{
354
+ valid: boolean;
355
+ payload?: any;
356
+ claims?: any;
357
+ error?: string;
358
+ }>;
359
+ /**
360
+ * Verify an SD-JWT by extracting the issuer's public key from the DID
361
+ * Automatically resolves did:jwk DIDs
362
+ *
363
+ * @param credential - The SD-JWT credential string
364
+ * @returns Verification result with valid flag and payload
365
+ *
366
+ * @example
367
+ * ```typescript
368
+ * const result = await SDJwtClient.verifyWithIssuerDid(credential)
369
+ * if (result.valid) {
370
+ * console.log('Issuer:', result.payload.iss)
371
+ * }
372
+ * ```
373
+ */
374
+ static verifyWithIssuerDid(credential: string): Promise<{
375
+ valid: boolean;
376
+ payload?: any;
377
+ claims?: any;
378
+ issuerDid?: string;
379
+ error?: string;
380
+ }>;
381
+ /**
382
+ * Decode an SD-JWT without verification
383
+ * Use this when you need to inspect the credential before verification
384
+ * or when you don't have the issuer's public key
385
+ *
386
+ * WARNING: The returned payload has not been verified!
387
+ * Only use this for inspection purposes, not for authorization decisions.
388
+ *
389
+ * @param credential - The SD-JWT credential string
390
+ * @returns Decoded JWT payload, header, and disclosures
391
+ *
392
+ * @example
393
+ * ```typescript
394
+ * const decoded = await SDJwtClient.decodeWithoutVerification(credential)
395
+ * console.log('Issuer (unverified):', decoded.payload?.iss)
396
+ * console.log('Disclosures:', decoded.disclosures?.length)
397
+ * ```
398
+ */
399
+ static decodeWithoutVerification(credential: string): Promise<{
400
+ payload?: any;
401
+ header?: any;
402
+ disclosures?: any[];
403
+ claims?: any;
404
+ error?: string;
405
+ }>;
406
+ /**
407
+ * Extract issuer DID from an SD-JWT without verification
408
+ * Useful for determining the issuer before verification
409
+ *
410
+ * @param credential - The SD-JWT credential string
411
+ * @returns The issuer DID or null if not found
412
+ */
413
+ static extractIssuerDid(credential: string): string | null;
414
+ }
415
+ //# sourceMappingURL=sdjwt-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdjwt-client.d.ts","sourceRoot":"","sources":["../../src/utils/sdjwt-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ import { CredentialType } from '../types';
2
+ export interface DisclosureFields {
3
+ selectiveFields: string[];
4
+ mandatoryFields: string[];
5
+ neverDisclose: string[];
6
+ decoyCount: number;
7
+ }
8
+ /**
9
+ * Get selective disclosure fields for a given credential type.
10
+ * If requestedFields is provided, they are filtered against the neverDisclose list.
11
+ */
12
+ export declare function getDefaultDisclosureFields(credentialType: CredentialType, requestedFields?: string[]): DisclosureFields;
13
+ //# sourceMappingURL=sdjwt-disclosure.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sdjwt-disclosure.d.ts","sourceRoot":"","sources":["../../src/utils/sdjwt-disclosure.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,UAAU,CAAA;AAEzC,MAAM,WAAW,gBAAgB;IAC/B,eAAe,EAAE,MAAM,EAAE,CAAA;IACzB,eAAe,EAAE,MAAM,EAAE,CAAA;IACzB,aAAa,EAAE,MAAM,EAAE,CAAA;IACvB,UAAU,EAAE,MAAM,CAAA;CACnB;AAqED;;;GAGG;AACH,wBAAgB,0BAA0B,CACxC,cAAc,EAAE,cAAc,EAC9B,eAAe,CAAC,EAAE,MAAM,EAAE,GACzB,gBAAgB,CAYlB"}
@@ -0,0 +1,15 @@
1
+ import { UserTier, TierLimits } from '../types/tier';
2
+ /**
3
+ * Check if a tier limit value represents unlimited.
4
+ * In TIER_LIMITS, -1 is used to represent unlimited values.
5
+ */
6
+ export declare function isUnlimited(value: number): boolean;
7
+ /**
8
+ * Safely resolve a tier string to a valid UserTier, defaulting to 'free'.
9
+ */
10
+ export declare function resolveUserTier(tier: string | undefined | null): UserTier;
11
+ /**
12
+ * Get tier limits for a user's tier, with safe fallback to free tier.
13
+ */
14
+ export declare function getTierLimits(tier: string | undefined | null): TierLimits;
15
+ //# sourceMappingURL=tier-utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tier-utils.d.ts","sourceRoot":"","sources":["../../src/utils/tier-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,UAAU,EAAe,MAAM,eAAe,CAAA;AAEjE;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAElD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,QAAQ,CAKzE;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,UAAU,CAEzE"}
@@ -0,0 +1,43 @@
1
+ import { IssueSDJWTVCRequest, IssueSDJWTVCResult, VerifySDJWTVCResult } from '../types';
2
+ import { KeyManager } from '../did/key-manager';
3
+ /**
4
+ * API-focused VC Manager for server-side operations
5
+ * Provides stateless SD-JWT operations without local persistence
6
+ */
7
+ export declare class APIVCManager {
8
+ private keyManager;
9
+ /**
10
+ * 🔴 Deliberately does NOT call `SDJwtClient.setKeyManager` — that assigned a
11
+ * static, so constructing one of these repointed every other manager's key
12
+ * resolution. Every call below passes `this.keyManager` instead (#1449).
13
+ */
14
+ constructor(keyManager?: KeyManager);
15
+ /**
16
+ * Issue an SD-JWT VC with selective disclosure
17
+ */
18
+ issueSDJWTVC(request: IssueSDJWTVCRequest): Promise<IssueSDJWTVCResult>;
19
+ /**
20
+ * Verify an SD-JWT VC
21
+ */
22
+ verifySDJWTVC(credential: string): Promise<VerifySDJWTVCResult>;
23
+ /**
24
+ * Issue a project access credential
25
+ */
26
+ issueProjectAccessCredential(agentDid: string, projectId: string, permissions: string[], issuerDid: string, expirationHours?: number): Promise<IssueSDJWTVCResult>;
27
+ /**
28
+ * Issue a tool access credential
29
+ */
30
+ issueToolAccessCredential(agentDid: string, toolName: string, actions: string[], projectId: string, issuerDid: string, expirationHours?: number): Promise<IssueSDJWTVCResult>;
31
+ /**
32
+ * Issue a multi-tool access credential
33
+ */
34
+ issueMultiToolCredential(agentDid: string, toolPermissions: Array<{
35
+ tool: string;
36
+ actions: string[];
37
+ }>, projectId: string, issuerDid: string, expirationHours?: number): Promise<IssueSDJWTVCResult>;
38
+ /**
39
+ * Issue an admin credential
40
+ */
41
+ issueAdminCredential(agentDid: string, scope: 'project' | 'global', projectId: string | undefined, issuerDid: string, expirationHours?: number): Promise<IssueSDJWTVCResult>;
42
+ }
43
+ //# sourceMappingURL=api-vc-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api-vc-manager.d.ts","sourceRoot":"","sources":["../../src/vc/api-vc-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,mBAAmB,EACnB,kBAAkB,EAClB,mBAAmB,EAEpB,MAAM,UAAU,CAAA;AACjB,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAI/C;;;GAGG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,UAAU,CAAY;IAE9B;;;;OAIG;gBACS,UAAU,CAAC,EAAE,UAAU;IAInC;;OAEG;IACG,YAAY,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,kBAAkB,CAAC;IAgE7E;;OAEG;IACG,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC;IA6CrE;;OAEG;IACG,4BAA4B,CAChC,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EAAE,EACrB,SAAS,EAAE,MAAM,EACjB,eAAe,SAAK,GACnB,OAAO,CAAC,kBAAkB,CAAC;IAkB9B;;OAEG;IACG,yBAAyB,CAC7B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,OAAO,EAAE,MAAM,EAAE,EACjB,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,eAAe,SAAK,GACnB,OAAO,CAAC,kBAAkB,CAAC;IAkB9B;;OAEG;IACG,wBAAwB,CAC5B,QAAQ,EAAE,MAAM,EAChB,eAAe,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC,EAC3D,SAAS,EAAE,MAAM,EACjB,SAAS,EAAE,MAAM,EACjB,eAAe,SAAK,GACnB,OAAO,CAAC,kBAAkB,CAAC;IAiB9B;;OAEG;IACG,oBAAoB,CACxB,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,SAAS,GAAG,QAAQ,EAC3B,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,SAAS,EAAE,MAAM,EACjB,eAAe,SAAI,GAClB,OAAO,CAAC,kBAAkB,CAAC;CAiB/B"}
@@ -0,0 +1,55 @@
1
+ import { VCTemplate } from '../types';
2
+ import { KeyManager } from '../did/key-manager';
3
+ import { AgentManager } from '../did/agent';
4
+ import { UserIdentityManager } from '../identity/user-identity-manager';
5
+ export declare class VCManager {
6
+ private keyManager;
7
+ private templates;
8
+ private agentManager;
9
+ private userIdentityManager;
10
+ constructor(keyManager?: KeyManager, agentManager?: AgentManager, userIdentityManager?: UserIdentityManager);
11
+ /**
12
+ * Get fields that should be selectively disclosable based on VC type
13
+ */
14
+ private getSelectivelyDisclosableFields;
15
+ /**
16
+ * Issue a Verifiable Credential as SD-JWT VC
17
+ * Enhanced to support User/Agent DID separation
18
+ */
19
+ issue(template: string, claims: any, options: {
20
+ issuerDid?: string;
21
+ subjectDid?: string;
22
+ agentId?: string;
23
+ expiresIn?: string;
24
+ }): Promise<string>;
25
+ /**
26
+ * Get subject's public key for cnf claim
27
+ */
28
+ private getSubjectPublicKey;
29
+ /**
30
+ * Issue using existing Issuer API (OID4VCI)
31
+ */
32
+ issueViaAPI(credentialType: string, claims: any, options: {
33
+ issuerDid: string;
34
+ subjectDid: string;
35
+ }): Promise<string>;
36
+ /**
37
+ * Verify a SD-JWT VC
38
+ */
39
+ verify(sdjwtVc: string, options?: {
40
+ expectedIssuer?: string;
41
+ expectedSubject?: string;
42
+ requiredClaims?: string[];
43
+ }): Promise<any>;
44
+ /**
45
+ * Revoke a Verifiable Credential
46
+ */
47
+ revoke(_vcId: string, _issuerDid: string): Promise<void>;
48
+ /**
49
+ * Register a custom VC template
50
+ */
51
+ registerTemplate(template: VCTemplate): void;
52
+ private registerDefaultTemplates;
53
+ private calculateExpirationDate;
54
+ }
55
+ //# sourceMappingURL=vc-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vc-manager.d.ts","sourceRoot":"","sources":["../../src/vc/vc-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgD,UAAU,EAAE,MAAM,UAAU,CAAA;AAEnF,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAE/C,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAC3C,OAAO,EAAE,mBAAmB,EAAE,MAAM,mCAAmC,CAAA;AAGvE,qBAAa,SAAS;IACpB,OAAO,CAAC,UAAU,CAAY;IAC9B,OAAO,CAAC,SAAS,CAAqC;IACtD,OAAO,CAAC,YAAY,CAAc;IAClC,OAAO,CAAC,mBAAmB,CAAqB;gBAG9C,UAAU,CAAC,EAAE,UAAU,EACvB,YAAY,CAAC,EAAE,YAAY,EAC3B,mBAAmB,CAAC,EAAE,mBAAmB;IAiB3C;;OAEG;IACH,OAAO,CAAC,+BAA+B;IAavC;;;OAGG;IACG,KAAK,CACT,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,GAAG,EACX,OAAO,EAAE;QACP,SAAS,CAAC,EAAE,MAAM,CAAA;QAClB,UAAU,CAAC,EAAE,MAAM,CAAA;QACnB,OAAO,CAAC,EAAE,MAAM,CAAA;QAChB,SAAS,CAAC,EAAE,MAAM,CAAA;KACnB,GACA,OAAO,CAAC,MAAM,CAAC;IAqGlB;;OAEG;YACW,mBAAmB;IAgCjC;;OAEG;IACG,WAAW,CACf,cAAc,EAAE,MAAM,EACtB,MAAM,EAAE,GAAG,EACX,OAAO,EAAE;QACP,SAAS,EAAE,MAAM,CAAA;QACjB,UAAU,EAAE,MAAM,CAAA;KACnB,GACA,OAAO,CAAC,MAAM,CAAC;IAoClB;;OAEG;IACG,MAAM,CACV,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE;QACR,cAAc,CAAC,EAAE,MAAM,CAAA;QACvB,eAAe,CAAC,EAAE,MAAM,CAAA;QACxB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAA;KAC1B,GACA,OAAO,CAAC,GAAG,CAAC;IAgDf;;OAEG;IACG,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAK9D;;OAEG;IACH,gBAAgB,CAAC,QAAQ,EAAE,UAAU,GAAG,IAAI;IAI5C,OAAO,CAAC,wBAAwB;IA4BhC,OAAO,CAAC,uBAAuB;CA2BhC"}
@@ -0,0 +1,89 @@
1
+ /**
2
+ * Single source of truth for Key Binding JWT (KB-JWT) issuance shared across
3
+ * the AIdentity stack. Four production code paths build KB-JWTs and they
4
+ * MUST stay byte-for-byte equivalent so a presentation built on one side is
5
+ * accepted by the verifier on the other:
6
+ *
7
+ * - SDK clients via `VPManager.create()` (this package)
8
+ * - API service via `packages/api/src/vp/vp-creation.service.ts`
9
+ * - Remote MCP via `packages/remote-mcp/src/services/vp-creation.service.ts`
10
+ * - agentd (`@vess-id/vess`) via `VPBuilder.buildVP()`
11
+ * (`packages/agentd/src/wallet/vp-builder.ts`)
12
+ *
13
+ * Historically each path had its own copy of this logic. PR #391 (the
14
+ * commit that made `exp` REQUIRED on the verifier side) updated only two of
15
+ * the three issuer paths known at the time; the SDK was missed and every
16
+ * SDK-built VP started failing at verification time. The follow-up
17
+ * consolidation (commit 02b169aa) brought the SDK in line, but agentd —
18
+ * which had its own KB-JWT literal in `wallet/vp-builder.ts` — was not
19
+ * recognized as a fourth issuer. Staging then rejected every VP from
20
+ * `@vess-id/vess` agentd alpha builds with `KB-JWT missing exp` until the
21
+ * agentd hotfix (this commit's cohort) wired its VPBuilder through
22
+ * `buildKbJwtPayload()`. This module exists so that a future verifier
23
+ * change cannot drift from the issuer side: any update lands in one place
24
+ * and all four paths inherit it.
25
+ */
26
+ /**
27
+ * Default KB-JWT lifetime in seconds. Mirrors the cap enforced by the API's
28
+ * `KeyBindingVerifierService.MAX_KB_JWT_LIFETIME_SECONDS` (also 300).
29
+ *
30
+ * The KB-JWT `exp` is the smaller of:
31
+ * - `iat + KB_JWT_DEFAULT_LIFETIME_SECONDS`
32
+ * - the parent VC's `exp` (so the bearer's freshness window cannot outlive
33
+ * the underlying credential's validity, which is itself bounded by
34
+ * `grant.expiresAt` at issuance time).
35
+ */
36
+ export declare const KB_JWT_DEFAULT_LIFETIME_SECONDS = 300;
37
+ export interface KbJwtPayload {
38
+ iss: string;
39
+ aud: string;
40
+ nonce: string;
41
+ iat: number;
42
+ exp: number;
43
+ }
44
+ export interface BuildKbJwtPayloadArgs {
45
+ /** Holder DID — becomes the KB-JWT `iss` claim. */
46
+ holderDid: string;
47
+ /** Verifier audience (URL or hostname). Will be normalized via {@link normalizeDomain}. */
48
+ audience: string;
49
+ /** Verifier-supplied nonce / challenge. */
50
+ nonce: string;
51
+ /** The parent SD-JWT VC string. Its `exp` (if any) caps the KB-JWT lifetime. */
52
+ vcCredential: string;
53
+ }
54
+ export interface BuildKbJwtPayloadDeps {
55
+ /** Returns the current time in milliseconds. Defaults to `Date.now`. */
56
+ now?: () => number;
57
+ }
58
+ /**
59
+ * Build a Key Binding JWT payload for an SD-JWT VC presentation.
60
+ *
61
+ * Throws when the parent VC is already expired (`vc.exp <= now`). The error
62
+ * message intentionally contains the substring `"VC has expired"` so that
63
+ * downstream catchers (notably remote-mcp's `isCredentialInvalidError`) can
64
+ * detect a stale-credential condition and trigger a re-approval flow rather
65
+ * than surface an opaque issuance failure to the user.
66
+ */
67
+ export declare function buildKbJwtPayload(args: BuildKbJwtPayloadArgs, deps?: BuildKbJwtPayloadDeps): KbJwtPayload;
68
+ /**
69
+ * Best-effort read of the VC's `exp` claim from the SD-JWT outer payload.
70
+ * Returns undefined when the VC is malformed, missing exp, or the field is
71
+ * not a number — callers fall back to {@link KB_JWT_DEFAULT_LIFETIME_SECONDS}
72
+ * in that case so issuance does not break for VCs without an explicit expiry.
73
+ */
74
+ export declare function readVcExpSeconds(sdJwtVc: string): number | undefined;
75
+ /**
76
+ * Normalize a domain string for consistent use as a JWT `aud` claim.
77
+ *
78
+ * The API verifier compares the KB-JWT `aud` against the expected domain by
79
+ * exact string match, so issuer and verifier must agree on the canonical
80
+ * form. We delegate to the URL parser, which strips paths and lowercases
81
+ * the host, then return the resulting `origin`.
82
+ *
83
+ * Inputs without a scheme are assumed to be hostnames; `localhost` (with or
84
+ * without a port) defaults to `http://`, everything else to `https://`. If
85
+ * URL parsing fails, the input is returned unchanged so a caller can still
86
+ * detect the mismatch downstream rather than silently swallowing a typo.
87
+ */
88
+ export declare function normalizeDomain(domain: string): string;
89
+ //# sourceMappingURL=kb-jwt-builder.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"kb-jwt-builder.d.ts","sourceRoot":"","sources":["../../src/vp/kb-jwt-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH;;;;;;;;;GASG;AACH,eAAO,MAAM,+BAA+B,MAAM,CAAA;AAElD,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,MAAM,CAAA;IACb,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;CACZ;AAED,MAAM,WAAW,qBAAqB;IACpC,mDAAmD;IACnD,SAAS,EAAE,MAAM,CAAA;IACjB,2FAA2F;IAC3F,QAAQ,EAAE,MAAM,CAAA;IAChB,2CAA2C;IAC3C,KAAK,EAAE,MAAM,CAAA;IACb,gFAAgF;IAChF,YAAY,EAAE,MAAM,CAAA;CACrB;AAED,MAAM,WAAW,qBAAqB;IACpC,wEAAwE;IACxE,GAAG,CAAC,EAAE,MAAM,MAAM,CAAA;CACnB;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,IAAI,EAAE,qBAAqB,EAC3B,IAAI,GAAE,qBAA0B,GAC/B,YAAY,CAqBd;AAED;;;;;GAKG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAUpE;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAgBtD"}