@kya-os/mcp 1.16.2 → 1.17.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 (469) hide show
  1. package/AUDITABILITY.md +129 -8
  2. package/CHANGELOG.md +579 -0
  3. package/CONFORMANCE.md +4 -4
  4. package/README.md +65 -26
  5. package/SPEC.md +85 -17
  6. package/dist/audit/adapters/legacy-audit-log.d.ts +0 -1
  7. package/dist/audit/adapters/mcp.d.ts +0 -1
  8. package/dist/audit/adapters/mcp.js +35 -20
  9. package/dist/audit/adapters/mcp.js.map +1 -1
  10. package/dist/audit/adapters/references.d.ts +9 -0
  11. package/dist/audit/adapters/references.js +22 -0
  12. package/dist/audit/adapters/references.js.map +1 -0
  13. package/dist/audit/assurance.d.ts +0 -1
  14. package/dist/audit/checkpoint-coordinator.d.ts +0 -1
  15. package/dist/audit/checkpoint.d.ts +17 -1
  16. package/dist/audit/checkpoint.js +76 -21
  17. package/dist/audit/checkpoint.js.map +1 -1
  18. package/dist/audit/cli.d.ts +0 -1
  19. package/dist/audit/crypto.d.ts +0 -1
  20. package/dist/audit/crypto.js +12 -3
  21. package/dist/audit/crypto.js.map +1 -1
  22. package/dist/audit/errors.d.ts +0 -1
  23. package/dist/audit/evidence.d.ts +0 -1
  24. package/dist/audit/index.d.ts +0 -1
  25. package/dist/audit/integrity.d.ts +0 -1
  26. package/dist/audit/merkle.d.ts +0 -1
  27. package/dist/audit/mirror-service.d.ts +0 -1
  28. package/dist/audit/projection.d.ts +1 -1
  29. package/dist/audit/projection.js +23 -2
  30. package/dist/audit/projection.js.map +1 -1
  31. package/dist/audit/providers/anchor.d.ts +0 -1
  32. package/dist/audit/providers/evidence.d.ts +0 -1
  33. package/dist/audit/providers/journal.d.ts +0 -1
  34. package/dist/audit/providers/memory-journal.d.ts +0 -1
  35. package/dist/audit/providers/observer.d.ts +0 -1
  36. package/dist/audit/providers/outbox.d.ts +35 -6
  37. package/dist/audit/providers/outbox.js +46 -8
  38. package/dist/audit/providers/outbox.js.map +1 -1
  39. package/dist/audit/providers/recorder-client.d.ts +0 -1
  40. package/dist/audit/providers/source-state.d.ts +24 -2
  41. package/dist/audit/providers/source-state.js +65 -44
  42. package/dist/audit/providers/source-state.js.map +1 -1
  43. package/dist/audit/read-contract.d.ts +0 -1
  44. package/dist/audit/read-service.d.ts +2 -3
  45. package/dist/audit/read-service.js +17 -12
  46. package/dist/audit/read-service.js.map +1 -1
  47. package/dist/audit/recorder-service.d.ts +33 -5
  48. package/dist/audit/recorder-service.js +116 -20
  49. package/dist/audit/recorder-service.js.map +1 -1
  50. package/dist/audit/reference-recorder.d.ts +0 -1
  51. package/dist/audit/replay-bundle.d.ts +0 -1
  52. package/dist/audit/replay-bundle.js +143 -36
  53. package/dist/audit/replay-bundle.js.map +1 -1
  54. package/dist/audit/schemas.d.ts +0 -1
  55. package/dist/audit/service.d.ts +6 -3
  56. package/dist/audit/service.js +55 -24
  57. package/dist/audit/service.js.map +1 -1
  58. package/dist/audit/testing/index.d.ts +0 -1
  59. package/dist/audit/testing/provider-contracts.d.ts +1 -2
  60. package/dist/audit/testing/provider-contracts.js +32 -2
  61. package/dist/audit/testing/provider-contracts.js.map +1 -1
  62. package/dist/audit/types.d.ts +0 -1
  63. package/dist/audit/verifier.d.ts +57 -5
  64. package/dist/audit/verifier.js +240 -49
  65. package/dist/audit/verifier.js.map +1 -1
  66. package/dist/auth/handshake.d.ts +12 -1
  67. package/dist/auth/handshake.js +44 -11
  68. package/dist/auth/handshake.js.map +1 -1
  69. package/dist/auth/index.d.ts +0 -1
  70. package/dist/auth/types.d.ts +0 -1
  71. package/dist/authz/accountability.d.ts +0 -1
  72. package/dist/authz/adapter.d.ts +0 -1
  73. package/dist/authz/examples/inmemory-oidc.d.ts +0 -1
  74. package/dist/authz/index.d.ts +0 -1
  75. package/dist/authz/oidc/authorize.d.ts +0 -1
  76. package/dist/authz/oidc/metadata.d.ts +0 -1
  77. package/dist/authz/oidc/oidc-adapter.d.ts +0 -1
  78. package/dist/authz/oidc/oidc-adapter.js +51 -3
  79. package/dist/authz/oidc/oidc-adapter.js.map +1 -1
  80. package/dist/authz/oidc/pending-flow-store.d.ts +6 -1
  81. package/dist/authz/oidc/pending-flow-store.js +22 -2
  82. package/dist/authz/oidc/pending-flow-store.js.map +1 -1
  83. package/dist/authz/oidc/pkce.d.ts +0 -1
  84. package/dist/authz/registry.d.ts +0 -1
  85. package/dist/authz/requirement.d.ts +0 -1
  86. package/dist/card/build.d.ts +0 -1
  87. package/dist/card/builder.d.ts +0 -1
  88. package/dist/card/cimd.d.ts +19 -5
  89. package/dist/card/cimd.js +52 -7
  90. package/dist/card/cimd.js.map +1 -1
  91. package/dist/card/delegation.d.ts +0 -1
  92. package/dist/card/delegation.js +25 -15
  93. package/dist/card/delegation.js.map +1 -1
  94. package/dist/card/emit.d.ts +0 -1
  95. package/dist/card/index.d.ts +0 -1
  96. package/dist/card/middleware.d.ts +0 -1
  97. package/dist/card/proof/build.d.ts +0 -1
  98. package/dist/card/proof/canonical.d.ts +0 -1
  99. package/dist/card/proof/canonical.js +6 -1
  100. package/dist/card/proof/canonical.js.map +1 -1
  101. package/dist/card/proof/http-sig.d.ts +0 -1
  102. package/dist/card/proof/index.d.ts +0 -1
  103. package/dist/card/proof/nonce-cache.d.ts +15 -14
  104. package/dist/card/proof/nonce-cache.js +22 -20
  105. package/dist/card/proof/nonce-cache.js.map +1 -1
  106. package/dist/card/proof/signer.d.ts +0 -1
  107. package/dist/card/proof/types.d.ts +10 -4
  108. package/dist/card/proof/types.js +2 -2
  109. package/dist/card/proof/verify.d.ts +0 -1
  110. package/dist/card/proof/verify.js +17 -3
  111. package/dist/card/proof/verify.js.map +1 -1
  112. package/dist/card/resolve.d.ts +0 -1
  113. package/dist/card/resolve.js +13 -8
  114. package/dist/card/resolve.js.map +1 -1
  115. package/dist/card/revocation.d.ts +0 -1
  116. package/dist/card/revocation.js +18 -6
  117. package/dist/card/revocation.js.map +1 -1
  118. package/dist/card/schema.d.ts +7 -6
  119. package/dist/card/schema.js +7 -3
  120. package/dist/card/schema.js.map +1 -1
  121. package/dist/card/verify.d.ts +0 -1
  122. package/dist/delegation/audience-validator.d.ts +0 -1
  123. package/dist/delegation/bitstring.d.ts +0 -1
  124. package/dist/delegation/cascading-revocation.d.ts +1 -2
  125. package/dist/delegation/cascading-revocation.js +34 -36
  126. package/dist/delegation/cascading-revocation.js.map +1 -1
  127. package/dist/delegation/chain-enforcement.d.ts +26 -5
  128. package/dist/delegation/chain-enforcement.js +110 -34
  129. package/dist/delegation/chain-enforcement.js.map +1 -1
  130. package/dist/delegation/delegation-graph.d.ts +30 -1
  131. package/dist/delegation/delegation-graph.js +33 -0
  132. package/dist/delegation/delegation-graph.js.map +1 -1
  133. package/dist/delegation/delegation-registration.d.ts +22 -0
  134. package/dist/delegation/delegation-registration.js +51 -0
  135. package/dist/delegation/delegation-registration.js.map +1 -0
  136. package/dist/delegation/delegation-status-entry.d.ts +22 -0
  137. package/dist/delegation/delegation-status-entry.js +42 -0
  138. package/dist/delegation/delegation-status-entry.js.map +1 -0
  139. package/dist/delegation/did-key-resolver.d.ts +0 -1
  140. package/dist/delegation/did-key-resolver.js +15 -4
  141. package/dist/delegation/did-key-resolver.js.map +1 -1
  142. package/dist/delegation/did-linkage.d.ts +0 -1
  143. package/dist/delegation/did-resolver-registry.d.ts +0 -1
  144. package/dist/delegation/did-web-resolver.d.ts +0 -1
  145. package/dist/delegation/did-web-resolver.js +40 -5
  146. package/dist/delegation/did-web-resolver.js.map +1 -1
  147. package/dist/delegation/holder-binding.d.ts +11 -11
  148. package/dist/delegation/holder-binding.js +8 -17
  149. package/dist/delegation/holder-binding.js.map +1 -1
  150. package/dist/delegation/index.d.ts +0 -1
  151. package/dist/delegation/outbound-headers.d.ts +0 -1
  152. package/dist/delegation/outbound-proof.d.ts +0 -1
  153. package/dist/delegation/scope-matcher.d.ts +25 -2
  154. package/dist/delegation/scope-matcher.js +75 -5
  155. package/dist/delegation/scope-matcher.js.map +1 -1
  156. package/dist/delegation/status-cache.d.ts +0 -1
  157. package/dist/delegation/statuslist-manager.d.ts +18 -2
  158. package/dist/delegation/statuslist-manager.js +40 -14
  159. package/dist/delegation/statuslist-manager.js.map +1 -1
  160. package/dist/delegation/storage/memory-graph-storage.d.ts +9 -3
  161. package/dist/delegation/storage/memory-graph-storage.js +28 -14
  162. package/dist/delegation/storage/memory-graph-storage.js.map +1 -1
  163. package/dist/delegation/storage/memory-statuslist-storage.d.ts +0 -1
  164. package/dist/delegation/utils.d.ts +5 -5
  165. package/dist/delegation/utils.js +4 -4
  166. package/dist/delegation/utils.js.map +1 -1
  167. package/dist/delegation/vc-issuer.d.ts +0 -1
  168. package/dist/delegation/vc-jwt-verify.d.ts +7 -2
  169. package/dist/delegation/vc-jwt-verify.js +55 -3
  170. package/dist/delegation/vc-jwt-verify.js.map +1 -1
  171. package/dist/delegation/vc-verification-checks.d.ts +0 -1
  172. package/dist/delegation/vc-verification-checks.js +9 -5
  173. package/dist/delegation/vc-verification-checks.js.map +1 -1
  174. package/dist/delegation/vc-verifier.d.ts +0 -1
  175. package/dist/delegation/vc-verifier.types.d.ts +0 -1
  176. package/dist/delegation/verification-method-key.d.ts +0 -1
  177. package/dist/delegation/verification-method-key.js +4 -3
  178. package/dist/delegation/verification-method-key.js.map +1 -1
  179. package/dist/errors.d.ts +0 -1
  180. package/dist/extension/declaration.d.ts +0 -1
  181. package/dist/extension/gate.d.ts +0 -1
  182. package/dist/extension/index.d.ts +0 -1
  183. package/dist/extension/settings.d.ts +0 -1
  184. package/dist/index.d.ts +2 -3
  185. package/dist/index.js +1 -1
  186. package/dist/index.js.map +1 -1
  187. package/dist/integrations/cheqd/dlr.d.ts +0 -1
  188. package/dist/integrations/cheqd/dlr.js +6 -1
  189. package/dist/integrations/cheqd/dlr.js.map +1 -1
  190. package/dist/integrations/cheqd/index.d.ts +0 -1
  191. package/dist/integrations/cheqd/linkage.d.ts +0 -1
  192. package/dist/integrations/cheqd/registrar.d.ts +0 -1
  193. package/dist/integrations/cheqd/resolver.d.ts +0 -1
  194. package/dist/integrations/cheqd/statuslist-resolver.d.ts +0 -1
  195. package/dist/logging/index.d.ts +0 -1
  196. package/dist/logging/logger.d.ts +0 -1
  197. package/dist/middleware/index.d.ts +0 -1
  198. package/dist/middleware/kya-os-transport.d.ts +5 -3
  199. package/dist/middleware/kya-os-transport.js +58 -24
  200. package/dist/middleware/kya-os-transport.js.map +1 -1
  201. package/dist/middleware/with-kya-os-server.d.ts +24 -4
  202. package/dist/middleware/with-kya-os-server.js +7 -0
  203. package/dist/middleware/with-kya-os-server.js.map +1 -1
  204. package/dist/middleware/with-kya-os.config-types.d.ts +22 -4
  205. package/dist/middleware/with-kya-os.d.ts +0 -1
  206. package/dist/middleware/with-kya-os.delegation-gate.d.ts +2 -1
  207. package/dist/middleware/with-kya-os.delegation-gate.js +37 -9
  208. package/dist/middleware/with-kya-os.delegation-gate.js.map +1 -1
  209. package/dist/middleware/with-kya-os.delegation-verify.d.ts +1 -1
  210. package/dist/middleware/with-kya-os.delegation-verify.js +45 -9
  211. package/dist/middleware/with-kya-os.delegation-verify.js.map +1 -1
  212. package/dist/middleware/with-kya-os.deps.d.ts +0 -1
  213. package/dist/middleware/with-kya-os.grants.d.ts +13 -6
  214. package/dist/middleware/with-kya-os.grants.js +56 -18
  215. package/dist/middleware/with-kya-os.grants.js.map +1 -1
  216. package/dist/middleware/with-kya-os.helpers.d.ts +0 -1
  217. package/dist/middleware/with-kya-os.js +14 -4
  218. package/dist/middleware/with-kya-os.js.map +1 -1
  219. package/dist/middleware/with-kya-os.policy-gate.d.ts +0 -1
  220. package/dist/middleware/with-kya-os.policy-gate.js +18 -9
  221. package/dist/middleware/with-kya-os.policy-gate.js.map +1 -1
  222. package/dist/middleware/with-kya-os.protocol.d.ts +0 -1
  223. package/dist/middleware/with-kya-os.session.d.ts +28 -1
  224. package/dist/middleware/with-kya-os.session.js +146 -7
  225. package/dist/middleware/with-kya-os.session.js.map +1 -1
  226. package/dist/middleware/with-kya-os.types.d.ts +28 -5
  227. package/dist/policy/approval.d.ts +13 -2
  228. package/dist/policy/approval.js +15 -4
  229. package/dist/policy/approval.js.map +1 -1
  230. package/dist/policy/classifier.d.ts +0 -1
  231. package/dist/policy/default-engine.d.ts +5 -2
  232. package/dist/policy/default-engine.js +10 -2
  233. package/dist/policy/default-engine.js.map +1 -1
  234. package/dist/policy/engine.d.ts +0 -1
  235. package/dist/policy/index.d.ts +0 -1
  236. package/dist/policy/projection.d.ts +0 -1
  237. package/dist/policy/types.d.ts +0 -1
  238. package/dist/proof/covered-request.d.ts +46 -0
  239. package/dist/proof/covered-request.js +107 -0
  240. package/dist/proof/covered-request.js.map +1 -0
  241. package/dist/proof/errors.d.ts +3 -1
  242. package/dist/proof/errors.js +5 -0
  243. package/dist/proof/errors.js.map +1 -1
  244. package/dist/proof/generator.d.ts +51 -1
  245. package/dist/proof/generator.js +71 -13
  246. package/dist/proof/generator.js.map +1 -1
  247. package/dist/proof/index.d.ts +1 -2
  248. package/dist/proof/index.js.map +1 -1
  249. package/dist/proof/verifier.d.ts +50 -12
  250. package/dist/proof/verifier.js +164 -84
  251. package/dist/proof/verifier.js.map +1 -1
  252. package/dist/providers/audit-log.d.ts +0 -1
  253. package/dist/providers/base.d.ts +19 -1
  254. package/dist/providers/base.js.map +1 -1
  255. package/dist/providers/grant-store.d.ts +8 -2
  256. package/dist/providers/grant-store.js +5 -5
  257. package/dist/providers/grant-store.js.map +1 -1
  258. package/dist/providers/index.d.ts +0 -1
  259. package/dist/providers/memory.d.ts +19 -1
  260. package/dist/providers/memory.js +53 -7
  261. package/dist/providers/memory.js.map +1 -1
  262. package/dist/providers/node-crypto.d.ts +4 -1
  263. package/dist/providers/node-crypto.js +32 -9
  264. package/dist/providers/node-crypto.js.map +1 -1
  265. package/dist/providers/nonce-admission.d.ts +31 -0
  266. package/dist/providers/nonce-admission.js +47 -0
  267. package/dist/providers/nonce-admission.js.map +1 -0
  268. package/dist/providers/nonce-retention.d.ts +8 -0
  269. package/dist/providers/nonce-retention.js +15 -0
  270. package/dist/providers/nonce-retention.js.map +1 -0
  271. package/dist/providers/runtime-fetch.d.ts +0 -1
  272. package/dist/providers/system-clock.d.ts +0 -1
  273. package/dist/providers/web-crypto.d.ts +0 -1
  274. package/dist/providers/web-crypto.js +7 -1
  275. package/dist/providers/web-crypto.js.map +1 -1
  276. package/dist/session/index.d.ts +0 -1
  277. package/dist/session/manager.d.ts +13 -1
  278. package/dist/session/manager.js +25 -9
  279. package/dist/session/manager.js.map +1 -1
  280. package/dist/session/session-store.d.ts +0 -1
  281. package/dist/types/protocol.d.ts +11 -3
  282. package/dist/types/protocol.js +21 -14
  283. package/dist/types/protocol.js.map +1 -1
  284. package/dist/utils/base58.d.ts +16 -3
  285. package/dist/utils/base58.js +34 -12
  286. package/dist/utils/base58.js.map +1 -1
  287. package/dist/utils/base64.d.ts +0 -1
  288. package/dist/utils/canonical-json.d.ts +7 -1
  289. package/dist/utils/canonical-json.js +130 -60
  290. package/dist/utils/canonical-json.js.map +1 -1
  291. package/dist/utils/crypto-service.d.ts +0 -1
  292. package/dist/utils/crypto-service.js +22 -2
  293. package/dist/utils/crypto-service.js.map +1 -1
  294. package/dist/utils/did-helpers.d.ts +0 -1
  295. package/dist/utils/ed25519-constants.d.ts +0 -1
  296. package/dist/utils/ed25519-public-key.d.ts +27 -0
  297. package/dist/utils/ed25519-public-key.js +86 -0
  298. package/dist/utils/ed25519-public-key.js.map +1 -0
  299. package/dist/utils/guards.d.ts +0 -1
  300. package/dist/utils/index.d.ts +0 -1
  301. package/dist/utils/ip-classifier.d.ts +0 -1
  302. package/dist/utils/safe-fetch-transports.d.ts +0 -1
  303. package/dist/utils/safe-fetch-types.d.ts +0 -1
  304. package/dist/utils/safe-fetch.d.ts +0 -1
  305. package/dist/utils/statuslist-bits.d.ts +0 -1
  306. package/dist/utils/statuslist-purpose.d.ts +0 -1
  307. package/dist/utils/ttl-cache.d.ts +0 -1
  308. package/dist/utils/url.d.ts +0 -1
  309. package/package.json +9 -6
  310. package/schemas/card-delegation-credential.json +4 -1
  311. package/dist/audit/adapters/legacy-audit-log.d.ts.map +0 -1
  312. package/dist/audit/adapters/mcp.d.ts.map +0 -1
  313. package/dist/audit/assurance.d.ts.map +0 -1
  314. package/dist/audit/checkpoint-coordinator.d.ts.map +0 -1
  315. package/dist/audit/checkpoint.d.ts.map +0 -1
  316. package/dist/audit/cli.d.ts.map +0 -1
  317. package/dist/audit/crypto.d.ts.map +0 -1
  318. package/dist/audit/errors.d.ts.map +0 -1
  319. package/dist/audit/evidence.d.ts.map +0 -1
  320. package/dist/audit/index.d.ts.map +0 -1
  321. package/dist/audit/integrity.d.ts.map +0 -1
  322. package/dist/audit/merkle.d.ts.map +0 -1
  323. package/dist/audit/mirror-service.d.ts.map +0 -1
  324. package/dist/audit/projection.d.ts.map +0 -1
  325. package/dist/audit/providers/anchor.d.ts.map +0 -1
  326. package/dist/audit/providers/evidence.d.ts.map +0 -1
  327. package/dist/audit/providers/journal.d.ts.map +0 -1
  328. package/dist/audit/providers/memory-journal.d.ts.map +0 -1
  329. package/dist/audit/providers/observer.d.ts.map +0 -1
  330. package/dist/audit/providers/outbox.d.ts.map +0 -1
  331. package/dist/audit/providers/recorder-client.d.ts.map +0 -1
  332. package/dist/audit/providers/source-state.d.ts.map +0 -1
  333. package/dist/audit/read-contract.d.ts.map +0 -1
  334. package/dist/audit/read-service.d.ts.map +0 -1
  335. package/dist/audit/recorder-service.d.ts.map +0 -1
  336. package/dist/audit/reference-recorder.d.ts.map +0 -1
  337. package/dist/audit/replay-bundle.d.ts.map +0 -1
  338. package/dist/audit/schemas.d.ts.map +0 -1
  339. package/dist/audit/service.d.ts.map +0 -1
  340. package/dist/audit/testing/index.d.ts.map +0 -1
  341. package/dist/audit/testing/provider-contracts.d.ts.map +0 -1
  342. package/dist/audit/types.d.ts.map +0 -1
  343. package/dist/audit/verifier.d.ts.map +0 -1
  344. package/dist/auth/handshake.d.ts.map +0 -1
  345. package/dist/auth/index.d.ts.map +0 -1
  346. package/dist/auth/types.d.ts.map +0 -1
  347. package/dist/authz/accountability.d.ts.map +0 -1
  348. package/dist/authz/adapter.d.ts.map +0 -1
  349. package/dist/authz/examples/inmemory-oidc.d.ts.map +0 -1
  350. package/dist/authz/index.d.ts.map +0 -1
  351. package/dist/authz/oidc/authorize.d.ts.map +0 -1
  352. package/dist/authz/oidc/metadata.d.ts.map +0 -1
  353. package/dist/authz/oidc/oidc-adapter.d.ts.map +0 -1
  354. package/dist/authz/oidc/pending-flow-store.d.ts.map +0 -1
  355. package/dist/authz/oidc/pkce.d.ts.map +0 -1
  356. package/dist/authz/registry.d.ts.map +0 -1
  357. package/dist/authz/requirement.d.ts.map +0 -1
  358. package/dist/card/build.d.ts.map +0 -1
  359. package/dist/card/builder.d.ts.map +0 -1
  360. package/dist/card/cimd.d.ts.map +0 -1
  361. package/dist/card/delegation.d.ts.map +0 -1
  362. package/dist/card/emit.d.ts.map +0 -1
  363. package/dist/card/index.d.ts.map +0 -1
  364. package/dist/card/middleware.d.ts.map +0 -1
  365. package/dist/card/proof/build.d.ts.map +0 -1
  366. package/dist/card/proof/canonical.d.ts.map +0 -1
  367. package/dist/card/proof/http-sig.d.ts.map +0 -1
  368. package/dist/card/proof/index.d.ts.map +0 -1
  369. package/dist/card/proof/nonce-cache.d.ts.map +0 -1
  370. package/dist/card/proof/signer.d.ts.map +0 -1
  371. package/dist/card/proof/types.d.ts.map +0 -1
  372. package/dist/card/proof/verify.d.ts.map +0 -1
  373. package/dist/card/resolve.d.ts.map +0 -1
  374. package/dist/card/revocation.d.ts.map +0 -1
  375. package/dist/card/schema.d.ts.map +0 -1
  376. package/dist/card/verify.d.ts.map +0 -1
  377. package/dist/delegation/audience-validator.d.ts.map +0 -1
  378. package/dist/delegation/bitstring.d.ts.map +0 -1
  379. package/dist/delegation/cascading-revocation.d.ts.map +0 -1
  380. package/dist/delegation/chain-enforcement.d.ts.map +0 -1
  381. package/dist/delegation/delegation-graph.d.ts.map +0 -1
  382. package/dist/delegation/did-key-resolver.d.ts.map +0 -1
  383. package/dist/delegation/did-linkage.d.ts.map +0 -1
  384. package/dist/delegation/did-resolver-registry.d.ts.map +0 -1
  385. package/dist/delegation/did-web-resolver.d.ts.map +0 -1
  386. package/dist/delegation/holder-binding.d.ts.map +0 -1
  387. package/dist/delegation/index.d.ts.map +0 -1
  388. package/dist/delegation/outbound-headers.d.ts.map +0 -1
  389. package/dist/delegation/outbound-proof.d.ts.map +0 -1
  390. package/dist/delegation/scope-matcher.d.ts.map +0 -1
  391. package/dist/delegation/status-cache.d.ts.map +0 -1
  392. package/dist/delegation/statuslist-manager.d.ts.map +0 -1
  393. package/dist/delegation/storage/memory-graph-storage.d.ts.map +0 -1
  394. package/dist/delegation/storage/memory-statuslist-storage.d.ts.map +0 -1
  395. package/dist/delegation/utils.d.ts.map +0 -1
  396. package/dist/delegation/vc-issuer.d.ts.map +0 -1
  397. package/dist/delegation/vc-jwt-verify.d.ts.map +0 -1
  398. package/dist/delegation/vc-verification-checks.d.ts.map +0 -1
  399. package/dist/delegation/vc-verifier.d.ts.map +0 -1
  400. package/dist/delegation/vc-verifier.types.d.ts.map +0 -1
  401. package/dist/delegation/verification-method-key.d.ts.map +0 -1
  402. package/dist/errors.d.ts.map +0 -1
  403. package/dist/extension/declaration.d.ts.map +0 -1
  404. package/dist/extension/gate.d.ts.map +0 -1
  405. package/dist/extension/index.d.ts.map +0 -1
  406. package/dist/extension/settings.d.ts.map +0 -1
  407. package/dist/index.d.ts.map +0 -1
  408. package/dist/integrations/cheqd/dlr.d.ts.map +0 -1
  409. package/dist/integrations/cheqd/index.d.ts.map +0 -1
  410. package/dist/integrations/cheqd/linkage.d.ts.map +0 -1
  411. package/dist/integrations/cheqd/registrar.d.ts.map +0 -1
  412. package/dist/integrations/cheqd/resolver.d.ts.map +0 -1
  413. package/dist/integrations/cheqd/statuslist-resolver.d.ts.map +0 -1
  414. package/dist/logging/index.d.ts.map +0 -1
  415. package/dist/logging/logger.d.ts.map +0 -1
  416. package/dist/middleware/index.d.ts.map +0 -1
  417. package/dist/middleware/kya-os-transport.d.ts.map +0 -1
  418. package/dist/middleware/with-kya-os-server.d.ts.map +0 -1
  419. package/dist/middleware/with-kya-os.config-types.d.ts.map +0 -1
  420. package/dist/middleware/with-kya-os.d.ts.map +0 -1
  421. package/dist/middleware/with-kya-os.delegation-gate.d.ts.map +0 -1
  422. package/dist/middleware/with-kya-os.delegation-verify.d.ts.map +0 -1
  423. package/dist/middleware/with-kya-os.deps.d.ts.map +0 -1
  424. package/dist/middleware/with-kya-os.grants.d.ts.map +0 -1
  425. package/dist/middleware/with-kya-os.helpers.d.ts.map +0 -1
  426. package/dist/middleware/with-kya-os.policy-gate.d.ts.map +0 -1
  427. package/dist/middleware/with-kya-os.protocol.d.ts.map +0 -1
  428. package/dist/middleware/with-kya-os.session.d.ts.map +0 -1
  429. package/dist/middleware/with-kya-os.types.d.ts.map +0 -1
  430. package/dist/policy/approval.d.ts.map +0 -1
  431. package/dist/policy/classifier.d.ts.map +0 -1
  432. package/dist/policy/default-engine.d.ts.map +0 -1
  433. package/dist/policy/engine.d.ts.map +0 -1
  434. package/dist/policy/index.d.ts.map +0 -1
  435. package/dist/policy/projection.d.ts.map +0 -1
  436. package/dist/policy/types.d.ts.map +0 -1
  437. package/dist/proof/errors.d.ts.map +0 -1
  438. package/dist/proof/generator.d.ts.map +0 -1
  439. package/dist/proof/index.d.ts.map +0 -1
  440. package/dist/proof/verifier.d.ts.map +0 -1
  441. package/dist/providers/audit-log.d.ts.map +0 -1
  442. package/dist/providers/base.d.ts.map +0 -1
  443. package/dist/providers/grant-store.d.ts.map +0 -1
  444. package/dist/providers/index.d.ts.map +0 -1
  445. package/dist/providers/memory.d.ts.map +0 -1
  446. package/dist/providers/node-crypto.d.ts.map +0 -1
  447. package/dist/providers/runtime-fetch.d.ts.map +0 -1
  448. package/dist/providers/system-clock.d.ts.map +0 -1
  449. package/dist/providers/web-crypto.d.ts.map +0 -1
  450. package/dist/session/index.d.ts.map +0 -1
  451. package/dist/session/manager.d.ts.map +0 -1
  452. package/dist/session/session-store.d.ts.map +0 -1
  453. package/dist/types/protocol.d.ts.map +0 -1
  454. package/dist/utils/base58.d.ts.map +0 -1
  455. package/dist/utils/base64.d.ts.map +0 -1
  456. package/dist/utils/canonical-json.d.ts.map +0 -1
  457. package/dist/utils/crypto-service.d.ts.map +0 -1
  458. package/dist/utils/did-helpers.d.ts.map +0 -1
  459. package/dist/utils/ed25519-constants.d.ts.map +0 -1
  460. package/dist/utils/guards.d.ts.map +0 -1
  461. package/dist/utils/index.d.ts.map +0 -1
  462. package/dist/utils/ip-classifier.d.ts.map +0 -1
  463. package/dist/utils/safe-fetch-transports.d.ts.map +0 -1
  464. package/dist/utils/safe-fetch-types.d.ts.map +0 -1
  465. package/dist/utils/safe-fetch.d.ts.map +0 -1
  466. package/dist/utils/statuslist-bits.d.ts.map +0 -1
  467. package/dist/utils/statuslist-purpose.d.ts.map +0 -1
  468. package/dist/utils/ttl-cache.d.ts.map +0 -1
  469. package/dist/utils/url.d.ts.map +0 -1
package/CHANGELOG.md CHANGED
@@ -7,6 +7,585 @@ Versioning: https://semver.org/spec/v2.0.0.html
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [1.17.0] - 2026-10-05
11
+
12
+ ### Added
13
+
14
+ - **Scope helpers in `@kya-os/mcp/delegation`.** `matcherContains(outer,
15
+ inner)` decides, by sound rules only, whether one scope matcher grants
16
+ everything another grants. `authorityContains(authority)` builds that check
17
+ once for a whole list of matchers. `scopeAuthority(credential)` returns a
18
+ credential's flat scopes and CRISP matchers as one list of matchers.
19
+ `crispScopes(credential)` returns its CRISP matchers. Scope attenuation
20
+ below is built on them.
21
+ - **Signer binding options for `ProofVerifier.verifyProof`.** An optional
22
+ fourth argument, `{ expectedDid, expectedAudience }` (type
23
+ `ProofVerificationOptions`), rejects a proof from another signer
24
+ (`DID_MISMATCH`) or addressed to another audience (`AUDIENCE_MISMATCH`);
25
+ `expectedAudience` may list several DIDs. Omitting it verifies as before.
26
+ - **`withKyaOs` takes `nonceCache`, `requireAtomicNonce`, and
27
+ `responseProofProfile`.** The adapter could not pass them to the middleware,
28
+ and its `session` option documented a top-level `nonceCache` that did not
29
+ exist. Each replica of a multi-replica deployment therefore kept a private
30
+ in-memory nonce cache and accepted a handshake replayed from another
31
+ replica (SPEC.md §5.5, §11.2; SPEC-MCP-EXTENSION.md §10.4),
32
+ `requireAtomicNonce` was unreachable, and envelope-profile proofs could not
33
+ be enabled. All three now pass through to `createKyaOsMiddleware`. Each is
34
+ optional, and leaving it out keeps the previous default.
35
+ - **`KyaOsCallContext.principal` and `KyaOsCallContext.approvals`.**
36
+ `wrapWithDelegation` fills them for the handler it wraps; see the
37
+ `withPolicyGate` entry under Security. Both are optional members.
38
+ - **`verifyApprovalQuorum` takes several request hashes.** Its `requestHash`
39
+ argument may be a list of hashes that identify the one suspended action; a
40
+ grant over any of them counts. A single string works as before.
41
+
42
+ - **Audit verification and delivery hooks, all optional.**
43
+ `AuditArtifactVerifier` gains `verifySignedCheckpoint` (a checkpoint without
44
+ its leaves), `verifyCurrentKeys` (over `AuditSignedArtifacts`), a
45
+ `maxClockSkewMs` option, and an optional
46
+ `AuditVerificationContext` argument on `verifyEntries`, `verifyCheckpoint`,
47
+ and `verifyObservation` that carries the checkpoints a policy's checkpoint
48
+ bounds name. `applyRequiredAuditProfile` applies a policy's
49
+ `requiredAuditProfile` to a report. `AUDIT_REASON_CODES` gains
50
+ `KEY_BOUNDARY_UNRESOLVED`, `KEY_NOT_CURRENT`, `MERKLE_PROOF_MISSING`,
51
+ `OBSERVATION_FUTURE_DATED`, and `REQUIRED_PROFILE_UNMET`. On the write path,
52
+ `AuditOutboxItemKey` and `auditOutboxItemKey` identify an outbox item by
53
+ source and event ID, `AuditOutboxProvider.capabilities.keyedBySource` opts an
54
+ adapter into receiving that key, `AuditTrailConfiguration` gains
55
+ `onAcknowledgementFailure`, `AuditSourceStateProvider` gains an optional
56
+ `abandonClaim`, and `MemoryAuditSourceState` takes a `redeliveryWindow`.
57
+ Every new provider member is optional, so existing adapters still implement
58
+ their interfaces.
59
+
60
+ ### Changed
61
+
62
+ - **SPEC.md: the `did:key` verification method id is `<did>#<multibase>`.**
63
+ §4.3, the §6.2 example and Appendix C.2 and C.3 gave `<did>#keys-1`, which
64
+ contradicts the W3C did:key method and which no standard resolver,
65
+ including this one, resolves. They, and `CONFORMANCE.md` L1.1, now give the
66
+ W3C form. No code changes.
67
+ - **`json-canonicalize` 3.0.1.** Entity Card proofs (the request hash and the
68
+ covered claims) and cheqd DLR content still canonicalize through
69
+ `json-canonicalize`. 3.x throws on `NaN` and `Infinity`, as RFC 8785
70
+ §3.2.2.3 requires, where 2.0.0 wrote `null`; every JSON value canonicalizes
71
+ to the same bytes as before. A received JSON-RPC request cannot carry those
72
+ values, so verifying calls is unaffected. Minting a card proof, or preparing
73
+ DLR content, with a non-finite number now fails instead of hashing `null`:
74
+ the rule `canonicalizeJson` already applies to response proofs and audit
75
+ records. The package also ships dual ESM/CJS builds.
76
+ - **Built with TypeScript 6.0.** The emitted JavaScript and declaration files
77
+ are byte-identical to the 5.9 build.
78
+ - **Declaration maps are no longer published.** The `.d.ts.map` files pointed
79
+ at `src/`, which the package does not include, so Go to Definition already
80
+ fell back to the `.d.ts`. Types are unchanged. JavaScript source maps stay:
81
+ under `node --enable-source-maps`, or an error tracker that applies source
82
+ maps, stack traces still name the `src/*.ts` file and line. The package drops
83
+ from 691 to 525 files and from 2.69 MB to 2.47 MB unpacked.
84
+
85
+ ### Security
86
+
87
+ - **Scope attenuation across scope representations.** `validateScopeAttenuation`
88
+ treated a parent credential that restricts scope only through
89
+ `constraints.crisp.scopes` matchers as unrestricted, because its flat scope
90
+ list was empty. A re-delegated child could then claim any flat scope (for
91
+ example `admin:root` under a parent limited to the `safe:` prefix), and the
92
+ chain validated. Both credentials are now read as one typed authority (flat
93
+ scopes as `exact` matchers, plus CRISP matchers), and every scope and matcher
94
+ the child grants must be proven inside the parent's authority by sound
95
+ containment rules; anything unprovable is rejected. Sound narrowings that
96
+ were rejected before are now accepted: a flat scope that a parent's matcher
97
+ grants, an `exact` matcher for a parent's flat scope, and a narrower `prefix`
98
+ or `path-prefix` under the parent's. A malformed scope entry proves nothing,
99
+ so it fails closed instead of throwing. A parent with no scopes of either
100
+ kind stays scope-unrestricted, as before (SPEC.md §6.3, §6.4).
101
+ - **`verifyProofDetached` replay and skew bypass.** The signature was checked
102
+ over the payload the caller supplied, while the timestamp and replay checks
103
+ read `proof.meta`, which that payload did not bind: an accepted proof with a
104
+ fresh `meta.nonce`, `ts` or hash verified again. The supplied payload must
105
+ now equal the payload rebuilt from `meta` byte for byte
106
+ (`INVALID_JWS_PAYLOAD`). A caller that passes the canonical payload, as the
107
+ method documents, sees no change.
108
+ - **`ProofGenerator.verifyProof` checks `meta` through the signature.** It
109
+ verified the JWS against its embedded payload and compared the hashes in the
110
+ unsigned `meta`, so a proof with rewritten `meta.requestHash` and
111
+ `meta.responseHash` verified for a different call, and one without
112
+ `meta.responseHash` accepted any response. It now verifies the signature
113
+ over the payload rebuilt from `meta`, requires a response exactly when the
114
+ proof binds one (the rule `ProofVerifier` already applied), and checks
115
+ `meta.did` and `meta.kid` against its identity. It still checks the artifact
116
+ only, with no freshness or replay state. Proofs it minted verify as before.
117
+ - **The embedded JWS payload must be the signed one.** Verification put the
118
+ payload rebuilt from `meta` in place of the JWS's own payload segment
119
+ without looking at that segment, so an intermediary could rewrite the
120
+ embedded `aud`, `responseHash` or `outcome` that JWT tooling and audit
121
+ stores read, and the proof still verified. `CryptoService.verifyJWS` with a
122
+ detached payload now also requires an embedded payload that differs from it
123
+ to verify under the same signature, which only the signed payload does
124
+ (SPEC.md §7.4: the `meta` block and the decoded payload reconcile exactly).
125
+ A JWS without a payload segment (`header..signature`) verifies as before,
126
+ and so does every proof this library mints.
127
+ - **`kid` must belong to `did`.** A proof signed with one DID's key could name
128
+ another DID as its signer (`iss`/`sub`) and verify against the key its `kid`
129
+ named. `ProofVerifier` now rejects a DID URL `kid` whose DID is not
130
+ `meta.did` (`KID_DID_MISMATCH`), as the Entity Card verifier already did
131
+ (SPEC-ENTITY-CARD.md §8). A relative `kid` is unaffected.
132
+ - **The `withKyaOs` transport no longer re-signs results a wrapper already
133
+ proved.** It ran `wrapWithProof` again over every non-error `tools/call`
134
+ result. A `needs_authorization` challenge from `wrapWithDelegation` (not an
135
+ error result) lost its signed `outcome: "needs_authorization"` proof to an
136
+ outcome-less one, which SPEC.md §7.2 reads as `allowed`, and the audit trail
137
+ gained a started and succeeded lifecycle for a call that never ran. A
138
+ delegated call lost its scope-bearing proof and was recorded twice. Once a
139
+ middleware is connected to the transport, its wrappers and outcome paths
140
+ stamp what they return with a random per-middleware token in a private
141
+ `_meta` member, and the transport passes a stamped result through untouched.
142
+ The stamp lives in `_meta` because the MCP SDK re-creates the result object
143
+ when it validates it. The transport removes it from every result before the
144
+ message is sent, so it never reaches the wire. A result without the stamp
145
+ is proved and audited as before, whatever proof, `proofError` or
146
+ `org.kya-os/audit` members it carries: those are removed first, so content
147
+ relayed from an upstream server cannot suppress this server's proof and
148
+ audit events or ship its own proof in their place. Other `_meta` members are
149
+ kept. A middleware used without the transport stamps nothing.
150
+ - **`withPolicyGate` composed inside `wrapWithDelegation` sees the verified
151
+ call.** The delegation gate strips every `_kyaos*` argument before its
152
+ handler runs. The policy gate then projected its principal from the already
153
+ stripped `_kyaos_delegation`, so engines saw `agentDid: "unknown"` and no
154
+ delegated scopes (a deny-list engine allowed everything), and
155
+ `_kyaos_approvals` never arrived, so no step-up could be satisfied. The
156
+ delegation gate now passes the authenticated principal and scopes (for a
157
+ durable grant, those of its re-verified credential) and the approvals in the
158
+ call context, and the policy gate prefers them. Approvals stay outside the
159
+ holder-binding request hash. A policy gate used on its own behaves as
160
+ before.
161
+ - **did:key and base58 input is bounded before decoding.** The did:key path
162
+ decoded the whole counterparty-supplied DID before checking it was a 34-byte
163
+ key, and `base58Decode` had no input limit and quadratic cost: one 100 KB
164
+ `did:key:z…` in a tool call held the event loop for seconds. A did:key whose
165
+ base58 part is longer than 64 characters (an Ed25519 key is always 47) is
166
+ now rejected unread, and its payload must be exactly the prefix and 32-byte
167
+ key. `publicKeyMultibase` and `publicKeyBase58` in DID documents are decoded
168
+ only up to 1024 characters, enough for any published public key.
169
+ `base58Decode` takes that bound as a new optional `maxLength` argument (the
170
+ package root exports 1024 as `MAX_BASE58_DECODE_LENGTH`), and a `maxLength`
171
+ that is not a non-negative integer throws a `RangeError`. Called without
172
+ it, `base58Decode` decodes any length, as before. Its byte conversion is now
173
+ linear; accumulating the digits stays quadratic, which the bound keeps
174
+ small. Every well-formed Ed25519 did:key and verification method resolves
175
+ as before.
176
+ - **`GenericOidcAdapter` accepts only a real token response.** Any 2xx JSON
177
+ body from the token endpoint was a successful authorization, including `{}`
178
+ and the HTTP 200 `{"error":"bad_verification_code"}` some providers return
179
+ for a bad or replayed code. The body must now be a JSON object with no
180
+ `error` member and a non-empty string `access_token` (RFC 6749 §5.1). A
181
+ non-Bearer `token_type` (some providers send `bot`) is accepted. The granted
182
+ scopes are read strictly: an absent `scope` means the requested scopes
183
+ (RFC 6749 §5.1), a string is split on whitespace, so `""` grants none, a
184
+ list of strings is taken as is, and any other `scope` fails the
185
+ authorization instead of granting the requested scopes.
186
+ - **`DefaultPolicyEngine` step-up counts distinct, allowed approvers.** One
187
+ approver listed twice in `humanApprovals` satisfied a quorum of two, and
188
+ `stepUpApprovers` was returned in the step-up challenge but not enforced.
189
+ Only distinct approvers, and only those on the allowlist when one is set,
190
+ now count toward `stepUpQuorum`. `verifyApprovalQuorum` reports the verified
191
+ approvers as `QuorumResult.approvers`, the set `humanApprovals` should be
192
+ built from. It always sets the field; the field is optional, so code that
193
+ builds its own `QuorumResult` still compiles. The `stepUpQuorum` value
194
+ itself is read as before, and distinct, allowed approvals decide as before.
195
+ - **Small-order Ed25519 public keys are rejected.** Under such a key one
196
+ signature verifies for every message, so anyone could sign as a did:key
197
+ built from it, and OpenSSL, WebCrypto and `jose` all accept it.
198
+ `NodeCryptoProvider` and `WebCryptoProvider` now refuse the small-order
199
+ encodings libsodium blocks, and so does every path that imports a key
200
+ itself: VC-JWT verification, Entity Card proofs and their HTTP message
201
+ signatures, and `CompactJwsAuditSignatureVerifier`. Those check the imported
202
+ key rather than the JWK, because Node's JWK import tolerates junk in `x`.
203
+ The audit verifier cannot read back a public key its resolver imported as
204
+ non-extractable, and verifies under such a key as before.
205
+ `NodeCryptoProvider` also decodes keys strictly, as `WebCryptoProvider`
206
+ already did: a 64-byte key or a key with trailing junk no longer verifies.
207
+ ASCII whitespace in a key is still ignored, as both decoders did, so a key
208
+ read from a file with its newline verifies as before, and so does a 32-byte
209
+ key in base64, unpadded base64, or base64url.
210
+ - **Strict canonicalization never honours `toJSON`.** `canonicalizeJson` and
211
+ `canonicalizeJsonBytes` validated their input and then serialized it with
212
+ `json-canonicalize`, which hands any object with a `toJSON` member to
213
+ `JSON.stringify`: `{"toJSON":"x", ...}` came out unsorted (not RFC 8785),
214
+ and a hidden `toJSON` function, or one on an array, replaced the value that
215
+ was hashed or signed. They now serialize the validated value themselves, in
216
+ one pass linear in the size of the input. Properties JSON does not carry
217
+ (non-enumerable ones, and an array's non-index ones such as a `toJSON`) are
218
+ ignored, as before, and never consulted, so `'abc'.match(/b/)` still
219
+ serializes as `["b"]`. An accessor array element is now refused, as an
220
+ accessor member already was, because the value checked could differ from
221
+ the value written. Output is byte-identical to `json-canonicalize` for plain
222
+ JSON (anything `JSON.parse` returns or an object literal builds), and the
223
+ conformance vectors are unchanged.
224
+
225
+ - **Graph revocation is checked for the whole chain.** `validateDelegationChain`
226
+ asked its `RevocationChecker` about the leaf only, so a leaf minted after an
227
+ ancestor's revocation, and therefore never registered in the graph, still
228
+ validated. Every credential in the verified chain is now checked, root
229
+ first, and a checker that throws fails the chain instead of throwing.
230
+
231
+ - **Revocation is recorded in the graph.** `revokeDelegation` only flipped a
232
+ status bit when `credentialStatusId` had the form `<list>#<digits>`, and
233
+ otherwise reported success while recording nothing, so a delegation whose
234
+ status id was a `urn:uuid:` read as live after revocation (SPEC.md §6.5 step
235
+ 1). `DelegationNode` gains an optional `revoked` flag, which revocation sets,
236
+ restore clears, and `isRevoked` honours alongside the status bit, and
237
+ `registerDelegation` accepts an optional structured `credentialStatus` so no
238
+ id has to be parsed. A status id that names no list entry still registers
239
+ and revokes without error, as before; it now also reads as revoked. Both
240
+ fields are optional, so existing storage providers keep working. One that
241
+ persists a fixed set of node fields must also store `revoked`: revocation
242
+ reads the node back, and revoking a delegation that has no status list
243
+ entry through a provider that dropped the mark now throws, naming that
244
+ requirement, instead of reporting success while recording nothing. With an
245
+ entry, the status bit still records it.
246
+
247
+ - **Registering a delegation id again cannot replace it.** `registerDelegation`
248
+ overwrote the stored node whenever an id was registered again, dropping its
249
+ `credentialStatusId`, revocation and children: re-registering a revoked
250
+ ancestor read its whole subtree as live again, and re-registering a node
251
+ under its own descendant left a parent cycle that `getChain` walked forever.
252
+ A repeat registration that matches the stored node in every registered field
253
+ (`parentId`, `issuerDid`, `subjectDid`, `credentialStatusId`,
254
+ `credentialStatus`) is now a no-op that returns the stored node, children
255
+ and revocation intact, so retries stay safe. One that differs in any of them
256
+ throws, as does a delegation naming itself as parent, on the non-atomic path
257
+ and in `MemoryDelegationGraphStorage.registerNodeAtomic`; the memory store's
258
+ chain walk throws on a cycle. A custom `AtomicDelegationGraphStorageProvider`
259
+ should apply the same rule, since only it can close the race between the
260
+ manager's check and its write.
261
+
262
+ - **First status list creation is serialized with updates.** A status list was
263
+ created on first allocation outside its update lock, so a concurrent
264
+ allocation could replace a list that had just recorded a revocation with a
265
+ fresh, empty one (SPEC.md §11.10). Creation now runs inside the list's lock
266
+ and re-reads the list there.
267
+
268
+ - **`did:web` host labels cannot smuggle in another URL.** The host label is
269
+ percent-decoded, and what it decoded to was used unchecked:
270
+ `did:web:trusted.example%40attacker.example` fetched its document from
271
+ `attacker.example`, and `%2F`, `%3F` and `%23` injected a path, query or
272
+ fragment. A host that decodes to `@`, `/`, `\`, `?`, `#`, whitespace, a
273
+ control character, or a `:` beyond one port separator (a bracketed IPv6
274
+ literal keeps its own colons) is now rejected, as is a path component that
275
+ decodes to a separator, a dot-segment or nothing (SPEC.md §4.4). A malformed
276
+ escape returns `null` instead of throwing. Ports, IPv4 and IPv6 literals and
277
+ percent-encoded internationalized hosts resolve as before.
278
+
279
+ - **Unreadable validity bounds fail closed.** An `expirationDate` that did not
280
+ parse (`2020-02-30T25:00:00Z`) and a non-numeric `constraints.notAfter` or
281
+ `notBefore` were read as no bound at all, so the credential never expired;
282
+ a `notAfter` of `0` was skipped the same way. A present bound that cannot be
283
+ read now places the credential outside its validity window. Basic checks
284
+ also accepted any delegation `status` other than `revoked` and `expired`
285
+ (`suspended`, or none), though the type allows only `active`, `revoked` and
286
+ `expired`; only `active` passes now.
287
+
288
+ - **VC-JWT verification no longer throws on hostile input.** A JOSE header or
289
+ claims set that is not a JSON object (`null`, an array), a `kid` that is not
290
+ a string, and a DID resolver that throws all escaped `verifyDelegationJwt`
291
+ as exceptions, so a caller outside a `try` recorded no rejection. Each now
292
+ returns a failed result.
293
+
294
+ - **CIMD documents can no longer speak for another origin's DID.**
295
+ `cardFromClientMetadata` accepted any declared `_meta["org.kya-os/did"]`,
296
+ and `verifyCimdBind` took the DID from the DID document rather than the card,
297
+ so a document at `https://attacker.example/clients/x` declaring
298
+ `did:web:victim.example:clients:acme` produced a victim-id card whose bind
299
+ check passed. `cardFromClientMetadata` now rejects a declared `did:web`
300
+ whose origin (host and port) differs from the `client_id`'s. Every
301
+ same-origin shape the CIMD draft allows still derives a card: a root with a
302
+ trailing slash, a query, an explicit `:443`, a root DID declared on a path
303
+ `client_id`, and a declared `did:key`. `verifyCimdBind(cimd, didDoc,
304
+ expectedDid?)` takes an optional third argument (pass the card's `id`) and
305
+ then also requires `didDoc.id` to be that DID and `client_id` to be its HTTPS
306
+ form, compared as normalized URLs. Two-argument calls behave exactly as
307
+ before, so they cannot detect a card/document mismatch.
308
+
309
+ - **`resolveCard` no longer conflates distinct `did:web` DIDs.** The identity
310
+ binding percent-decoded each segment and rejoined with `:`, so
311
+ `did:web:host:users:alice%3Aagent` accepted Alice's card
312
+ `did:web:host:users:alice:agent`, and `did:web:host:8443` accepted a card for
313
+ the port-form `did:web:host%3A8443`. DIDs are now compared in canonical
314
+ encoded form: host lowercased, each segment decoded and re-encoded, so two
315
+ spellings of one DID still match.
316
+
317
+ - **`MaxAmount` attenuation compares exact decimals.** Limits were truncated to
318
+ six fractional digits, so `100.0000009` passed as a narrowing of `100`, and a
319
+ child `0.0000009` under a parent `0.0000001` (both scaled to zero) passed
320
+ too. Both limits are now scaled to the longer fraction and compared exactly
321
+ (SPEC.md §6.10).
322
+
323
+ - **Audit checkpoints no longer sign a rewritten history.**
324
+ `AuditCheckpointBuilder.createCheckpoint` compared the journal with the latest
325
+ checkpoint only when both had the same tree size. A journal that had been
326
+ rewritten or restored and had since grown got a new signed checkpoint chained
327
+ to the old one, which it does not extend: a split view carrying the
328
+ recorder's own signature. The builder now checks that the journal still holds
329
+ the latest checkpoint's exact tree as its prefix and fails with
330
+ `AUDIT_CHECKPOINT_CONFLICT` otherwise.
331
+
332
+ - **Audit verification policies are enforced instead of ignored.** The
333
+ `validFromCheckpoint` / `validUntilCheckpoint` bounds (on recorder, observer,
334
+ and exporter keys and on trusted ledger epochs), `requiredAuditProfile`, and
335
+ `keyRevocationMode` were schema-valid but never read, so an entry signed after
336
+ its key's validity boundary verified, and a bundle without checkpoints passed
337
+ an AAP-4 policy with exit code 0. Checkpoint bounds now place each artifact by
338
+ tree position against checkpoints resolved by digest; a bound that cannot be
339
+ placed (a missing boundary, one in another epoch, or any bound on an exporter
340
+ key, since an export has no ledger position) makes the dimension
341
+ `indeterminate`, never `valid`. A required profile marks each dimension it
342
+ depends on `invalid` unless it is `valid`. Under `keyRevocationMode`
343
+ `current` or `both`, every signing key must also still be valid at
344
+ `verifiedAt`, reported in `currentAuthorization` (`AUDIT_KEY_NOT_CURRENT`);
345
+ `as_observed` is unchanged. Every policy that 1.16 accepted is still
346
+ accepted; none is rejected for the constraints it uses.
347
+
348
+ - **A predecessor epoch ends at the terminal checkpoint its successor
349
+ committed.** The bundle verifier only checked that the committed terminal
350
+ checkpoint was present, so a stale authority that kept checkpointing the old
351
+ epoch after rollover verified as valid. A predecessor checkpoint over a larger
352
+ tree than that terminal now reports `AUDIT_CHECKPOINT_FORK_DETECTED`. Entries
353
+ past the terminal alone are not a fork, since the terminal checkpoint's own
354
+ `checkpoint.created` event follows it.
355
+
356
+ - **The recorder fails closed when its journal moves backwards.** After a
357
+ failover to a lagging primary or a restore, `AuditRecorderService` appended on
358
+ the lower head and signed a second, different entry at an already receipted
359
+ sequence. A head read below this recorder's own commits is now raised to its
360
+ committed head for the compare-and-append, so a stale read replica still only
361
+ costs a retry, and a journal whose compare-and-append answer reports a head
362
+ below that committed head, or a different digest at a sequence it already
363
+ reported, fails with `AUDIT_JOURNAL_FAILURE` before anything is appended.
364
+
365
+ - **Hostile references can no longer keep an MCP audit event out of the
366
+ ledger.** `McpAuditEventAdapter` truncated references by UTF-16 code units and
367
+ passed context references through unbounded, so a presented credential ID
368
+ with a lone surrogate, a split surrogate pair, or more than 256 characters
369
+ made the event fail canonicalization or schema validation, even in
370
+ best-effort mode, and a rejected delegation went unrecorded. Every caller
371
+ reference, including `authorization.*` and correlation/causation IDs, is now
372
+ kept verbatim when well-formed and within bounds, and otherwise recorded as
373
+ the `sha256:` digest of its UTF-8 encoding. An over-long tool name or
374
+ reference that 1.16 truncated is recorded as that digest instead.
375
+ `wrapWithDelegation` still truncates a rejected credential's ID to 256 code
376
+ units before the adapter sees it, as in 1.16.
377
+
378
+ - **A failed append no longer disposes evidence a committed entry still uses.**
379
+ The recorder's cleanup after a failed append disposed every submitted
380
+ evidence object, including one that already existed and that an earlier
381
+ committed entry references (a session's shared actor object, for example).
382
+ Only objects that the failed submission newly stored are disposed now, and
383
+ never one that a concurrent submission to the same recorder held at the same
384
+ time, since that submission may have committed a reference to it.
385
+
386
+ - **A projection built from a forked history is never reported verified.**
387
+ `AuditProjectionWorker.reconcile` reported a lagging projection as `pending`
388
+ without checking its offset digest, and `synchronize` appended entries that do
389
+ not chain from that offset. Reconciliation now compares the offset with the
390
+ journal entry at that sequence (`gap_detected` on mismatch), and
391
+ synchronization fails with `AUDIT_PROJECTION_CONFLICT` instead of extending a
392
+ foreign prefix.
393
+
394
+ ### Fixed
395
+
396
+ - **A `requestHash` over the request as sent now verifies.** SPEC.md §7.3 and
397
+ Appendix C.1 describe `requestHash` over the `tools/call` request, while the
398
+ middleware hashes `{method: <tool name>, params: <arguments>}`, so a client
399
+ recomputing the hash from the request it sent always got
400
+ `CONTENT_BINDING_MISMATCH`, and a holder-of-key request proof minted that
401
+ way never bound at the PEP. Every verifier of a received request hash now
402
+ accepts either shape of the same call: `ProofVerifier` content binding,
403
+ `ProofGenerator.verifyProof`, the holder-binding check of
404
+ `wrapWithDelegation` and durable-grant resolution, and step-up approval
405
+ grants in `withPolicyGate`. The caller may hold the request in either shape
406
+ (`{method: "tools/call", params: {name, arguments}}` as sent, or the legacy
407
+ shape), and both hashes are derived from it; the §7.3 shape leaves out
408
+ `params._meta` and the `_kyaos*` control arguments. Producers are
409
+ unchanged: response and outcome proofs, the `requestHash` of a
410
+ `needs_approval` challenge, and `generateRequestProof` still emit the
411
+ legacy shape, so verifiers of earlier releases keep accepting them. Each
412
+ accepted hash covers the same tool name and business arguments, so no proof
413
+ over a different call is admitted. §7.3 now states the control-argument and
414
+ `_meta` exclusions, and Appendix C.1 gives covered-request vectors.
415
+ - **`fetchPublicKeyFromDID` resolves the `kid` proofs carry.** It prefixed `#`
416
+ to every `kid`, so a full DID URL (`did:key:z…#z…`, the form this library
417
+ mints) never matched. A DID URL `kid` must now name the DID being resolved
418
+ (`KID_DID_MISMATCH` otherwise) and match the verification method id; a bare
419
+ fragment is still resolved against the DID.
420
+ - **`MemoryResumeTokenStore` stays bounded.** A token is minted for every
421
+ unauthorized call, and was deleted only when that exact token was read after
422
+ it expired; fulfilled tokens were never deleted. `create()` now drops expired
423
+ tokens and `fulfill()` deletes the token. A challenge's `expiresAt` is now
424
+ the expiry the store enforces, read back from the store: it came from
425
+ `authorization.resumeTokenTtl`, so a configured hour was advertised for a
426
+ token the default store expires after 10 minutes. `resumeTokenTtl` is now
427
+ the fallback for a store that cannot report a future expiry in
428
+ milliseconds.
429
+ - **Expired sessions no longer switch off the single-session fallback.** The
430
+ fallback counted every stored session, live or expired, and nothing swept
431
+ them, so once a second session had existed proofs stopped for every
432
+ unthreaded call. A count above one now sweeps expired sessions first (at
433
+ most once a minute). Concurrent first calls under `autoSession` share one
434
+ auto-created session instead of racing into two.
435
+ - **Proofs keep handler `_meta` keys.** Attaching a proof, or a `proofError`
436
+ in the middleware or the transport, replaced `_meta` and dropped keys such
437
+ as `traceparent` and `io.modelcontextprotocol/related-task`. They are now
438
+ merged (SPEC.md §7.6). The proof, `proofError` and `org.kya-os/audit`
439
+ members are the exception: only the middleware sets them, so a handler's
440
+ copies are still dropped when a proof or proof error is attached, and a
441
+ relayed upstream result cannot place them next to this server's proof.
442
+ - **The transport matches proofs to responses only.** A server-initiated
443
+ request (for example `elicitation/create`) whose id equalled a pending
444
+ `tools/call` id consumed that call's entry, and the tool response shipped
445
+ unproven. Entries for cancelled calls are also dropped on
446
+ `notifications/cancelled`.
447
+ - **SPEC.md: nonce retention is bounded by the acceptance window.** §5.2, §5.5
448
+ and §11.2 required nonces to be kept for the session TTL plus a minute,
449
+ while §5.2 also recommended 60 seconds. A nonce presented after its
450
+ timestamp leaves the acceptance window is rejected on that timestamp, so the
451
+ longer retention bought memory and denial-of-service exposure and no
452
+ protection. §5.5 now requires retention until `ts + skew` plus a margin, for
453
+ the widest skew the verifier may apply, which is what the reference
454
+ implementation already does, and says why the bound holds on every
455
+ nonce-checked path. CONFORMANCE.md L2.5 follows, and L2.11 describes the
456
+ per-proof nonce and both request-hash shapes.
457
+ - **In-memory replay and pending-flow stores evict on their own.**
458
+ `MemoryNonceCacheProvider`, the default replay store for `withKyaOs` and
459
+ `SessionManager`, and `MemoryPendingFlowStore` freed expired entries only on
460
+ an explicit `cleanup()`, which nothing schedules, so every handshake nonce
461
+ and abandoned authorization flow stayed resident. Both now sweep expired
462
+ entries as they are written to: every 1000 writes, or after a minute. A live
463
+ entry is never swept, and `cleanup()` works as before.
464
+ - **`@kya-os/mcp/providers` bundles for browsers and Workers again.** The
465
+ entry documented for `WebCryptoProvider` also exports `NodeCryptoProvider`,
466
+ which imported `node:crypto` at module load and broke every browser bundle.
467
+ `node:crypto` now loads on first use; the exports are unchanged.
468
+ - **cheqd DLR content hashes are always computed.** `prepareCheqdDlrResource`
469
+ returned a caller-supplied `contentHash` as the artifact's content address
470
+ without checking it against the bytes being anchored. The hash is now
471
+ always computed from the canonical content bytes, and a supplied one that
472
+ differs throws. Canonicalization of the content is unchanged.
473
+
474
+ - **Status list indexes stay inside the list.** `updateStatus` parsed
475
+ `statusListIndex` with `parseInt`, so revoking `"5abc"` flipped bit 5, which
476
+ belongs to another credential, while `checkStatus` already parsed strictly.
477
+ Both now share the strict parser. `allocateStatusEntry` also handed out
478
+ indexes past the end of the list, which no read or revocation could reach;
479
+ it now throws once the list is full (SPEC.md §6.7).
480
+
481
+ - **A status list with an unreadable validity window is not fresh.** A
482
+ `validUntil` / `validFrom` (or `expirationDate` / `issuanceDate`) that was
483
+ present but not a parseable date was treated as absent, so the list read as
484
+ live. It now reads as not fresh (L3 → L2); the revocation bit is still read.
485
+
486
+ - **Card schemas match the published JSON Schemas.** `CapabilityAttestation`
487
+ stripped unknown members (the JSON Schema allows them), dropping sidecar
488
+ fields such as `credentialStatus` before the capability verifier saw them;
489
+ extra members are now preserved. `DelegationCredentialSchema.type` accepted
490
+ any string array; it now requires `VerifiableCredential` and
491
+ `DelegationCredential`, so another VC with a ZCAP-shaped subject is not read
492
+ as a delegation hop. `schemas/card-delegation-credential.json` enforces the
493
+ same two types it already documented.
494
+
495
+ - **`getInclusionProof` works for sequence 1.** The entry lookup started its
496
+ range read after sequence 1 for any sequence up to 1, so the first entry after
497
+ genesis could never be proven.
498
+
499
+ - **`listEntries` pages are bounded by the head they echo.** The head was read
500
+ after the page, so a concurrent append could return `nextAfterSequence: null`
501
+ with a head beyond the last entry, contrary to SPEC-AUDIT-READ §2.2. The head
502
+ is now read first and bounds the page.
503
+
504
+ - **Subset replay bundles verify.** A checkpoint was verified only against every
505
+ leaf of its tree, and included checkpoints had to link directly, so a
506
+ legitimate export of a sequence range or of non-adjacent checkpoints was
507
+ invalid. Without its complete prefix, a checkpoint is now verified by
508
+ signature, digest, trust, and declared range, and each covered entry needs a
509
+ verified inclusion proof (`AUDIT_MERKLE_PROOF_MISSING` otherwise).
510
+ Checkpoints that could have omitted ones between them may be bound by a
511
+ verified consistency proof instead of a direct `previousCheckpointDigest`
512
+ link, the rule independent observers already apply.
513
+
514
+ - **Concurrent checkpoints on one builder chain in order.** Two concurrent
515
+ `createCheckpoint` calls at different sizes could both chain to the same
516
+ predecessor. A builder now serializes its calls per ledger epoch. The
517
+ `AuditCheckpointStore` contract is unchanged.
518
+
519
+ - **A failed checkpoint lifecycle hook runs again.** When `onCheckpointCreated`
520
+ threw after the checkpoint was stored, a retry returned the stored checkpoint
521
+ without calling the hook, losing the lifecycle event. The builder's next
522
+ `createCheckpoint` call now runs the hook again for every checkpoint whose
523
+ hook failed, oldest first and before any newer checkpoint's, even when the
524
+ ledger has grown in between; the hook should be idempotent on the checkpoint
525
+ digest. A hook that completed is not repeated.
526
+
527
+ - **A future-dated observation is not fresh.** With a freshness requirement,
528
+ an observation dated after `verifiedAt` passed. One dated beyond the clock
529
+ skew allowance (`maxClockSkewMs`, default 120 s) is now `invalid` with
530
+ `AUDIT_OBSERVATION_FUTURE_DATED`.
531
+
532
+ - **Redelivering a stable event ID returns the original receipt.**
533
+ `MemoryAuditSourceState` dropped the claims of receipted events, so an
534
+ at-least-once redelivery after later events got a new source sequence and was
535
+ rejected as `AUDIT_EVENT_ID_CONFLICT`. Receipted claims are now retained for a
536
+ bounded `redeliveryWindow` (default 1024 per source). Different content under
537
+ a retained event ID is still an `AuditProtocolError` with
538
+ `AUDIT_EVENT_ID_CONFLICT`, now raised by the source state; it was a plain
539
+ `Error` there before.
540
+
541
+ - **Rejected input no longer consumes a source sequence.** The trail claimed a
542
+ source sequence before validating the event, so schema-invalid input, a lone
543
+ surrogate, or an unreferenced evidence object left a permanent gap and a
544
+ broken `previousSourceEventDigest` link. Validation now runs first, and a
545
+ claim whose event cannot be emitted is released through the optional
546
+ `abandonClaim`.
547
+
548
+ - **Source state no longer leaks behind an open gap.** One unreceipted sequence
549
+ stopped `MemoryAuditSourceState` from pruning anything after it. It now keeps
550
+ only pending events plus the redelivery window.
551
+
552
+ - **A replica that loses the cold-start genesis race recovers.** When every read
553
+ was stale, the losing genesis surfaced as an idempotency conflict and failed
554
+ with `AUDIT_EVENT_ID_CONFLICT`; it is now validated against the epoch
555
+ configuration like any raced genesis.
556
+
557
+ - **A committed outbox item is never reported as a delivery failure.** If
558
+ `markDelivered` threw after the recorder committed, `flush()` called
559
+ `markFailed` and `onDeliveryFailure`. The item now counts as delivered, the
560
+ error goes to the new `onAcknowledgementFailure` callback, and redelivery
561
+ resolves to the same receipt.
562
+
563
+ - **Outbox items are identified by source and event ID.** Event IDs are unique
564
+ only within a source, but `MemoryAuditOutbox` keyed items by event ID alone,
565
+ so one source could acknowledge or displace another's pending item.
566
+ `markDelivered` and `markFailed` now accept an `AuditOutboxItemKey` as well as
567
+ a bare event ID, and the trail passes the key to an outbox that declares
568
+ `capabilities.keyedBySource`, as `MemoryAuditOutbox` now does. An adapter
569
+ that implements `markDelivered(eventId: string)` still type-checks and still
570
+ receives the bare event ID, and so does a `MemoryAuditOutbox` subclass that
571
+ overrides `markDelivered` or `markFailed`: the memory outbox declares the
572
+ capability only for its own implementations, unless the subclass declares it
573
+ again. `MemoryAuditOutbox` throws on a bare event ID that more than one source
574
+ has pending instead of guessing.
575
+
576
+ - **Default audit event IDs are random.** `audit_<time>_<counter>` was unique
577
+ only per trail instance, so two trails sharing an outbox collided. Defaults
578
+ are now `audit_<uuid>`; `eventIdFactory` still overrides them.
579
+
580
+ ### Deprecated
581
+
582
+ - **The legacy request-hash shape.** `requestHash` over
583
+ `{method: <tool name>, params: <arguments>}` is deprecated in favour of the
584
+ SPEC.md §7.3 covered `tools/call` request. Producers switch to the §7.3
585
+ shape in 2.0.0; verifiers accept both until then.
586
+ - `ProofVerifier.verifyProofDetached`. The payload it takes must now equal the
587
+ payload rebuilt from `proof.meta`, so it adds nothing over `verifyProof`.
588
+
10
589
  ## [1.16.2] - 2026-09-21
11
590
 
12
591
  ### Changed
package/CONFORMANCE.md CHANGED
@@ -52,7 +52,7 @@ Implementation MUST:
52
52
  - Generate cryptographically secure random 32-byte private seed
53
53
  - Derive 32-byte public key from seed
54
54
  - Derive `did:key` DID from public key using multicodec prefix `0xed01` and base58btc encoding
55
- - Key ID format: `<did>#keys-1`
55
+ - Key ID format: `<did>#<multibase>`, the W3C did:key verification method ID (SPEC.md §4.3)
56
56
 
57
57
  #### L1.2 — SHA-256 Hashing
58
58
 
@@ -125,7 +125,7 @@ Implementation MUST validate:
125
125
  #### L2.5 — Nonce Replay Prevention
126
126
 
127
127
  Implementation MUST:
128
- - Store (nonce, agentDid) tuples for at least `sessionTtlMinutes + 1 minute`
128
+ - Store (nonce, agentDid) tuples at least until the nonce's timestamp leaves the acceptance window (`ts + skew`, SPEC §5.5)
129
129
  - Reject any request with a previously-seen nonce for the same agentDid
130
130
  - Support cleanup of expired nonces
131
131
 
@@ -139,10 +139,10 @@ Proof metadata MUST include:
139
139
  - `did`: Signer's DID
140
140
  - `kid`: Key ID used for signing
141
141
  - `ts`: Unix epoch seconds
142
- - `nonce`: Session nonce
142
+ - `nonce`: Fresh random nonce per proof
143
143
  - `audience`: Session audience
144
144
  - `sessionId`: Session identifier
145
- - `requestHash`: SHA-256 of canonicalized request (`sha256:<hex>`)
145
+ - `requestHash`: SHA-256 of the canonicalized request (`sha256:<hex>`), over the covered request of SPEC §7.3 or, as 1.x implementations emit it, the legacy `{method: <tool name>, params: <arguments>}` shape; a verifier accepts either for the same call
146
146
 
147
147
  `responseHash` (SHA-256 of the canonicalized response, `sha256:<hex>`) MUST be
148
148
  present on proofs that carry a response body — success proofs and