@xemahq/xema 0.59.1 → 0.60.1

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 (850) hide show
  1. package/README.md +1 -2
  2. package/dist/appliance-owner.d.ts.map +1 -1
  3. package/dist/appliance-owner.js +6 -6
  4. package/dist/appliance-owner.js.map +1 -1
  5. package/dist/assets/appliance-base/authorization.lock.json +5186 -0
  6. package/dist/assets/appliance-base/distribution.lock.json +760 -279
  7. package/dist/assets/appliance-base/images.lock.json +576 -513
  8. package/dist/assets/appliance-lean/authorization.lock.json +4648 -0
  9. package/dist/assets/appliance-lean/distribution.lock.json +641 -186
  10. package/dist/assets/appliance-lean/images.lock.json +574 -512
  11. package/dist/assets/boot-graph.json +33 -14
  12. package/dist/assets/distribution-assets.manifest.json +23 -20
  13. package/dist/cli.d.ts.map +1 -1
  14. package/dist/cli.js +7 -9
  15. package/dist/cli.js.map +1 -1
  16. package/dist/commands/biome-dev.d.ts.map +1 -1
  17. package/dist/commands/biome-dev.js +41 -137
  18. package/dist/commands/biome-dev.js.map +1 -1
  19. package/dist/commands/biome-lifecycle.d.ts +24 -0
  20. package/dist/commands/biome-lifecycle.d.ts.map +1 -0
  21. package/dist/commands/biome-lifecycle.js +253 -0
  22. package/dist/commands/biome-lifecycle.js.map +1 -0
  23. package/dist/commands/biome.d.ts +2 -4
  24. package/dist/commands/biome.d.ts.map +1 -1
  25. package/dist/commands/biome.js +61 -46
  26. package/dist/commands/biome.js.map +1 -1
  27. package/dist/commands/config.d.ts.map +1 -1
  28. package/dist/commands/config.js +96 -8
  29. package/dist/commands/config.js.map +1 -1
  30. package/dist/commands/doctor.d.ts.map +1 -1
  31. package/dist/commands/doctor.js +13 -20
  32. package/dist/commands/doctor.js.map +1 -1
  33. package/dist/commands/down.d.ts.map +1 -1
  34. package/dist/commands/down.js +14 -21
  35. package/dist/commands/down.js.map +1 -1
  36. package/dist/commands/init.d.ts.map +1 -1
  37. package/dist/commands/init.js +6 -3
  38. package/dist/commands/init.js.map +1 -1
  39. package/dist/commands/installation-tenancy.d.ts +11 -0
  40. package/dist/commands/installation-tenancy.d.ts.map +1 -0
  41. package/dist/commands/installation-tenancy.js +308 -0
  42. package/dist/commands/installation-tenancy.js.map +1 -0
  43. package/dist/commands/installation.d.ts.map +1 -1
  44. package/dist/commands/installation.js +19 -5
  45. package/dist/commands/installation.js.map +1 -1
  46. package/dist/commands/logs.d.ts +2 -0
  47. package/dist/commands/logs.d.ts.map +1 -1
  48. package/dist/commands/logs.js +41 -8
  49. package/dist/commands/logs.js.map +1 -1
  50. package/dist/commands/{dev.d.ts → mirror.d.ts} +1 -1
  51. package/dist/commands/mirror.d.ts.map +1 -0
  52. package/dist/commands/mirror.js +132 -0
  53. package/dist/commands/mirror.js.map +1 -0
  54. package/dist/commands/source.d.ts.map +1 -1
  55. package/dist/commands/source.js +3 -2
  56. package/dist/commands/source.js.map +1 -1
  57. package/dist/commands/status.d.ts.map +1 -1
  58. package/dist/commands/status.js +40 -21
  59. package/dist/commands/status.js.map +1 -1
  60. package/dist/commands/up.d.ts.map +1 -1
  61. package/dist/commands/up.js +36 -4
  62. package/dist/commands/up.js.map +1 -1
  63. package/dist/dev/infra-preflight.d.ts.map +1 -1
  64. package/dist/dev/infra-preflight.js +0 -4
  65. package/dist/dev/infra-preflight.js.map +1 -1
  66. package/dist/lib/confirm.d.ts +3 -0
  67. package/dist/lib/confirm.d.ts.map +1 -0
  68. package/dist/lib/confirm.js +19 -0
  69. package/dist/lib/confirm.js.map +1 -0
  70. package/dist/lib/output-format.d.ts +6 -0
  71. package/dist/lib/output-format.d.ts.map +1 -0
  72. package/dist/lib/output-format.js +20 -0
  73. package/dist/lib/output-format.js.map +1 -0
  74. package/dist/mirror/config/mirror-config-document.d.ts +18 -0
  75. package/dist/mirror/config/mirror-config-document.d.ts.map +1 -0
  76. package/dist/mirror/config/mirror-config-document.js +57 -0
  77. package/dist/mirror/config/mirror-config-document.js.map +1 -0
  78. package/dist/mirror/config/mirror-config-schema.d.ts +54 -0
  79. package/dist/mirror/config/mirror-config-schema.d.ts.map +1 -0
  80. package/dist/mirror/config/mirror-config-schema.js +80 -0
  81. package/dist/mirror/config/mirror-config-schema.js.map +1 -0
  82. package/dist/mirror/kit/delta.d.ts +4 -0
  83. package/dist/mirror/kit/delta.d.ts.map +1 -0
  84. package/dist/mirror/kit/delta.js +41 -0
  85. package/dist/mirror/kit/delta.js.map +1 -0
  86. package/dist/mirror/kit/export-kit.d.ts +16 -0
  87. package/dist/mirror/kit/export-kit.d.ts.map +1 -0
  88. package/dist/mirror/kit/export-kit.js +112 -0
  89. package/dist/mirror/kit/export-kit.js.map +1 -0
  90. package/dist/mirror/kit/import-kit.d.ts +9 -0
  91. package/dist/mirror/kit/import-kit.d.ts.map +1 -0
  92. package/dist/mirror/kit/import-kit.js +166 -0
  93. package/dist/mirror/kit/import-kit.js.map +1 -0
  94. package/dist/mirror/kit/kit-archive.d.ts +4 -0
  95. package/dist/mirror/kit/kit-archive.d.ts.map +1 -0
  96. package/dist/mirror/kit/kit-archive.js +38 -0
  97. package/dist/mirror/kit/kit-archive.js.map +1 -0
  98. package/dist/mirror/kit/kit-layout.d.ts +10 -0
  99. package/dist/mirror/kit/kit-layout.d.ts.map +1 -0
  100. package/dist/mirror/kit/kit-layout.js +19 -0
  101. package/dist/mirror/kit/kit-layout.js.map +1 -0
  102. package/dist/mirror/kit/kit-sums.d.ts +5 -0
  103. package/dist/mirror/kit/kit-sums.d.ts.map +1 -0
  104. package/dist/mirror/kit/kit-sums.js +63 -0
  105. package/dist/mirror/kit/kit-sums.js.map +1 -0
  106. package/dist/mirror/kit/layout-sync.d.ts +8 -0
  107. package/dist/mirror/kit/layout-sync.d.ts.map +1 -0
  108. package/dist/mirror/kit/layout-sync.js +58 -0
  109. package/dist/mirror/kit/layout-sync.js.map +1 -0
  110. package/dist/mirror/plan/bundle-content.d.ts +10 -0
  111. package/dist/mirror/plan/bundle-content.d.ts.map +1 -0
  112. package/dist/mirror/plan/bundle-content.js +61 -0
  113. package/dist/mirror/plan/bundle-content.js.map +1 -0
  114. package/dist/mirror/plan/declaration-file.d.ts +9 -0
  115. package/dist/mirror/plan/declaration-file.d.ts.map +1 -0
  116. package/dist/mirror/plan/declaration-file.js +27 -0
  117. package/dist/mirror/plan/declaration-file.js.map +1 -0
  118. package/dist/mirror/plan/edition-inputs.d.ts +57 -0
  119. package/dist/mirror/plan/edition-inputs.d.ts.map +1 -0
  120. package/dist/mirror/plan/edition-inputs.js +44 -0
  121. package/dist/mirror/plan/edition-inputs.js.map +1 -0
  122. package/dist/mirror/plan/edition-reader.d.ts +9 -0
  123. package/dist/mirror/plan/edition-reader.d.ts.map +1 -0
  124. package/dist/mirror/plan/edition-reader.js +47 -0
  125. package/dist/mirror/plan/edition-reader.js.map +1 -0
  126. package/dist/mirror/plan/image-content.d.ts +30 -0
  127. package/dist/mirror/plan/image-content.d.ts.map +1 -0
  128. package/dist/mirror/plan/image-content.js +120 -0
  129. package/dist/mirror/plan/image-content.js.map +1 -0
  130. package/dist/mirror/plan/npm-lockfile.d.ts +12 -0
  131. package/dist/mirror/plan/npm-lockfile.d.ts.map +1 -0
  132. package/dist/mirror/plan/npm-lockfile.js +106 -0
  133. package/dist/mirror/plan/npm-lockfile.js.map +1 -0
  134. package/dist/mirror/plan/oci-reads.d.ts +22 -0
  135. package/dist/mirror/plan/oci-reads.d.ts.map +1 -0
  136. package/dist/mirror/plan/oci-reads.js +43 -0
  137. package/dist/mirror/plan/oci-reads.js.map +1 -0
  138. package/dist/mirror/plan/plan-command.d.ts +22 -0
  139. package/dist/mirror/plan/plan-command.d.ts.map +1 -0
  140. package/dist/mirror/plan/plan-command.js +81 -0
  141. package/dist/mirror/plan/plan-command.js.map +1 -0
  142. package/dist/mirror/plan/plan-file.d.ts +13 -0
  143. package/dist/mirror/plan/plan-file.d.ts.map +1 -0
  144. package/dist/mirror/plan/plan-file.js +63 -0
  145. package/dist/mirror/plan/plan-file.js.map +1 -0
  146. package/dist/mirror/plan/resolve-content-set.d.ts +16 -0
  147. package/dist/mirror/plan/resolve-content-set.d.ts.map +1 -0
  148. package/dist/mirror/plan/resolve-content-set.js +90 -0
  149. package/dist/mirror/plan/resolve-content-set.js.map +1 -0
  150. package/dist/mirror/preflight/glob.d.ts +2 -0
  151. package/dist/mirror/preflight/glob.d.ts.map +1 -0
  152. package/dist/mirror/preflight/glob.js +59 -0
  153. package/dist/mirror/preflight/glob.js.map +1 -0
  154. package/dist/mirror/preflight/harbor-api.d.ts +27 -0
  155. package/dist/mirror/preflight/harbor-api.d.ts.map +1 -0
  156. package/dist/mirror/preflight/harbor-api.js +39 -0
  157. package/dist/mirror/preflight/harbor-api.js.map +1 -0
  158. package/dist/mirror/preflight/preflight.d.ts +18 -0
  159. package/dist/mirror/preflight/preflight.d.ts.map +1 -0
  160. package/dist/mirror/preflight/preflight.js +41 -0
  161. package/dist/mirror/preflight/preflight.js.map +1 -0
  162. package/dist/mirror/preflight/tag-moves.d.ts +16 -0
  163. package/dist/mirror/preflight/tag-moves.d.ts.map +1 -0
  164. package/dist/mirror/preflight/tag-moves.js +28 -0
  165. package/dist/mirror/preflight/tag-moves.js.map +1 -0
  166. package/dist/mirror/preflight/write-probe.d.ts +10 -0
  167. package/dist/mirror/preflight/write-probe.d.ts.map +1 -0
  168. package/dist/mirror/preflight/write-probe.js +36 -0
  169. package/dist/mirror/preflight/write-probe.js.map +1 -0
  170. package/dist/mirror/target/extras.d.ts +16 -0
  171. package/dist/mirror/target/extras.d.ts.map +1 -0
  172. package/dist/mirror/target/extras.js +47 -0
  173. package/dist/mirror/target/extras.js.map +1 -0
  174. package/dist/mirror/target/npm-registry.d.ts +20 -0
  175. package/dist/mirror/target/npm-registry.d.ts.map +1 -0
  176. package/dist/mirror/target/npm-registry.js +67 -0
  177. package/dist/mirror/target/npm-registry.js.map +1 -0
  178. package/dist/mirror/target/npm-sync.d.ts +15 -0
  179. package/dist/mirror/target/npm-sync.d.ts.map +1 -0
  180. package/dist/mirror/target/npm-sync.js +44 -0
  181. package/dist/mirror/target/npm-sync.js.map +1 -0
  182. package/dist/mirror/target/oci-items.d.ts +27 -0
  183. package/dist/mirror/target/oci-items.d.ts.map +1 -0
  184. package/dist/mirror/target/oci-items.js +79 -0
  185. package/dist/mirror/target/oci-items.js.map +1 -0
  186. package/dist/mirror/target/oci-sync.d.ts +20 -0
  187. package/dist/mirror/target/oci-sync.d.ts.map +1 -0
  188. package/dist/mirror/target/oci-sync.js +93 -0
  189. package/dist/mirror/target/oci-sync.js.map +1 -0
  190. package/dist/mirror/target/receipt-store.d.ts +13 -0
  191. package/dist/mirror/target/receipt-store.d.ts.map +1 -0
  192. package/dist/mirror/target/receipt-store.js +61 -0
  193. package/dist/mirror/target/receipt-store.js.map +1 -0
  194. package/dist/mirror/target/receipt.d.ts +13 -0
  195. package/dist/mirror/target/receipt.d.ts.map +1 -0
  196. package/dist/mirror/target/receipt.js +25 -0
  197. package/dist/mirror/target/receipt.js.map +1 -0
  198. package/dist/mirror/target/seed-push.d.ts +15 -0
  199. package/dist/mirror/target/seed-push.d.ts.map +1 -0
  200. package/dist/mirror/target/seed-push.js +20 -0
  201. package/dist/mirror/target/seed-push.js.map +1 -0
  202. package/dist/mirror/target/target-access.d.ts +7 -0
  203. package/dist/mirror/target/target-access.d.ts.map +1 -0
  204. package/dist/mirror/target/target-access.js +17 -0
  205. package/dist/mirror/target/target-access.js.map +1 -0
  206. package/dist/mirror/target/target-commands.d.ts +21 -0
  207. package/dist/mirror/target/target-commands.d.ts.map +1 -0
  208. package/dist/mirror/target/target-commands.js +134 -0
  209. package/dist/mirror/target/target-commands.js.map +1 -0
  210. package/dist/mirror/target/target-context.d.ts +11 -0
  211. package/dist/mirror/target/target-context.d.ts.map +1 -0
  212. package/dist/mirror/target/target-context.js +31 -0
  213. package/dist/mirror/target/target-context.js.map +1 -0
  214. package/dist/mirror/target/target-ports.d.ts +18 -0
  215. package/dist/mirror/target/target-ports.d.ts.map +1 -0
  216. package/dist/mirror/target/target-ports.js +49 -0
  217. package/dist/mirror/target/target-ports.js.map +1 -0
  218. package/dist/mirror/target/target-state.d.ts +22 -0
  219. package/dist/mirror/target/target-state.d.ts.map +1 -0
  220. package/dist/mirror/target/target-state.js +41 -0
  221. package/dist/mirror/target/target-state.js.map +1 -0
  222. package/dist/runtime/biome-dev.d.ts +0 -16
  223. package/dist/runtime/biome-dev.d.ts.map +1 -1
  224. package/dist/runtime/biome-dev.js +0 -53
  225. package/dist/runtime/biome-dev.js.map +1 -1
  226. package/dist/runtime/biome-host/biome-directory-packer.d.ts +3 -0
  227. package/dist/runtime/biome-host/biome-directory-packer.d.ts.map +1 -0
  228. package/dist/runtime/biome-host/biome-directory-packer.js +12 -0
  229. package/dist/runtime/biome-host/biome-directory-packer.js.map +1 -0
  230. package/dist/runtime/biome-host/bundle-packer.d.ts +8 -0
  231. package/dist/runtime/biome-host/bundle-packer.d.ts.map +1 -0
  232. package/dist/runtime/biome-host/bundle-packer.js +3 -0
  233. package/dist/runtime/biome-host/bundle-packer.js.map +1 -0
  234. package/dist/runtime/biome-host/from-spec.d.ts +33 -0
  235. package/dist/runtime/biome-host/from-spec.d.ts.map +1 -0
  236. package/dist/runtime/biome-host/from-spec.js +70 -0
  237. package/dist/runtime/biome-host/from-spec.js.map +1 -0
  238. package/dist/runtime/biome-host/lifecycle-client.d.ts +20 -0
  239. package/dist/runtime/biome-host/lifecycle-client.d.ts.map +1 -0
  240. package/dist/runtime/biome-host/lifecycle-client.js +197 -0
  241. package/dist/runtime/biome-host/lifecycle-client.js.map +1 -0
  242. package/dist/runtime/biome-host/lifecycle-contract.d.ts +95 -0
  243. package/dist/runtime/biome-host/lifecycle-contract.d.ts.map +1 -0
  244. package/dist/runtime/biome-host/lifecycle-contract.js +61 -0
  245. package/dist/runtime/biome-host/lifecycle-contract.js.map +1 -0
  246. package/dist/runtime/biome-host/lifecycle-flow.d.ts +29 -0
  247. package/dist/runtime/biome-host/lifecycle-flow.d.ts.map +1 -0
  248. package/dist/runtime/biome-host/lifecycle-flow.js +106 -0
  249. package/dist/runtime/biome-host/lifecycle-flow.js.map +1 -0
  250. package/dist/runtime/biome-host/plan-sources.d.ts +4 -0
  251. package/dist/runtime/biome-host/plan-sources.d.ts.map +1 -0
  252. package/dist/runtime/biome-host/plan-sources.js +26 -0
  253. package/dist/runtime/biome-host/plan-sources.js.map +1 -0
  254. package/dist/runtime/biome-host/relay/bundle-fetch.d.ts +12 -0
  255. package/dist/runtime/biome-host/relay/bundle-fetch.d.ts.map +1 -0
  256. package/dist/runtime/biome-host/relay/bundle-fetch.js +76 -0
  257. package/dist/runtime/biome-host/relay/bundle-fetch.js.map +1 -0
  258. package/dist/runtime/biome-host/relay/declared-scheme.d.ts +3 -0
  259. package/dist/runtime/biome-host/relay/declared-scheme.d.ts.map +1 -0
  260. package/dist/runtime/biome-host/relay/declared-scheme.js +14 -0
  261. package/dist/runtime/biome-host/relay/declared-scheme.js.map +1 -0
  262. package/dist/runtime/biome-host/relay/npm-token.d.ts +4 -0
  263. package/dist/runtime/biome-host/relay/npm-token.d.ts.map +1 -0
  264. package/dist/runtime/biome-host/relay/npm-token.js +16 -0
  265. package/dist/runtime/biome-host/relay/npm-token.js.map +1 -0
  266. package/dist/runtime/biome-host/relay/relay-flow.d.ts +16 -0
  267. package/dist/runtime/biome-host/relay/relay-flow.d.ts.map +1 -0
  268. package/dist/runtime/biome-host/relay/relay-flow.js +48 -0
  269. package/dist/runtime/biome-host/relay/relay-flow.js.map +1 -0
  270. package/dist/runtime/biome-host/source-staging.d.ts +17 -0
  271. package/dist/runtime/biome-host/source-staging.d.ts.map +1 -0
  272. package/dist/runtime/biome-host/source-staging.js +80 -0
  273. package/dist/runtime/biome-host/source-staging.js.map +1 -0
  274. package/dist/runtime/biome-host/sse.d.ts +2 -0
  275. package/dist/runtime/biome-host/sse.d.ts.map +1 -0
  276. package/dist/runtime/biome-host/sse.js +33 -0
  277. package/dist/runtime/biome-host/sse.js.map +1 -0
  278. package/dist/runtime/biome-local-install.js +1 -1
  279. package/dist/runtime/biome-local-install.js.map +1 -1
  280. package/dist/runtime/browser-origins.d.ts +9 -0
  281. package/dist/runtime/browser-origins.d.ts.map +1 -1
  282. package/dist/runtime/browser-origins.js +10 -0
  283. package/dist/runtime/browser-origins.js.map +1 -1
  284. package/dist/runtime/config/config-document.d.ts +10 -0
  285. package/dist/runtime/config/config-document.d.ts.map +1 -0
  286. package/dist/runtime/config/config-document.js +56 -0
  287. package/dist/runtime/config/config-document.js.map +1 -0
  288. package/dist/runtime/config/config-migrations.d.ts +21 -0
  289. package/dist/runtime/config/config-migrations.d.ts.map +1 -0
  290. package/dist/runtime/config/config-migrations.js +102 -0
  291. package/dist/runtime/config/config-migrations.js.map +1 -0
  292. package/dist/runtime/config/config-paths.d.ts +3 -0
  293. package/dist/runtime/config/config-paths.d.ts.map +1 -0
  294. package/dist/runtime/config/config-paths.js +9 -0
  295. package/dist/runtime/config/config-paths.js.map +1 -0
  296. package/dist/runtime/config/dev-mode.d.ts +0 -1
  297. package/dist/runtime/config/dev-mode.d.ts.map +1 -1
  298. package/dist/runtime/config/dev-mode.js +11 -27
  299. package/dist/runtime/config/dev-mode.js.map +1 -1
  300. package/dist/runtime/config/init-presets.js +5 -9
  301. package/dist/runtime/config/init-presets.js.map +1 -1
  302. package/dist/runtime/config/launch-config-help.d.ts +4 -0
  303. package/dist/runtime/config/launch-config-help.d.ts.map +1 -0
  304. package/dist/runtime/config/launch-config-help.js +42 -0
  305. package/dist/runtime/config/launch-config-help.js.map +1 -0
  306. package/dist/runtime/config/launch-config.d.ts +60 -0
  307. package/dist/runtime/config/launch-config.d.ts.map +1 -0
  308. package/dist/runtime/config/launch-config.js +123 -0
  309. package/dist/runtime/config/launch-config.js.map +1 -0
  310. package/dist/runtime/config/launch-schema.d.ts +18 -0
  311. package/dist/runtime/config/launch-schema.d.ts.map +1 -0
  312. package/dist/runtime/config/launch-schema.js +31 -0
  313. package/dist/runtime/config/launch-schema.js.map +1 -0
  314. package/dist/runtime/config/loader.d.ts.map +1 -1
  315. package/dist/runtime/config/loader.js +4 -14
  316. package/dist/runtime/config/loader.js.map +1 -1
  317. package/dist/runtime/config/schema.d.ts +43 -38
  318. package/dist/runtime/config/schema.d.ts.map +1 -1
  319. package/dist/runtime/config/schema.js +17 -46
  320. package/dist/runtime/config/schema.js.map +1 -1
  321. package/dist/runtime/config/sources-config.d.ts +0 -2
  322. package/dist/runtime/config/sources-config.d.ts.map +1 -1
  323. package/dist/runtime/config/sources-config.js +10 -29
  324. package/dist/runtime/config/sources-config.js.map +1 -1
  325. package/dist/runtime/config/versioned-document.d.ts +26 -0
  326. package/dist/runtime/config/versioned-document.d.ts.map +1 -0
  327. package/dist/runtime/config/versioned-document.js +87 -0
  328. package/dist/runtime/config/versioned-document.js.map +1 -0
  329. package/dist/runtime/directory-changes.d.ts +12 -0
  330. package/dist/runtime/directory-changes.d.ts.map +1 -0
  331. package/dist/runtime/directory-changes.js +62 -0
  332. package/dist/runtime/directory-changes.js.map +1 -0
  333. package/dist/runtime/foreground.d.ts +2 -0
  334. package/dist/runtime/foreground.d.ts.map +1 -1
  335. package/dist/runtime/foreground.js +5 -20
  336. package/dist/runtime/foreground.js.map +1 -1
  337. package/dist/runtime/infra/infra-runner.js +5 -5
  338. package/dist/runtime/infra/infra-runner.js.map +1 -1
  339. package/dist/runtime/infra/keycloak-realm.d.ts +3 -19
  340. package/dist/runtime/infra/keycloak-realm.d.ts.map +1 -1
  341. package/dist/runtime/infra/keycloak-realm.js +12 -133
  342. package/dist/runtime/infra/keycloak-realm.js.map +1 -1
  343. package/dist/runtime/installation/current-launcher-renderer.js.map +1 -1
  344. package/dist/runtime/installation/from-current-config.d.ts.map +1 -1
  345. package/dist/runtime/installation/from-current-config.js +24 -47
  346. package/dist/runtime/installation/from-current-config.js.map +1 -1
  347. package/dist/runtime/installation/index.d.ts +1 -0
  348. package/dist/runtime/installation/index.d.ts.map +1 -1
  349. package/dist/runtime/installation/index.js +1 -0
  350. package/dist/runtime/installation/index.js.map +1 -1
  351. package/dist/runtime/installation/installation-file.d.ts +3 -0
  352. package/dist/runtime/installation/installation-file.d.ts.map +1 -0
  353. package/dist/runtime/installation/installation-file.js +9 -0
  354. package/dist/runtime/installation/installation-file.js.map +1 -0
  355. package/dist/runtime/installation/readiness.d.ts +6 -7
  356. package/dist/runtime/installation/readiness.d.ts.map +1 -1
  357. package/dist/runtime/installation/readiness.js +82 -132
  358. package/dist/runtime/installation/readiness.js.map +1 -1
  359. package/dist/runtime/installation/state-store.d.ts +4 -0
  360. package/dist/runtime/installation/state-store.d.ts.map +1 -1
  361. package/dist/runtime/installation/state-store.js +22 -1
  362. package/dist/runtime/installation/state-store.js.map +1 -1
  363. package/dist/runtime/installation/to-current-config.d.ts +4 -1
  364. package/dist/runtime/installation/to-current-config.d.ts.map +1 -1
  365. package/dist/runtime/installation/to-current-config.js +10 -36
  366. package/dist/runtime/installation/to-current-config.js.map +1 -1
  367. package/dist/runtime/launch-plan-format.d.ts.map +1 -1
  368. package/dist/runtime/launch-plan-format.js +31 -6
  369. package/dist/runtime/launch-plan-format.js.map +1 -1
  370. package/dist/runtime/launch-result.d.ts +15 -0
  371. package/dist/runtime/launch-result.d.ts.map +1 -0
  372. package/dist/runtime/launch-result.js +3 -0
  373. package/dist/runtime/launch-result.js.map +1 -0
  374. package/dist/runtime/launch.d.ts +16 -5
  375. package/dist/runtime/launch.d.ts.map +1 -1
  376. package/dist/runtime/launch.js +151 -315
  377. package/dist/runtime/launch.js.map +1 -1
  378. package/dist/runtime/license/helm-pull-secret.d.ts +1 -1
  379. package/dist/runtime/license/helm-pull-secret.d.ts.map +1 -1
  380. package/dist/runtime/license/helm-pull-secret.js +2 -2
  381. package/dist/runtime/license/helm-pull-secret.js.map +1 -1
  382. package/dist/runtime/lifecycle-progress/index.d.ts +9 -0
  383. package/dist/runtime/lifecycle-progress/index.d.ts.map +1 -0
  384. package/dist/runtime/lifecycle-progress/index.js +30 -0
  385. package/dist/runtime/lifecycle-progress/index.js.map +1 -0
  386. package/dist/runtime/lifecycle-progress/json-renderer.d.ts +3 -0
  387. package/dist/runtime/lifecycle-progress/json-renderer.d.ts.map +1 -0
  388. package/dist/runtime/lifecycle-progress/json-renderer.js +27 -0
  389. package/dist/runtime/lifecycle-progress/json-renderer.js.map +1 -0
  390. package/dist/runtime/lifecycle-progress/text-renderer.d.ts +5 -0
  391. package/dist/runtime/lifecycle-progress/text-renderer.d.ts.map +1 -0
  392. package/dist/runtime/lifecycle-progress/text-renderer.js +83 -0
  393. package/dist/runtime/lifecycle-progress/text-renderer.js.map +1 -0
  394. package/dist/runtime/lifecycle-progress/types.d.ts +79 -0
  395. package/dist/runtime/lifecycle-progress/types.d.ts.map +1 -0
  396. package/dist/runtime/lifecycle-progress/types.js +32 -0
  397. package/dist/runtime/lifecycle-progress/types.js.map +1 -0
  398. package/dist/runtime/lock-loader.d.ts +13 -3
  399. package/dist/runtime/lock-loader.d.ts.map +1 -1
  400. package/dist/runtime/lock-loader.js +28 -8
  401. package/dist/runtime/lock-loader.js.map +1 -1
  402. package/dist/runtime/paths.d.ts +2 -0
  403. package/dist/runtime/paths.d.ts.map +1 -1
  404. package/dist/runtime/paths.js +17 -4
  405. package/dist/runtime/paths.js.map +1 -1
  406. package/dist/runtime/roster.d.ts +6 -5
  407. package/dist/runtime/roster.d.ts.map +1 -1
  408. package/dist/runtime/roster.js +0 -21
  409. package/dist/runtime/roster.js.map +1 -1
  410. package/dist/runtime/runner/container-preflight.d.ts +3 -2
  411. package/dist/runtime/runner/container-preflight.d.ts.map +1 -1
  412. package/dist/runtime/runner/container-preflight.js +5 -5
  413. package/dist/runtime/runner/container-preflight.js.map +1 -1
  414. package/dist/runtime/runner/container-runner.d.ts +0 -22
  415. package/dist/runtime/runner/container-runner.d.ts.map +1 -1
  416. package/dist/runtime/runner/container-runner.js +0 -112
  417. package/dist/runtime/runner/container-runner.js.map +1 -1
  418. package/dist/runtime/runner/docker-cli.d.ts +1 -0
  419. package/dist/runtime/runner/docker-cli.d.ts.map +1 -1
  420. package/dist/runtime/runner/docker-cli.js +19 -0
  421. package/dist/runtime/runner/docker-cli.js.map +1 -1
  422. package/dist/runtime/runner/helm-cli.d.ts +1 -0
  423. package/dist/runtime/runner/helm-cli.d.ts.map +1 -1
  424. package/dist/runtime/runner/helm-cli.js +5 -1
  425. package/dist/runtime/runner/helm-cli.js.map +1 -1
  426. package/dist/runtime/runner/helm-pre-install.d.ts +3 -2
  427. package/dist/runtime/runner/helm-pre-install.d.ts.map +1 -1
  428. package/dist/runtime/runner/helm-pre-install.js +3 -3
  429. package/dist/runtime/runner/helm-pre-install.js.map +1 -1
  430. package/dist/runtime/runner/helm-runner.d.ts +29 -4
  431. package/dist/runtime/runner/helm-runner.d.ts.map +1 -1
  432. package/dist/runtime/runner/helm-runner.js +44 -14
  433. package/dist/runtime/runner/helm-runner.js.map +1 -1
  434. package/dist/runtime/runner/kube-cli.d.ts +1 -0
  435. package/dist/runtime/runner/kube-cli.d.ts.map +1 -1
  436. package/dist/runtime/runner/kube-cli.js +24 -2
  437. package/dist/runtime/runner/kube-cli.js.map +1 -1
  438. package/dist/runtime/secrets/managed-local-key-provider.d.ts +2 -0
  439. package/dist/runtime/secrets/managed-local-key-provider.d.ts.map +1 -1
  440. package/dist/runtime/secrets/managed-local-key-provider.js +17 -8
  441. package/dist/runtime/secrets/managed-local-key-provider.js.map +1 -1
  442. package/dist/runtime/seed/closure-container.d.ts +8 -0
  443. package/dist/runtime/seed/closure-container.d.ts.map +1 -0
  444. package/dist/runtime/seed/closure-container.js +23 -0
  445. package/dist/runtime/seed/closure-container.js.map +1 -0
  446. package/dist/runtime/seed/closure-helm.d.ts +9 -0
  447. package/dist/runtime/seed/closure-helm.d.ts.map +1 -0
  448. package/dist/runtime/seed/closure-helm.js +16 -0
  449. package/dist/runtime/seed/closure-helm.js.map +1 -0
  450. package/dist/runtime/seed/closure-names.d.ts +4 -0
  451. package/dist/runtime/seed/closure-names.d.ts.map +1 -0
  452. package/dist/runtime/seed/closure-names.js +29 -0
  453. package/dist/runtime/seed/closure-names.js.map +1 -0
  454. package/dist/runtime/seed/closure-native.d.ts +3 -0
  455. package/dist/runtime/seed/closure-native.d.ts.map +1 -0
  456. package/dist/runtime/seed/closure-native.js +18 -0
  457. package/dist/runtime/seed/closure-native.js.map +1 -0
  458. package/dist/runtime/seed/installation-tar.d.ts +5 -0
  459. package/dist/runtime/seed/installation-tar.d.ts.map +1 -0
  460. package/dist/runtime/seed/installation-tar.js +30 -0
  461. package/dist/runtime/seed/installation-tar.js.map +1 -0
  462. package/dist/runtime/seed/launch-env.d.ts +42 -0
  463. package/dist/runtime/seed/launch-env.d.ts.map +1 -0
  464. package/dist/runtime/seed/launch-env.js +150 -0
  465. package/dist/runtime/seed/launch-env.js.map +1 -0
  466. package/dist/runtime/seed/seed-container.d.ts +13 -0
  467. package/dist/runtime/seed/seed-container.d.ts.map +1 -0
  468. package/dist/runtime/seed/seed-container.js +175 -0
  469. package/dist/runtime/seed/seed-container.js.map +1 -0
  470. package/dist/runtime/seed/seed-delivery-env.d.ts +39 -0
  471. package/dist/runtime/seed/seed-delivery-env.d.ts.map +1 -0
  472. package/dist/runtime/seed/seed-delivery-env.js +47 -0
  473. package/dist/runtime/seed/seed-delivery-env.js.map +1 -0
  474. package/dist/runtime/seed/seed-down.d.ts +2 -0
  475. package/dist/runtime/seed/seed-down.d.ts.map +1 -0
  476. package/dist/runtime/seed/seed-down.js +52 -0
  477. package/dist/runtime/seed/seed-down.js.map +1 -0
  478. package/dist/runtime/seed/seed-env-file.d.ts +3 -0
  479. package/dist/runtime/seed/seed-env-file.d.ts.map +1 -0
  480. package/dist/runtime/seed/seed-env-file.js +24 -0
  481. package/dist/runtime/seed/seed-env-file.js.map +1 -0
  482. package/dist/runtime/seed/seed-env-secret.d.ts +18 -0
  483. package/dist/runtime/seed/seed-env-secret.d.ts.map +1 -0
  484. package/dist/runtime/seed/seed-env-secret.js +62 -0
  485. package/dist/runtime/seed/seed-env-secret.js.map +1 -0
  486. package/dist/runtime/seed/seed-environment.d.ts +12 -0
  487. package/dist/runtime/seed/seed-environment.d.ts.map +1 -0
  488. package/dist/runtime/seed/seed-environment.js +66 -0
  489. package/dist/runtime/seed/seed-environment.js.map +1 -0
  490. package/dist/runtime/seed/seed-facts.d.ts +22 -0
  491. package/dist/runtime/seed/seed-facts.d.ts.map +1 -0
  492. package/dist/runtime/seed/seed-facts.js +40 -0
  493. package/dist/runtime/seed/seed-facts.js.map +1 -0
  494. package/dist/runtime/seed/seed-helm.d.ts +10 -0
  495. package/dist/runtime/seed/seed-helm.d.ts.map +1 -0
  496. package/dist/runtime/seed/seed-helm.js +74 -0
  497. package/dist/runtime/seed/seed-helm.js.map +1 -0
  498. package/dist/runtime/seed/seed-image-user.d.ts +6 -0
  499. package/dist/runtime/seed/seed-image-user.d.ts.map +1 -0
  500. package/dist/runtime/seed/seed-image-user.js +14 -0
  501. package/dist/runtime/seed/seed-image-user.js.map +1 -0
  502. package/dist/runtime/seed/seed-installation-files.d.ts +23 -0
  503. package/dist/runtime/seed/seed-installation-files.d.ts.map +1 -0
  504. package/dist/runtime/seed/seed-installation-files.js +51 -0
  505. package/dist/runtime/seed/seed-installation-files.js.map +1 -0
  506. package/dist/runtime/seed/seed-installation.d.ts +20 -0
  507. package/dist/runtime/seed/seed-installation.d.ts.map +1 -0
  508. package/dist/runtime/seed/seed-installation.js +36 -0
  509. package/dist/runtime/seed/seed-installation.js.map +1 -0
  510. package/dist/runtime/seed/seed-launcher.d.ts +14 -0
  511. package/dist/runtime/seed/seed-launcher.d.ts.map +1 -0
  512. package/dist/runtime/seed/seed-launcher.js +155 -0
  513. package/dist/runtime/seed/seed-launcher.js.map +1 -0
  514. package/dist/runtime/seed/seed-options.d.ts +22 -0
  515. package/dist/runtime/seed/seed-options.d.ts.map +1 -0
  516. package/dist/runtime/seed/seed-options.js +57 -0
  517. package/dist/runtime/seed/seed-options.js.map +1 -0
  518. package/dist/runtime/seed/seed-platform-endpoints.d.ts +8 -0
  519. package/dist/runtime/seed/seed-platform-endpoints.d.ts.map +1 -0
  520. package/dist/runtime/seed/seed-platform-endpoints.js +55 -0
  521. package/dist/runtime/seed/seed-platform-endpoints.js.map +1 -0
  522. package/dist/runtime/seed/seed-process.d.ts +22 -0
  523. package/dist/runtime/seed/seed-process.d.ts.map +1 -0
  524. package/dist/runtime/seed/seed-process.js +79 -0
  525. package/dist/runtime/seed/seed-process.js.map +1 -0
  526. package/dist/runtime/seed/seed-record.d.ts +101 -0
  527. package/dist/runtime/seed/seed-record.d.ts.map +1 -0
  528. package/dist/runtime/seed/seed-record.js +141 -0
  529. package/dist/runtime/seed/seed-record.js.map +1 -0
  530. package/dist/runtime/seed/seed-resolved-deployment.d.ts +14 -0
  531. package/dist/runtime/seed/seed-resolved-deployment.d.ts.map +1 -0
  532. package/dist/runtime/seed/seed-resolved-deployment.js +52 -0
  533. package/dist/runtime/seed/seed-resolved-deployment.js.map +1 -0
  534. package/dist/runtime/seed/substrate-facts.d.ts +52 -0
  535. package/dist/runtime/seed/substrate-facts.d.ts.map +1 -0
  536. package/dist/runtime/seed/substrate-facts.js +92 -0
  537. package/dist/runtime/seed/substrate-facts.js.map +1 -0
  538. package/dist/runtime/seed/supervisor-contract.d.ts +9 -0
  539. package/dist/runtime/seed/supervisor-contract.d.ts.map +1 -0
  540. package/dist/runtime/seed/supervisor-contract.js +68 -0
  541. package/dist/runtime/seed/supervisor-contract.js.map +1 -0
  542. package/dist/runtime/seed/workload-identity-facts.d.ts +17 -0
  543. package/dist/runtime/seed/workload-identity-facts.d.ts.map +1 -0
  544. package/dist/runtime/seed/workload-identity-facts.js +53 -0
  545. package/dist/runtime/seed/workload-identity-facts.js.map +1 -0
  546. package/dist/runtime/sources/schema.d.ts +2 -0
  547. package/dist/runtime/sources/schema.d.ts.map +1 -1
  548. package/dist/runtime/sources/schema.js +10 -9
  549. package/dist/runtime/sources/schema.js.map +1 -1
  550. package/dist/runtime/store-client.d.ts +0 -10
  551. package/dist/runtime/store-client.d.ts.map +1 -1
  552. package/dist/runtime/store-client.js +0 -5
  553. package/dist/runtime/store-client.js.map +1 -1
  554. package/dist/runtime/tenancy/identity-installer.d.ts +11 -0
  555. package/dist/runtime/tenancy/identity-installer.d.ts.map +1 -0
  556. package/dist/runtime/tenancy/identity-installer.js +39 -0
  557. package/dist/runtime/tenancy/identity-installer.js.map +1 -0
  558. package/dist/runtime/tenancy/import-cache.d.ts +5 -0
  559. package/dist/runtime/tenancy/import-cache.d.ts.map +1 -0
  560. package/dist/runtime/tenancy/import-cache.js +27 -0
  561. package/dist/runtime/tenancy/import-cache.js.map +1 -0
  562. package/dist/runtime/tenancy/openfga.d.ts +4 -0
  563. package/dist/runtime/tenancy/openfga.d.ts.map +1 -0
  564. package/dist/runtime/tenancy/openfga.js +29 -0
  565. package/dist/runtime/tenancy/openfga.js.map +1 -0
  566. package/dist/runtime/tenancy/servers.d.ts +18 -0
  567. package/dist/runtime/tenancy/servers.d.ts.map +1 -0
  568. package/dist/runtime/tenancy/servers.js +102 -0
  569. package/dist/runtime/tenancy/servers.js.map +1 -0
  570. package/dist/runtime/tenancy/session.d.ts +19 -0
  571. package/dist/runtime/tenancy/session.d.ts.map +1 -0
  572. package/dist/runtime/tenancy/session.js +79 -0
  573. package/dist/runtime/tenancy/session.js.map +1 -0
  574. package/dist/runtime/tenancy/specs.d.ts +27 -0
  575. package/dist/runtime/tenancy/specs.d.ts.map +1 -0
  576. package/dist/runtime/tenancy/specs.js +129 -0
  577. package/dist/runtime/tenancy/specs.js.map +1 -0
  578. package/examples/01-local-native.yaml +1 -3
  579. package/examples/02-local-container-full.yaml +0 -2
  580. package/examples/03-byo-infra.yaml +1 -5
  581. package/examples/06-biome-sources.yaml +1 -3
  582. package/package.json +32 -37
  583. package/xema.config.example.yaml +1 -10
  584. package/dist/assets/keycloak/realm-xema.json +0 -397
  585. package/dist/commands/dev.d.ts.map +0 -1
  586. package/dist/commands/dev.js +0 -196
  587. package/dist/commands/dev.js.map +0 -1
  588. package/dist/commands/edition.d.ts +0 -3
  589. package/dist/commands/edition.d.ts.map +0 -1
  590. package/dist/commands/edition.js +0 -54
  591. package/dist/commands/edition.js.map +0 -1
  592. package/dist/commands/serve.d.ts +0 -3
  593. package/dist/commands/serve.d.ts.map +0 -1
  594. package/dist/commands/serve.js +0 -114
  595. package/dist/commands/serve.js.map +0 -1
  596. package/dist/dev/carved-installs.d.ts +0 -3
  597. package/dist/dev/carved-installs.d.ts.map +0 -1
  598. package/dist/dev/carved-installs.js +0 -63
  599. package/dist/dev/carved-installs.js.map +0 -1
  600. package/dist/dev/env-defaults.d.ts +0 -15
  601. package/dist/dev/env-defaults.d.ts.map +0 -1
  602. package/dist/dev/env-defaults.js +0 -178
  603. package/dist/dev/env-defaults.js.map +0 -1
  604. package/dist/dev/forked-worker-bootstrap-protocol.d.ts +0 -17
  605. package/dist/dev/forked-worker-bootstrap-protocol.d.ts.map +0 -1
  606. package/dist/dev/forked-worker-bootstrap-protocol.js +0 -35
  607. package/dist/dev/forked-worker-bootstrap-protocol.js.map +0 -1
  608. package/dist/dev/forked-worker-bootstrap.d.ts +0 -18
  609. package/dist/dev/forked-worker-bootstrap.d.ts.map +0 -1
  610. package/dist/dev/forked-worker-bootstrap.js +0 -84
  611. package/dist/dev/forked-worker-bootstrap.js.map +0 -1
  612. package/dist/dev/forked-worker.d.ts +0 -43
  613. package/dist/dev/forked-worker.d.ts.map +0 -1
  614. package/dist/dev/forked-worker.js +0 -358
  615. package/dist/dev/forked-worker.js.map +0 -1
  616. package/dist/edition/verify-image-evidence.bundle.mjs +0 -70456
  617. package/dist/edition/verify-image-evidence.bundle.provenance.json +0 -3957
  618. package/dist/runtime/backing-registration.d.ts +0 -11
  619. package/dist/runtime/backing-registration.d.ts.map +0 -1
  620. package/dist/runtime/backing-registration.js +0 -94
  621. package/dist/runtime/backing-registration.js.map +0 -1
  622. package/dist/runtime/edition/run-entry.d.ts +0 -9
  623. package/dist/runtime/edition/run-entry.d.ts.map +0 -1
  624. package/dist/runtime/edition/run-entry.js +0 -36
  625. package/dist/runtime/edition/run-entry.js.map +0 -1
  626. package/dist/runtime/edition/verb-map.d.ts +0 -70
  627. package/dist/runtime/edition/verb-map.d.ts.map +0 -1
  628. package/dist/runtime/edition/verb-map.js +0 -166
  629. package/dist/runtime/edition/verb-map.js.map +0 -1
  630. package/dist/runtime/env-seeder.d.ts +0 -26
  631. package/dist/runtime/env-seeder.d.ts.map +0 -1
  632. package/dist/runtime/env-seeder.js +0 -340
  633. package/dist/runtime/env-seeder.js.map +0 -1
  634. package/dist/runtime/port-map.d.ts +0 -3
  635. package/dist/runtime/port-map.d.ts.map +0 -1
  636. package/dist/runtime/port-map.js +0 -25
  637. package/dist/runtime/port-map.js.map +0 -1
  638. package/dist/runtime/run-manifest.d.ts +0 -52
  639. package/dist/runtime/run-manifest.d.ts.map +0 -1
  640. package/dist/runtime/run-manifest.js +0 -585
  641. package/dist/runtime/run-manifest.js.map +0 -1
  642. package/dist/runtime/runner/native-runner.d.ts +0 -13
  643. package/dist/runtime/runner/native-runner.d.ts.map +0 -1
  644. package/dist/runtime/runner/native-runner.js +0 -94
  645. package/dist/runtime/runner/native-runner.js.map +0 -1
  646. package/dist/runtime/runner/service-runner.d.ts +0 -28
  647. package/dist/runtime/runner/service-runner.d.ts.map +0 -1
  648. package/dist/runtime/runner/service-runner.js +0 -10
  649. package/dist/runtime/runner/service-runner.js.map +0 -1
  650. package/dist/runtime/secrets/generated-platform-secrets.d.ts +0 -16
  651. package/dist/runtime/secrets/generated-platform-secrets.d.ts.map +0 -1
  652. package/dist/runtime/secrets/generated-platform-secrets.js +0 -115
  653. package/dist/runtime/secrets/generated-platform-secrets.js.map +0 -1
  654. package/dist/runtime/secrets/resolver.d.ts +0 -23
  655. package/dist/runtime/secrets/resolver.d.ts.map +0 -1
  656. package/dist/runtime/secrets/resolver.js +0 -266
  657. package/dist/runtime/secrets/resolver.js.map +0 -1
  658. package/dist/runtime/supervisor.d.ts +0 -67
  659. package/dist/runtime/supervisor.d.ts.map +0 -1
  660. package/dist/runtime/supervisor.js +0 -227
  661. package/dist/runtime/supervisor.js.map +0 -1
  662. package/edition/README.md +0 -293
  663. package/edition/adapter-bundled-versions.mjs +0 -108
  664. package/edition/adapter-host-versions.mjs +0 -41
  665. package/edition/assemble-producer-input.mjs +0 -1423
  666. package/edition/assemble-third-party-input.mjs +0 -336
  667. package/edition/authored-source-check.mjs +0 -135
  668. package/edition/authorization-base.mjs +0 -357
  669. package/edition/biome-content.mjs +0 -327
  670. package/edition/build-biome-index.mjs +0 -180
  671. package/edition/build-ledger-completeness.mjs +0 -67
  672. package/edition/build-ledger.mjs +0 -107
  673. package/edition/build-platform-service-index.mjs +0 -292
  674. package/edition/build-runtime-image-source-index.mjs +0 -1187
  675. package/edition/built-verifier.mjs +0 -55
  676. package/edition/candidate-edition.mjs +0 -697
  677. package/edition/canonical-evidence-json.mjs +0 -82
  678. package/edition/canonical-repository-url.mjs +0 -47
  679. package/edition/catalogue-edition.mjs +0 -49
  680. package/edition/catalogue-evidence.mjs +0 -228
  681. package/edition/catalogue-fetch.mjs +0 -124
  682. package/edition/catalogue-lock-field.mjs +0 -41
  683. package/edition/catalogue-pin.mjs +0 -71
  684. package/edition/catalogue.mjs +0 -223
  685. package/edition/chart-set-source-commit.mjs +0 -97
  686. package/edition/check-committed-image-evidence.mjs +0 -412
  687. package/edition/checkout-indexed-source-repositories.mjs +0 -283
  688. package/edition/collected-refusals.mjs +0 -59
  689. package/edition/comment-blanker.mjs +0 -75
  690. package/edition/connector-source-authority.mjs +0 -60
  691. package/edition/contract-authority.mjs +0 -122
  692. package/edition/cosign-certificate-constraints.mjs +0 -50
  693. package/edition/cross-repo-build-inputs.mjs +0 -158
  694. package/edition/customer-definition.mjs +0 -174
  695. package/edition/customer-edition-verbs.mjs +0 -617
  696. package/edition/customer-flags.mjs +0 -15
  697. package/edition/develop-catalogue-free-resolve.mjs +0 -280
  698. package/edition/develop-chart-roster.mjs +0 -96
  699. package/edition/develop-chart-set.mjs +0 -147
  700. package/edition/develop-coverage-readers.mjs +0 -217
  701. package/edition/develop-coverage-run.mjs +0 -50
  702. package/edition/develop-coverage-verdict.mjs +0 -153
  703. package/edition/develop-coverage.mjs +0 -131
  704. package/edition/develop-current-resolution.mjs +0 -29
  705. package/edition/develop-edition-invariants.mjs +0 -142
  706. package/edition/develop-edition-resolve.mjs +0 -211
  707. package/edition/develop-edition.mjs +0 -379
  708. package/edition/develop-engine-image.mjs +0 -95
  709. package/edition/develop-follow.mjs +0 -491
  710. package/edition/develop-freeze.mjs +0 -289
  711. package/edition/develop-git-bundles.mjs +0 -255
  712. package/edition/develop-graph.mjs +0 -28
  713. package/edition/develop-image-coordinate.mjs +0 -54
  714. package/edition/develop-image-probe.mjs +0 -120
  715. package/edition/develop-image-record.mjs +0 -194
  716. package/edition/develop-record-ancestry.mjs +0 -144
  717. package/edition/develop-record-verify.mjs +0 -216
  718. package/edition/develop-resolve-report.mjs +0 -159
  719. package/edition/develop-select-records.mjs +0 -172
  720. package/edition/develop-selection-line.mjs +0 -30
  721. package/edition/develop-selection-pins.mjs +0 -36
  722. package/edition/develop-snapshot-inputs.mjs +0 -93
  723. package/edition/develop-verify-image-record.mjs +0 -109
  724. package/edition/dispatched-runtime-components.mjs +0 -172
  725. package/edition/dist-check.mjs +0 -1137
  726. package/edition/distribution-evidence-set.mjs +0 -1064
  727. package/edition/distribution-paths.mjs +0 -191
  728. package/edition/edition-artifact.mjs +0 -529
  729. package/edition/edition-biome-manifests.mjs +0 -85
  730. package/edition/edition-ceiling.mjs +0 -180
  731. package/edition/edition-channel.mjs +0 -20
  732. package/edition/edition-chart-set.mjs +0 -104
  733. package/edition/edition-config.mjs +0 -374
  734. package/edition/edition-constants.mjs +0 -110
  735. package/edition/edition-contract-parse.mjs +0 -179
  736. package/edition/edition-contract.json +0 -100
  737. package/edition/edition-image-seal.mjs +0 -110
  738. package/edition/edition-kind.mjs +0 -10
  739. package/edition/edition-list.mjs +0 -35
  740. package/edition/edition-locks.mjs +0 -79
  741. package/edition/edition-pin-verbs.mjs +0 -183
  742. package/edition/edition-pin.mjs +0 -17
  743. package/edition/edition-pinned-inputs.mjs +0 -116
  744. package/edition/edition-protocol.mjs +0 -277
  745. package/edition/edition-publisher.mjs +0 -21
  746. package/edition/edition-seal.mjs +0 -257
  747. package/edition/edition-source-pins.mjs +0 -211
  748. package/edition/edition-unpin.mjs +0 -16
  749. package/edition/edition-workspace.mjs +0 -204
  750. package/edition/evidence-checkout.mjs +0 -439
  751. package/edition/evidence-grammars.mjs +0 -18
  752. package/edition/evidence-input-mode.mjs +0 -136
  753. package/edition/evidence-trust-pin.mjs +0 -380
  754. package/edition/evidence-trust-policy.mjs +0 -374
  755. package/edition/external-source-walk.mjs +0 -485
  756. package/edition/first-party-source-ids.mjs +0 -62
  757. package/edition/fleet-coordinate-finality.mjs +0 -363
  758. package/edition/fulcio-certificate-extensions.mjs +0 -231
  759. package/edition/git-json.mjs +0 -54
  760. package/edition/git-source-auth.mjs +0 -131
  761. package/edition/image-delivery-entitlement-descriptor.mjs +0 -106
  762. package/edition/image-evidence-replay-state.mjs +0 -242
  763. package/edition/image-evidence.mjs +0 -1404
  764. package/edition/image-lock-service-rows.mjs +0 -26
  765. package/edition/image-subject-identity.mjs +0 -24
  766. package/edition/images-from-record.mjs +0 -298
  767. package/edition/indexes-at-pins.mjs +0 -13
  768. package/edition/kernel-capability-domain.mjs +0 -30
  769. package/edition/kernel-contract-authority.mjs +0 -517
  770. package/edition/kernel-contract-source-path-set.mjs +0 -94
  771. package/edition/kernel-package.mjs +0 -206
  772. package/edition/kernel-protocol-choice.mjs +0 -239
  773. package/edition/kernel-signer-kind.mjs +0 -23
  774. package/edition/lib.mjs +0 -3303
  775. package/edition/locked-bundle-signer.mjs +0 -297
  776. package/edition/map-with-concurrency.mjs +0 -19
  777. package/edition/no-follow-file.mjs +0 -94
  778. package/edition/oci-evidence-verbs.mjs +0 -419
  779. package/edition/oci-image-source-evidence.mjs +0 -364
  780. package/edition/operation-grant-admission.mjs +0 -285
  781. package/edition/operation-requirements.mjs +0 -282
  782. package/edition/oras-process.mjs +0 -35
  783. package/edition/oras.mjs +0 -742
  784. package/edition/pin-source.mjs +0 -242
  785. package/edition/pinned-cosign.mjs +0 -70
  786. package/edition/plan-image-evidence-refresh.mjs +0 -427
  787. package/edition/platform-lock-readability.mjs +0 -901
  788. package/edition/platform-service-class.mjs +0 -85
  789. package/edition/platform-service-ownership.mjs +0 -88
  790. package/edition/platform-service-source-authority.mjs +0 -105
  791. package/edition/positive-closure.mjs +0 -162
  792. package/edition/previous-seal-registry.mjs +0 -149
  793. package/edition/produce-distribution-completeness-evidence.mjs +0 -318
  794. package/edition/produce-edition-catalogue-evidence.mjs +0 -252
  795. package/edition/produce-image-delivery-entitlement-evidence.mjs +0 -304
  796. package/edition/produce-image-source-evidence.mjs +0 -788
  797. package/edition/producer-evidence-bundle.mjs +0 -201
  798. package/edition/producer-evidence-index-file.mjs +0 -4
  799. package/edition/record-refused.mjs +0 -12
  800. package/edition/registry-credentials.mjs +0 -225
  801. package/edition/release-catalogue.mjs +0 -47
  802. package/edition/release-channel-guard.mjs +0 -108
  803. package/edition/release-edition-artifact.mjs +0 -152
  804. package/edition/release-edition.mjs +0 -54
  805. package/edition/remedy-command.mjs +0 -89
  806. package/edition/repin-evidence-trust.mjs +0 -109
  807. package/edition/required-resource-provider.mjs +0 -58
  808. package/edition/resolve-chart-set.mjs +0 -376
  809. package/edition/resolve-customer-edition.mjs +0 -374
  810. package/edition/resolve-distribution.mjs +0 -2639
  811. package/edition/resolve-edition.mjs +0 -192
  812. package/edition/resolve-images.mjs +0 -2351
  813. package/edition/seal-image-digests.mjs +0 -954
  814. package/edition/sealed-distribution-lock.mjs +0 -22
  815. package/edition/sealed-evidence-accept.mjs +0 -82
  816. package/edition/shallow-checkout.mjs +0 -18
  817. package/edition/sigstore-bundle-media-type.mjs +0 -4
  818. package/edition/source-authority.mjs +0 -713
  819. package/edition/source-closure.mjs +0 -115
  820. package/edition/store-publisher-trust.mjs +0 -40
  821. package/edition/strict-json.mjs +0 -121
  822. package/edition/string-order.mjs +0 -5
  823. package/edition/third-party-admission.mjs +0 -91
  824. package/edition/third-party-bundle-registry.mjs +0 -242
  825. package/edition/third-party-certificate-extensions.mjs +0 -21
  826. package/edition/third-party-image-pins.mjs +0 -41
  827. package/edition/third-party-pins-trusted.mjs +0 -24
  828. package/edition/third-party-producer-evidence.mjs +0 -76
  829. package/edition/third-party-source-check.mjs +0 -28
  830. package/edition/third-party-source-context.mjs +0 -41
  831. package/edition/third-party-source-evidence.mjs +0 -287
  832. package/edition/third-party-source-flags.mjs +0 -134
  833. package/edition/third-party-source-pins.mjs +0 -259
  834. package/edition/third-party-source-uniqueness.mjs +0 -54
  835. package/edition/third-party-source-walk.mjs +0 -115
  836. package/edition/third-party-source-writer.mjs +0 -213
  837. package/edition/third-party-subjects.mjs +0 -128
  838. package/edition/trust-policy-arming-verb.mjs +0 -60
  839. package/edition/trust-policy-arming.mjs +0 -144
  840. package/edition/trust-policy-image-ownership.mjs +0 -85
  841. package/edition/trusted-executable.mjs +0 -166
  842. package/edition/verifier-binding.mjs +0 -45
  843. package/edition/verifier-files.mjs +0 -8
  844. package/edition/verifier-kernel-schemas.mjs +0 -22
  845. package/edition/verifier-provenance.mjs +0 -64
  846. package/edition/verify-catalogue-evidence.mjs +0 -247
  847. package/edition/verify-image-evidence.mjs +0 -475
  848. package/edition/verify-image-platforms.mjs +0 -523
  849. package/edition/why.mjs +0 -56
  850. package/edition/workspace-sections.mjs +0 -276
@@ -1,1404 +0,0 @@
1
- import { execFileSync } from 'node:child_process';
2
- import { X509Certificate, createPublicKey } from 'node:crypto';
3
- import {
4
- mkdtempSync,
5
- readFileSync,
6
- realpathSync,
7
- rmSync,
8
- writeFileSync,
9
- } from 'node:fs';
10
- import { tmpdir } from 'node:os';
11
- import {
12
- isAbsolute,
13
- join,
14
- relative,
15
- resolve,
16
- sep,
17
- } from 'node:path';
18
-
19
- import { canonicalJson, canonicalJsonBytes, decodeExactUtf8, parseCanonicalJsonBytes, sha256Digest } from './canonical-evidence-json.mjs';
20
- import { certificateConstraintArgs } from './cosign-certificate-constraints.mjs';
21
- import { assertCanonicalDistributionId } from './distribution-paths.mjs';
22
- import { effectiveRepositoryPins, manifestSourcePins } from './edition-source-pins.mjs';
23
- import { SHA256_DIGEST_PATTERN } from './evidence-grammars.mjs';
24
- import { evidenceSubjectKey } from './image-subject-identity.mjs';
25
- import { assertKernelContractAuthorityEqual } from './kernel-contract-authority.mjs';
26
- import {
27
- compareStrings,
28
- validateImmutableImageLock,
29
- } from './lib.mjs';
30
- import { readBoundedNoFollowFile } from './no-follow-file.mjs';
31
- import {
32
- assertThirdPartySubjectAdmission,
33
- thirdPartySourceRepositoryPins,
34
- thirdPartySourcesByRepository,
35
- } from './third-party-admission.mjs';
36
- import { loadThirdPartySourcePins } from './third-party-source-pins.mjs';
37
- import {
38
- assertPreparedExecutable,
39
- exactExecutableOutput,
40
- prepareDigestPinnedExecutable,
41
- } from './trusted-executable.mjs';
42
-
43
- const MAX_CANONICAL_JSON_BYTES = 2 * 1024 * 1024;
44
- const MAX_STATEMENT_BYTES = 2 * 1024 * 1024;
45
- const MAX_SIGSTORE_BUNDLE_BYTES = 16 * 1024 * 1024;
46
- const MAX_TRUSTED_ROOT_BYTES = 8 * 1024 * 1024;
47
- /** The kernel's `SignerKind.OidcCertificate`: the one signer kind this verifier runs (cosign keyless). */
48
- const OIDC_CERTIFICATE_SIGNER = 'oidc-certificate';
49
- export { canonicalJson, canonicalJsonBytes, decodeExactUtf8, parseCanonicalJsonBytes, sha256Digest };
50
- export const COSIGN_ENV = Object.freeze({
51
- LANG: 'C',
52
- LC_ALL: 'C',
53
- PATH: '/usr/bin:/bin',
54
- TZ: 'UTC',
55
- });
56
-
57
-
58
- export function resolveContainedFile(root, candidate, label) {
59
- if (
60
- typeof candidate !== 'string' ||
61
- candidate.length === 0 ||
62
- isAbsolute(candidate)
63
- ) {
64
- throw new Error(`${label} must be a repository-relative path`);
65
- }
66
- const rootReal = realpathSync(root);
67
- const path = resolve(rootReal, candidate);
68
- const pathReal = realpathSync(path);
69
- const rel = relative(rootReal, pathReal);
70
- if (rel === '..' || rel.startsWith(`..${sep}`) || isAbsolute(rel)) {
71
- throw new Error(`${label} escapes its evidence root`);
72
- }
73
- return pathReal;
74
- }
75
-
76
- function readExactDescriptorFile(root, path, expectedDigest, label, maxBytes) {
77
- if (!SHA256_DIGEST_PATTERN.test(expectedDigest)) {
78
- throw new Error(`${label} has an invalid expected sha256 digest`);
79
- }
80
- const { path: resolved, bytes } = readBoundedNoFollowFile(
81
- root,
82
- path,
83
- `${label} path`,
84
- maxBytes,
85
- );
86
- const actual = sha256Digest(bytes);
87
- if (actual !== expectedDigest) {
88
- throw new Error(
89
- `${label} digest mismatch: expected ${expectedDigest}, got ${actual}`,
90
- );
91
- }
92
- return { path: resolved, bytes };
93
- }
94
-
95
- export function readCanonicalJsonFromRoot(
96
- root,
97
- path,
98
- label,
99
- maxBytes = MAX_CANONICAL_JSON_BYTES,
100
- ) {
101
- return parseCanonicalJsonBytes(
102
- readBoundedNoFollowFile(root, path, label, maxBytes).bytes,
103
- label,
104
- );
105
- }
106
-
107
- export function validatePinnedTrustedRoot(policyRoot, policy) {
108
- const trustedRootFile = readBoundedNoFollowFile(
109
- policyRoot,
110
- policy.trustedRootPath,
111
- 'trusted root',
112
- MAX_TRUSTED_ROOT_BYTES,
113
- );
114
- const { path: trustedRoot, bytes: rootBytes } = trustedRootFile;
115
- if (sha256Digest(rootBytes) !== policy.trustedRootDigest) {
116
- throw new Error('pinned Sigstore trusted-root digest mismatch');
117
- }
118
- const rootDocument = JSON.parse(
119
- decodeExactUtf8(rootBytes, 'Sigstore trusted root'),
120
- );
121
- if (
122
- rootDocument?.mediaType !==
123
- 'application/vnd.dev.sigstore.trustedroot+json;version=0.1'
124
- ) {
125
- throw new Error('Sigstore trusted root has an unsupported mediaType');
126
- }
127
- return { path: trustedRoot, bytes: rootBytes };
128
- }
129
-
130
- /** The one transparency log a CLASSIC (`.sig` / `.att`) cosign signature is entered in: Rekor v1 of the public good instance. */
131
- const CLASSIC_REKOR_BASE_URL = 'https://rekor.sigstore.dev';
132
- const STRICT_BASE64 = /^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/u;
133
-
134
- const pemOf = (label, der) => `-----BEGIN ${label}-----\n${der.toString('base64').match(/.{1,64}/gu).join('\n')}\n-----END ${label}-----\n`;
135
- const isOpen = (entry) => entry?.validFor?.end === undefined;
136
-
137
- function derOf(rawBytes, what) {
138
- if (typeof rawBytes !== 'string' || rawBytes.length === 0 || !STRICT_BASE64.test(rawBytes)) {
139
- throw new Error(`Sigstore trusted root: ${what} rawBytes is not base64 DER`);
140
- }
141
- return Buffer.from(rawBytes, 'base64');
142
- }
143
-
144
- function publicKeyPem(entry, what) {
145
- const der = derOf(entry?.publicKey?.rawBytes, what);
146
- try {
147
- createPublicKey({ key: der, format: 'der', type: 'spki' });
148
- } catch {
149
- throw new Error(`Sigstore trusted root: ${what} is not a DER SubjectPublicKeyInfo`);
150
- }
151
- return pemOf('PUBLIC KEY', der);
152
- }
153
-
154
- /**
155
- * The classic cosign trust material of the pinned Sigstore trusted root, derived deterministically from its bytes (the
156
- * output of `validatePinnedTrustedRoot`): what cosign's classic verification reads from `SIGSTORE_ROOT_FILE`,
157
- * `SIGSTORE_REKOR_PUBLIC_KEY` and `SIGSTORE_CT_LOG_PUBLIC_KEY_FILE` when it cannot take `--trusted-root` (cosign 2.6
158
- * `verify-attestation` accepts `--trusted-root` only with `--new-bundle-format`, which classic `.att` attestations are
159
- * not). Only material still open is kept (no `validFor.end`): the Fulcio certificate chains of every open certificate
160
- * authority (at least one), exactly one open Rekor v1 log (`https://rekor.sigstore.dev`; later logs carry new-format
161
- * entries only) and exactly one open CT log. Any other count is refused.
162
- *
163
- * @returns {{fulcioPem: string, rekorPem: string, ctLogPem: string}}
164
- */
165
- export function classicCosignTrustMaterial(rootBytes) {
166
- const root = JSON.parse(decodeExactUtf8(rootBytes, 'Sigstore trusted root'));
167
- const listOf = (key) => (Array.isArray(root?.[key]) ? root[key] : []);
168
- const authorities = listOf('certificateAuthorities').filter(isOpen);
169
- if (authorities.length === 0) {
170
- throw new Error('Sigstore trusted root: no open Fulcio certificate authority (certificateAuthorities without validFor.end)');
171
- }
172
- const fulcioPem = authorities
173
- .flatMap((authority, index) => {
174
- const certificates = authority?.certChain?.certificates;
175
- if (!Array.isArray(certificates) || certificates.length === 0) {
176
- throw new Error(`Sigstore trusted root: open certificate authority ${index} has no certificate chain`);
177
- }
178
- return certificates.map((certificate) => {
179
- const der = derOf(certificate?.rawBytes, `certificate authority ${index} certificate`);
180
- try {
181
- new X509Certificate(der);
182
- } catch {
183
- throw new Error(`Sigstore trusted root: certificate authority ${index} holds a certificate that is not DER X.509`);
184
- }
185
- return pemOf('CERTIFICATE', der);
186
- });
187
- })
188
- .join('');
189
- const rekor = listOf('tlogs').filter((log) => log?.baseUrl === CLASSIC_REKOR_BASE_URL && isOpen(log?.publicKey));
190
- if (rekor.length !== 1) {
191
- throw new Error(`Sigstore trusted root: ${rekor.length} open Rekor v1 logs (${CLASSIC_REKOR_BASE_URL}); exactly one is required`);
192
- }
193
- const ctLogs = listOf('ctlogs').filter((log) => isOpen(log?.publicKey));
194
- if (ctLogs.length !== 1) {
195
- throw new Error(`Sigstore trusted root: ${ctLogs.length} open CT logs (ctlogs without validFor.end); exactly one is required`);
196
- }
197
- return { fulcioPem, rekorPem: publicKeyPem(rekor[0], 'the Rekor v1 log key'), ctLogPem: publicKeyPem(ctLogs[0], 'the CT log key') };
198
- }
199
-
200
- function assertTimeWindow({ issuedAt, expiresAt, now, maxTtlSeconds, label }) {
201
- const issued = Date.parse(issuedAt);
202
- const expires = Date.parse(expiresAt);
203
- const instant = now instanceof Date ? now.getTime() : Date.parse(now);
204
- if (![issued, expires, instant].every(Number.isFinite)) {
205
- throw new Error(`${label} has an invalid time`);
206
- }
207
- if (issued > instant) {
208
- throw new Error(`${label} is not yet valid`);
209
- }
210
- if (expires <= instant) {
211
- throw new Error(`${label} is expired`);
212
- }
213
- assertProducerTtlCeiling({ issuedAt, expiresAt, maxTtlSeconds, label });
214
- }
215
-
216
- /**
217
- * The declared lifetime (`expiresAt - issuedAt`) is at most the trust policy's ceiling `maxTtlSeconds`. Held by
218
- * `verify-evidence` (through the time window above) and by the third-party pin writer, which has no `now` to hold.
219
- */
220
- export function assertProducerTtlCeiling({ issuedAt, expiresAt, maxTtlSeconds, label }) {
221
- if (!Number.isSafeInteger(maxTtlSeconds) || maxTtlSeconds < 1) {
222
- throw new Error(`${label}: the trust policy's TTL ceiling ${String(maxTtlSeconds)} is not a positive integer`);
223
- }
224
- const issued = Date.parse(issuedAt);
225
- const expires = Date.parse(expiresAt);
226
- if (![issued, expires].every(Number.isFinite)) {
227
- throw new Error(`${label} has an invalid time`);
228
- }
229
- if (expires <= issued) {
230
- throw new Error(`${label} expiresAt must be after issuedAt`);
231
- }
232
- if (expires - issued > maxTtlSeconds * 1000) {
233
- throw new Error(
234
- `${label} exceeds the trusted maximum TTL (${(expires - issued) / 1000}s declared, maxProducerTtlSeconds ${maxTtlSeconds})`,
235
- );
236
- }
237
- }
238
-
239
- export function sourceIdentity(subject) {
240
- return evidenceSubjectKey(subject);
241
- }
242
-
243
- /** Root of the committed evidence tree, in every producing repository. */
244
- export const EVIDENCE_TREE_ROOT = 'evidence';
245
-
246
- /**
247
- * The repository-relative directory a producer commits ONE subject digest's
248
- * evidence bundle to. ONE owner: the producing workflows, the reuse check and
249
- * (later) the delivery-side loader all read the name from here rather than
250
- * interpolating a digest into a path themselves.
251
- *
252
- * `sha256-<hex>`, NOT `sha256:<hex>`. `:` is illegal in an NTFS path component,
253
- * so a `sha256:`-named directory cannot be checked out on Windows at all — the
254
- * clone fails, which would make the evidence plane silently undeliverable to
255
- * any Windows operator. `sha256-<hex>` is cosign's own on-registry convention
256
- * for exactly this reason (`sha256-<digest>.att`), so the plane gains no new
257
- * vocabulary.
258
- */
259
- export function evidenceDirectoryForDigest(manifestDigest) {
260
- if (!/^sha256:[a-f0-9]{64}$/.test(manifestDigest ?? '')) {
261
- throw new Error(
262
- `evidence directory requires an exact sha256:<64-hex> manifest digest, got "${String(manifestDigest)}"`,
263
- );
264
- }
265
- return `${EVIDENCE_TREE_ROOT}/${manifestDigest.replace(':', '-')}`;
266
- }
267
-
268
- function comparePlatform(left, right) {
269
- return compareStrings(
270
- `${left.os}/${left.architecture}/${left.variant ?? ''}`,
271
- `${right.os}/${right.architecture}/${right.variant ?? ''}`,
272
- );
273
- }
274
-
275
- function platformIdentity(platform) {
276
- return `${platform.os}/${platform.architecture}/${platform.variant ?? ''}`;
277
- }
278
-
279
- function assertPlatforms(platforms, requiredPlatforms, label) {
280
- if (platforms.length === 0) {
281
- throw new Error(`${label} omits its complete platform set`);
282
- }
283
- const sorted = [...platforms].sort(comparePlatform);
284
- if (canonicalJson(platforms) !== canonicalJson(sorted)) {
285
- throw new Error(`${label} platforms are not canonically ordered`);
286
- }
287
- const identities = new Set();
288
- const digests = new Set();
289
- for (const platform of platforms) {
290
- const identity = platformIdentity(platform);
291
- if (identities.has(identity)) {
292
- throw new Error(`${label} has duplicate platform "${identity}"`);
293
- }
294
- if (digests.has(platform.manifestDigest)) {
295
- throw new Error(
296
- `${label} reuses platform digest "${platform.manifestDigest}"`,
297
- );
298
- }
299
- identities.add(identity);
300
- digests.add(platform.manifestDigest);
301
- }
302
- // COVERAGE, not equality. `requiredPlatforms` is what the edition DEMANDS
303
- // the published coordinate serve — `verify-image-platforms.mjs` reads it the
304
- // same way at delivery (`missing = required.filter(not present)`), and this
305
- // gate must not contradict it.
306
- //
307
- // Equality here was a latent, total break of the whole plane. The canonical
308
- // `<imageRef>:<contentHash>` coordinate becomes a MULTI-ARCH INDEX once the
309
- // arm64 lane merges, so a statement produced against the delivered digest
310
- // necessarily proves BOTH platforms — while every non-appliance edition
311
- // declares `[linux/amd64]` and both appliance editions declare
312
- // `[linux/arm64]`. Under equality NO single statement could ever satisfy any
313
- // of them, and the same subject would need contradictory evidence per
314
- // edition. The producer signs ONE statement about ONE published artifact;
315
- // the edition's requirement is a subset of what that artifact serves.
316
- //
317
- // Nothing is weakened: every entry in `platforms` was proven at assembly
318
- // time through its own hash-verified image config
319
- // (`resolvePublishedPlatforms`), the ordering/uniqueness invariants above
320
- // still hold exactly, and a REQUIRED platform that the statement does not
321
- // attest is still a hard failure — which is the property that matters.
322
- const actualIdentities = new Set(platforms.map(platformIdentity));
323
- const missing = [
324
- ...new Set(requiredPlatforms.map(platformIdentity)),
325
- ]
326
- .filter((identity) => !actualIdentities.has(identity))
327
- .sort();
328
- if (missing.length > 0) {
329
- throw new Error(
330
- `${label} attests platforms ${[...actualIdentities].sort().join(', ')}, ` +
331
- `which omit ${missing.join(', ')} required by images.lock.json`,
332
- );
333
- }
334
- }
335
-
336
- export function normalizedImageLockDigest(imageLock) {
337
- return sha256Digest(canonicalJsonBytes(imageLock));
338
- }
339
-
340
- /**
341
- * Membership in an OPTIONAL policy allowlist.
342
- *
343
- * `imageProducer.buildDefinitionDigests` / `.parametersDigests` are optional in
344
- * `SigstoreIdentityPolicySchema`. Both are derived from the BuildKit SLSA v1
345
- * `buildDefinition`, which carries the build's VCS revision and resolved
346
- * dependencies — they change on essentially every build, so an armed policy
347
- * cannot enumerate them ahead of time. OMITTED therefore means "this dimension
348
- * is not pinned", and the build stays bound by builder id, build type, OCI
349
- * media type and the Sigstore certificate identity / workflow binding.
350
- *
351
- * PRESENT means a hermetic deployment pinned an exact build, and membership is
352
- * then STRICT — there is no "empty list means anything" escape: the kernel
353
- * schema rejects an empty list, and one reaching here anyway admits nothing.
354
- */
355
- function pinnedAllowlistAdmits(allowlist, value) {
356
- return allowlist === undefined || allowlist.includes(value);
357
- }
358
-
359
- export function validateProducerStatementBinding({
360
- statement,
361
- subject,
362
- sourceHashAlgorithm,
363
- expectedContractAuthority,
364
- now,
365
- maxTtlSeconds,
366
- producerPolicy,
367
- repositoryPin,
368
- consumedNonces = new Set(),
369
- }) {
370
- if (
371
- typeof sourceHashAlgorithm !== 'string' ||
372
- sourceHashAlgorithm.length === 0
373
- ) {
374
- throw new Error(
375
- "producer evidence validation requires the image lock's declared source hash algorithm",
376
- );
377
- }
378
- const { predicate } = statement;
379
- const label = `producer evidence for ${subject.kind}:${subject.id}`;
380
- assertKernelContractAuthorityEqual(
381
- predicate.contractAuthority,
382
- expectedContractAuthority,
383
- label,
384
- );
385
- assertTimeWindow({
386
- issuedAt: predicate.producerRun.issuedAt,
387
- expiresAt: predicate.producerRun.expiresAt,
388
- now,
389
- maxTtlSeconds,
390
- label,
391
- });
392
- if (consumedNonces.has(predicate.producerRun.nonce)) {
393
- throw new Error(`${label} replays an already-consumed nonce`);
394
- }
395
- if (
396
- repositoryPin?.repo !== subject.repo ||
397
- repositoryPin.sourceCommit !== subject.sourceCommit
398
- ) {
399
- throw new Error(`${label} does not match the committed repository pin`);
400
- }
401
- const expectedSource = {
402
- kind: subject.kind,
403
- id: subject.id,
404
- repositoryUrl: repositoryPin.repositoryUrl,
405
- repo: subject.repo,
406
- path: subject.path,
407
- sourceCommit: subject.sourceCommit,
408
- sourceManifestHash: subject.sourceManifestHash,
409
- // Read from the lock, never a literal: the lock's declared algorithm IS the
410
- // coordinate's identity, and a hardcoded copy here would silently keep
411
- // validating against a retired algorithm after the coordinate widened.
412
- sourceHashAlgorithm,
413
- sourceTreeHash: subject.contentHash,
414
- };
415
- if (canonicalJson(predicate.source) !== canonicalJson(expectedSource)) {
416
- throw new Error(`${label} source identity does not match images.lock.json`);
417
- }
418
- if (
419
- statement.subject[0].name !== subject.imageRef ||
420
- `sha256:${statement.subject[0].digest.sha256}` !==
421
- predicate.artifact.manifestDigest ||
422
- predicate.artifact.imageRepository !== subject.imageRef
423
- ) {
424
- throw new Error(`${label} has an OCI subject/digest substitution`);
425
- }
426
- // THE SEALED ARTIFACT. `imageDigest` names the exact manifest that SHIPS
427
- // (`seal-image-digests.mjs` writes it from the delivery-time platform
428
- // verifier; the chart plane installs by it). The producer statement attests
429
- // one manifest digest. If the two differ, the evidence proves an image OTHER
430
- // than the one the lock installs — every check above still passes, because
431
- // they bind the SOURCE coordinate and the statement's internal consistency,
432
- // not the shipped bytes. That is the one substitution a self-consistent
433
- // evidence set can carry, and it is the one a customer verifying its own
434
- // edition most needs refused. A subject with NO `imageDigest` gives the
435
- // statement nothing to be bound to, so it is refused, never read as "binds
436
- // nothing": evidence is verified against a sealed lock only.
437
- if (typeof subject.imageDigest !== 'string') {
438
- throw new Error(
439
- `${label}: images.lock.json seals no imageDigest for ${subject.kind}:${subject.id}, so the ` +
440
- 'attested manifest is bound to nothing. Run `xema edition resolve-digests` first.',
441
- );
442
- }
443
- if (subject.imageDigest !== predicate.artifact.manifestDigest) {
444
- throw new Error(
445
- `${label} attests manifest ${predicate.artifact.manifestDigest} but ` +
446
- `images.lock.json seals ${subject.imageDigest} for ${subject.imageRef}`,
447
- );
448
- }
449
- assertPlatforms(predicate.build.platforms, subject.requiredPlatforms, label);
450
- // The always-required anchors are checked unconditionally; the two per-build
451
- // digests only narrow the identity when the policy actually pinned them (see
452
- // `pinnedAllowlistAdmits`). Reading them unconditionally would throw a
453
- // TypeError on `undefined.includes` for every ordinary policy, and simply
454
- // ignoring a PRESENT list would be a gate that cannot fail.
455
- const authorizedBuildIdentity =
456
- Boolean(producerPolicy) &&
457
- producerPolicy.builderIds.includes(predicate.build.builderId) &&
458
- producerPolicy.buildTypes.includes(predicate.build.buildType) &&
459
- producerPolicy.manifestMediaTypes.includes(
460
- predicate.artifact.manifestMediaType,
461
- ) &&
462
- pinnedAllowlistAdmits(
463
- producerPolicy.buildDefinitionDigests,
464
- predicate.build.buildDefinitionDigest,
465
- ) &&
466
- pinnedAllowlistAdmits(
467
- producerPolicy.parametersDigests,
468
- predicate.build.parametersDigest,
469
- );
470
- if (!authorizedBuildIdentity) {
471
- throw new Error(
472
- `${label} build identity, definition, parameters, or OCI media type is not authorized`,
473
- );
474
- }
475
- const protectedDigests = new Set([
476
- predicate.artifact.manifestDigest,
477
- predicate.artifact.sbom.digest,
478
- predicate.artifact.provenance.digest,
479
- ]);
480
- if (protectedDigests.size !== 3) {
481
- throw new Error(
482
- `${label} substitutes an image, SBOM, or provenance digest`,
483
- );
484
- }
485
- return statement;
486
- }
487
-
488
- /**
489
- * The canonical order of a completeness `images[]` entry.
490
- *
491
- * Exported because the PRODUCER must emit exactly the order the verifier
492
- * demands: `validateCompletenessStatementBinding` REFUSES a statement whose
493
- * `images[]` is not in this order. Two copies of a comparator that a signature
494
- * is bound to is a signed artifact waiting to become unverifiable.
495
- */
496
- export function compareCompletenessImages(left, right) {
497
- return (
498
- compareStrings(left.subjectKind, right.subjectKind) ||
499
- compareStrings(left.subjectId, right.subjectId) ||
500
- // The generations of one composed artifact share kind and id: they order by image, then manifest.
501
- compareStrings(left.imageRepository, right.imageRepository) ||
502
- compareStrings(left.manifestDigest, right.manifestDigest)
503
- );
504
- }
505
-
506
- function normalizedCompletenessImages(images) {
507
- return [...images].sort(compareCompletenessImages);
508
- }
509
-
510
- export function validateCompletenessStatementBinding({
511
- statement,
512
- distributionLock,
513
- imageLock,
514
- verifiedProducers,
515
- evidenceDescriptors,
516
- now,
517
- maxTtlSeconds,
518
- expectedReleaseSourceCommit,
519
- evidenceNonces = new Set(),
520
- }) {
521
- const { predicate } = statement;
522
- const label = `distribution completeness for ${imageLock.distributionId}`;
523
- assertTimeWindow({
524
- issuedAt: predicate.issuedAt,
525
- expiresAt: predicate.expiresAt,
526
- now,
527
- maxTtlSeconds,
528
- label,
529
- });
530
- if (evidenceNonces.has(predicate.nonce)) {
531
- throw new Error(`${label} reuses a producer nonce`);
532
- }
533
- if (predicate.releaseSourceCommit !== expectedReleaseSourceCommit) {
534
- throw new Error(
535
- `${label} does not bind the exact editions release source commit`,
536
- );
537
- }
538
- const lockDigest = normalizedImageLockDigest(imageLock);
539
- if (
540
- predicate.distributionId !== distributionLock.distributionId ||
541
- predicate.distributionInputHash !== distributionLock.inputHash ||
542
- predicate.normalizedImageLockDigest !== lockDigest ||
543
- statement.subject[0].name !==
544
- `xema-distribution/${distributionLock.distributionId}` ||
545
- `sha256:${statement.subject[0].digest.sha256}` !== lockDigest
546
- ) {
547
- throw new Error(`${label} does not bind the selected distribution locks`);
548
- }
549
- const expectedImages = imageLock.subjects.map((subject) => {
550
- const key = sourceIdentity(subject);
551
- const producer = verifiedProducers.get(key);
552
- const descriptor = evidenceDescriptors.get(key);
553
- if (!producer || !descriptor) {
554
- throw new Error(`${label} omits producer evidence for ${key}`);
555
- }
556
- return {
557
- subjectKind: subject.kind,
558
- subjectId: subject.id,
559
- imageRepository: subject.imageRef,
560
- manifestDigest: producer.predicate.artifact.manifestDigest,
561
- producerStatementDigest: descriptor.statementDigest,
562
- producerBundleDigest: descriptor.bundleDigest,
563
- };
564
- });
565
- const actual = normalizedCompletenessImages(predicate.images);
566
- const expected = normalizedCompletenessImages(expectedImages);
567
- if (
568
- canonicalJson(predicate.images) !== canonicalJson(actual) ||
569
- canonicalJson(actual) !== canonicalJson(expected)
570
- ) {
571
- throw new Error(
572
- `${label} image set is incomplete, contains extras, or is not canonically ordered`,
573
- );
574
- }
575
- return statement;
576
- }
577
-
578
- export function validateEntitlementStatementBinding({
579
- statement,
580
- completenessStatementDigest,
581
- customerId,
582
- distributionId,
583
- mode,
584
- targetRegistry,
585
- now,
586
- maxTtlSeconds,
587
- consumedNonces = new Set(),
588
- }) {
589
- const { predicate } = statement;
590
- const label = `delivery entitlement for ${customerId}`;
591
- assertTimeWindow({
592
- issuedAt: predicate.issuedAt,
593
- expiresAt: predicate.expiresAt,
594
- now,
595
- maxTtlSeconds,
596
- label,
597
- });
598
- // The predicate's `idempotencyKey` is the issuer's own request key. Nothing
599
- // on the verifying side records keys across runs, so it is not checked here:
600
- // replay is refused by the nonce, and by the replay state's release sequence.
601
- if (consumedNonces.has(predicate.nonce)) {
602
- throw new Error(`${label} is replayed`);
603
- }
604
- if (
605
- predicate.customerId !== customerId ||
606
- predicate.distributionId !== distributionId ||
607
- predicate.distributionStatementDigest !== completenessStatementDigest ||
608
- predicate.mode !== mode ||
609
- predicate.targetRegistry !== targetRegistry
610
- ) {
611
- throw new Error(
612
- `${label} does not authorize the requested customer, distribution, mode, and target`,
613
- );
614
- }
615
- if (
616
- statement.subject[0].name !== `xema-distribution/${distributionId}` ||
617
- `sha256:${statement.subject[0].digest.sha256}` !==
618
- completenessStatementDigest
619
- ) {
620
- throw new Error(`${label} substitutes the distribution release`);
621
- }
622
- return statement;
623
- }
624
-
625
- /** Throw the kernel's refusal code, verbatim, when a kernel predicate check returned one. */
626
- function assertKernelPredicateAccepted(label, refusal) {
627
- if (refusal !== undefined) {
628
- throw new Error(`${label} is refused: ${refusal}`);
629
- }
630
- }
631
-
632
- function assertEvidenceChannel(channel) {
633
- if (typeof channel !== 'string' || channel === '') {
634
- throw new Error('evidence verification requires the channel of the edition being verified');
635
- }
636
- }
637
-
638
- /**
639
- * The policy rows that authorize `predicateType` on `channel`: a filter on the
640
- * row's `channel` and `predicateTypes`, and, when `imageRepository` is given
641
- * (producer evidence), on the row's `imageRepositories` holding that exact
642
- * repository (no prefix match). It reads no certificate and proves nothing by
643
- * itself.
644
- *
645
- * What ties a row to its channel is the kernel policy schema the policy was
646
- * parsed by: a row's `githubWorkflow.ref` must be the ref of its `channel`
647
- * (`EVIDENCE_CHANNEL_REFS`) and its `certificateIdentity` must be exactly
648
- * `https://github.com/<repository>/<path>@<ref>`. One ROW is therefore one
649
- * channel; the same workflow file may still be authorized on both channels, as
650
- * two rows naming the two refs. The caller then runs cosign once per returned
651
- * row with that row's `certificateIdentity`, `oidcIssuer`, workflow repository
652
- * and ref (and the exact workflow commit), so evidence signed from the other
653
- * channel's ref matches no row selected here and fails verification; an
654
- * edition that states a channel with no row for the predicate is refused
655
- * before cosign runs ("authorizes no signer").
656
- *
657
- * The channel an edition DESCRIPTOR states is unauthenticated input: it only
658
- * selects which policy rows are tried; what authenticates a channel is the
659
- * certificate matching a row of that channel.
660
- */
661
- export function policyCandidates(policy, predicateType, channel, imageRepository) {
662
- const candidates = policy.policies.filter(
663
- (candidate) =>
664
- candidate.channel === channel &&
665
- candidate.predicateTypes.includes(predicateType) &&
666
- (imageRepository === undefined ||
667
- candidate.imageRepositories?.includes(imageRepository) === true),
668
- );
669
- // The kernel policy also admits `public-key` signers; this verifier runs cosign keyless only, so such a row is refused, never skipped.
670
- const unsupported = candidates.find((candidate) => candidate.kind !== OIDC_CERTIFICATE_SIGNER);
671
- if (unsupported !== undefined) {
672
- throw new Error(
673
- `policy row "${unsupported.policyId}" is a ${JSON.stringify(unsupported.kind)} signer; this CLI verifies ${OIDC_CERTIFICATE_SIGNER} signers only`,
674
- );
675
- }
676
- return candidates;
677
- }
678
-
679
- function cosignVersion(cosignBinary) {
680
- const output = exactExecutableOutput(cosignBinary, ['version'], {
681
- env: COSIGN_ENV,
682
- timeout: 10_000,
683
- });
684
- const match = /\bGitVersion:\s*(v\d+\.\d+\.\d+)\b/.exec(output);
685
- if (!match) {
686
- throw new Error('cosign version output has no exact GitVersion');
687
- }
688
- return match[1];
689
- }
690
-
691
- export function prepareTrustedCosignBinary({ cosignBinary, policy }) {
692
- return prepareDigestPinnedExecutable({
693
- executablePath: cosignBinary,
694
- trustedDigests: policy.trustedCosignBinaryDigests,
695
- label: 'cosign',
696
- verifyVersion(privateBinary) {
697
- if (cosignVersion(privateBinary) !== policy.cosignVersion) {
698
- throw new Error(
699
- `cosign version does not match pinned ${policy.cosignVersion}`,
700
- );
701
- }
702
- },
703
- });
704
- }
705
-
706
- export function verifySigstoreEvidenceDescriptor({
707
- evidenceRoot,
708
- descriptor,
709
- policy,
710
- predicateType,
711
- channel,
712
- imageRepository,
713
- expectedWorkflowSha,
714
- parseStatement,
715
- policyRoot = evidenceRoot,
716
- trustedCosign,
717
- holdProducerWorkflow,
718
- // The statement bytes are the DSSE payload a third party's tool signed (cosign's provenance), which is
719
- // exact JSON but not this CLI's canonical form; only that caller replaces the canonical decoder.
720
- decodeStatement = parseCanonicalJsonBytes,
721
- }) {
722
- assertEvidenceChannel(channel);
723
- const statementFile = readExactDescriptorFile(
724
- evidenceRoot,
725
- descriptor.statementPath,
726
- descriptor.statementDigest,
727
- 'evidence statement',
728
- MAX_STATEMENT_BYTES,
729
- );
730
- const bundleFile = readExactDescriptorFile(
731
- evidenceRoot,
732
- descriptor.bundlePath,
733
- descriptor.bundleDigest,
734
- 'Sigstore bundle',
735
- MAX_SIGSTORE_BUNDLE_BYTES,
736
- );
737
- const bundle = JSON.parse(
738
- decodeExactUtf8(bundleFile.bytes, 'Sigstore bundle'),
739
- );
740
- if (bundle.mediaType !== descriptor.bundleMediaType) {
741
- throw new Error('Sigstore bundle mediaType does not match its descriptor');
742
- }
743
- if (
744
- bundle.messageSignature !== undefined ||
745
- typeof bundle.dsseEnvelope !== 'object' ||
746
- bundle.dsseEnvelope === null ||
747
- bundle.dsseEnvelope.payloadType !== 'application/vnd.in-toto+json' ||
748
- !Array.isArray(bundle.dsseEnvelope.signatures) ||
749
- bundle.dsseEnvelope.signatures.length !== 1 ||
750
- typeof bundle.dsseEnvelope.payload !== 'string' ||
751
- !/^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=)?$/.test(
752
- bundle.dsseEnvelope.payload,
753
- )
754
- ) {
755
- throw new Error(
756
- 'Sigstore bundle must contain exactly one DSSE in-toto signature',
757
- );
758
- }
759
- const dssePayload = Buffer.from(bundle.dsseEnvelope.payload, 'base64');
760
- if (
761
- dssePayload.toString('base64') !== bundle.dsseEnvelope.payload ||
762
- !dssePayload.equals(statementFile.bytes)
763
- ) {
764
- throw new Error(
765
- 'Sigstore DSSE payload does not exactly match the canonical statement',
766
- );
767
- }
768
- const statement = parseStatement(
769
- decodeStatement(statementFile.bytes, 'evidence statement'),
770
- );
771
- if (statement.predicateType !== predicateType) {
772
- throw new Error('evidence statement predicateType is not authorized');
773
- }
774
- const candidates = policyCandidates(
775
- policy,
776
- predicateType,
777
- channel,
778
- imageRepository,
779
- );
780
- if (candidates.length === 0) {
781
- throw new Error(
782
- `offline trust policy authorizes no signer for ${predicateType} on channel "${channel}"` +
783
- (imageRepository === undefined
784
- ? ''
785
- : ` and image repository "${imageRepository}"`),
786
- );
787
- }
788
- const trustedCosignPath = assertPreparedExecutable(trustedCosign, 'cosign');
789
- const trustedRoot = validatePinnedTrustedRoot(policyRoot, policy);
790
- const verifiedWorkflowSha =
791
- expectedWorkflowSha ??
792
- statement.predicate?.producerRun?.producerWorkflowSha;
793
- let verified = false;
794
- let verifiedIdentityPolicy;
795
- let verifiedCandidateWorkflowSha;
796
- const verificationErrors = [];
797
- for (const candidate of candidates) {
798
- if (!verifiedWorkflowSha) {
799
- throw new Error(
800
- `policy "${candidate.policyId}" requires an exact workflow SHA`,
801
- );
802
- }
803
- const verifiedOutputDirectory = mkdtempSync(
804
- join(tmpdir(), 'xema-verified-dsse-'),
805
- );
806
- try {
807
- const verifiedBundlePath = join(
808
- verifiedOutputDirectory,
809
- 'bundle.sigstore.json',
810
- );
811
- const verifiedTrustedRootPath = join(
812
- verifiedOutputDirectory,
813
- 'trusted-root.json',
814
- );
815
- writeFileSync(verifiedBundlePath, bundleFile.bytes, {
816
- flag: 'wx',
817
- mode: 0o600,
818
- });
819
- writeFileSync(verifiedTrustedRootPath, trustedRoot.bytes, {
820
- flag: 'wx',
821
- mode: 0o600,
822
- });
823
- // `--check-claims=false`: the attested claim is bound to the statement,
824
- // not to a blob — the DSSE payload was already proven byte-identical to
825
- // the canonical statement above, so cosign only has to prove the
826
- // signature under the exact certificate constraints.
827
- const args = [
828
- 'verify-blob-attestation',
829
- '--check-claims=false',
830
- '--offline',
831
- '--new-bundle-format',
832
- '--trusted-root',
833
- verifiedTrustedRootPath,
834
- '--bundle',
835
- verifiedBundlePath,
836
- ...certificateConstraintArgs(candidate, verifiedWorkflowSha),
837
- '--type',
838
- predicateType,
839
- ];
840
- execFileSync(trustedCosignPath, args, {
841
- env: COSIGN_ENV,
842
- stdio: ['ignore', 'ignore', 'pipe'],
843
- timeout: 60_000,
844
- });
845
- verified = true;
846
- verifiedIdentityPolicy = candidate;
847
- verifiedCandidateWorkflowSha = verifiedWorkflowSha;
848
- break;
849
- } catch (error) {
850
- verificationErrors.push(
851
- `${candidate.policyId}: ${
852
- error instanceof Error ? error.message : String(error)
853
- }`,
854
- );
855
- } finally {
856
- rmSync(verifiedOutputDirectory, {
857
- recursive: true,
858
- force: true,
859
- });
860
- }
861
- }
862
- if (!verified) {
863
- throw new Error(
864
- 'offline Sigstore verification failed for every trusted identity: ' +
865
- verificationErrors.join('; '),
866
- );
867
- }
868
- // The certificate's workflow commit is held to the data root's operator-stated pin for that workflow's repository.
869
- if (holdProducerWorkflow !== undefined) {
870
- assertKernelPredicateAccepted(
871
- `${predicateType} signer ${verifiedIdentityPolicy.githubWorkflow.repository}`,
872
- holdProducerWorkflow({
873
- repository: verifiedIdentityPolicy.githubWorkflow.repository,
874
- workflowCommit: verifiedCandidateWorkflowSha,
875
- }),
876
- );
877
- }
878
- return {
879
- statement,
880
- statementPath: statementFile.path,
881
- bundle,
882
- identityPolicy: verifiedIdentityPolicy,
883
- };
884
- }
885
-
886
- export async function verifyDistributionImageEvidenceSet(options) {
887
- assertEvidenceChannel(options.channel);
888
- const trustedCosign = prepareTrustedCosignBinary({
889
- cosignBinary: options.cosignBinary,
890
- policy: options.policy,
891
- });
892
- try {
893
- return await verifyDistributionImageEvidenceSetWithCosign({
894
- ...options,
895
- trustedCosign,
896
- });
897
- } finally {
898
- trustedCosign.dispose();
899
- }
900
- }
901
-
902
- async function verifyDistributionImageEvidenceSetWithCosign({
903
- distributionId,
904
- channel,
905
- dataRoot,
906
- // WHERE THE LOCKS ARE READ FROM: the editions root. The runtime index comes
907
- // from `dataRoot`: the index is the data root's, the lock is the edition's.
908
- editionsRoot,
909
- evidenceRoot,
910
- evidenceSet,
911
- policy,
912
- now,
913
- expectedReleaseSourceCommit,
914
- policyRoot = evidenceRoot,
915
- trustedCosign,
916
- schemas,
917
- }) {
918
- // The authority the producer statements are held to is the one the data
919
- // root's index states, which the entry has already held to the data root's
920
- // evidence-trust pin (`readTrustAnchors`); the bundled kernel is held to that
921
- // authority by the `--kernel` equality check at the entry, and the schemas that
922
- // parse the index are the bundled ones, held to their edition protocol.
923
- const {
924
- distributionLock,
925
- imageLock,
926
- repositoryPins,
927
- runtimeSourceIndex,
928
- thirdPartySources,
929
- } = await loadValidatedLocks(distributionId, dataRoot, schemas, {
930
- editionsRoot,
931
- channel,
932
- });
933
- const expectedContractAuthority = runtimeSourceIndex.contractAuthority;
934
- if (evidenceSet.distributionId !== distributionId) {
935
- throw new Error(
936
- `evidence set "${evidenceSet.distributionId}" does not match requested distribution "${distributionId}"`,
937
- );
938
- }
939
-
940
- const evidenceDescriptors = new Map();
941
- for (const producerEvidence of evidenceSet.producerEvidence) {
942
- const key = `${producerEvidence.subjectKind}\0${producerEvidence.subjectId}`;
943
- if (evidenceDescriptors.has(key)) {
944
- throw new Error(`evidence set duplicates producer subject ${key}`);
945
- }
946
- evidenceDescriptors.set(key, producerEvidence.evidence);
947
- }
948
- if (evidenceDescriptors.size !== imageLock.subjects.length) {
949
- throw new Error(
950
- `evidence set has ${evidenceDescriptors.size} producer subjects; images.lock.json requires exactly ${imageLock.subjects.length}`,
951
- );
952
- }
953
-
954
- const verifiedProducers = new Map();
955
- const verifiedNonces = new Set();
956
- for (const subject of imageLock.subjects) {
957
- const key = sourceIdentity(subject);
958
- const descriptor = evidenceDescriptors.get(key);
959
- if (!descriptor) {
960
- throw new Error(`evidence set omits producer subject ${key}`);
961
- }
962
- const repositoryPin = repositoryPins.get(subject.repo);
963
- if (!repositoryPin) {
964
- throw new Error(
965
- `runtime subject "${subject.kind}:${subject.id}" has no committed repository pin`,
966
- );
967
- }
968
- const { statement, identityPolicy, bundle } = verifySigstoreEvidenceDescriptor({
969
- evidenceRoot,
970
- descriptor,
971
- policy,
972
- predicateType: schemas.IMAGE_PRODUCER_PREDICATE_TYPE,
973
- channel,
974
- imageRepository: subject.imageRef,
975
- parseStatement: schemas.parseImageProducerStatement,
976
- policyRoot,
977
- trustedCosign,
978
- holdProducerWorkflow: (producer) => schemas.producerWorkflowPinRefusal(runtimeSourceIndex, producer),
979
- });
980
- const thirdPartySource = thirdPartySources.get(subject.repo);
981
- if (thirdPartySource !== undefined) {
982
- assertThirdPartySubjectAdmission({ subject, source: thirdPartySource, statement, identityPolicy, bundle });
983
- }
984
- // XEMA-1611 d9-1 first-party form pending d9: no repository-agreement assertion is made for a first-party subject
985
- // (a monorepo path is not the signing row's repository, and the xema-deploy rows sign other repositories' images).
986
- validateProducerStatementBinding({
987
- statement,
988
- subject,
989
- sourceHashAlgorithm: imageLock.sourceHashAlgorithm,
990
- expectedContractAuthority,
991
- now,
992
- maxTtlSeconds: policy.maxProducerTtlSeconds,
993
- producerPolicy: identityPolicy.imageProducer,
994
- repositoryPin,
995
- consumedNonces: verifiedNonces,
996
- });
997
- verifiedNonces.add(statement.predicate.producerRun.nonce);
998
- verifiedProducers.set(key, statement);
999
- }
1000
- for (const key of evidenceDescriptors.keys()) {
1001
- if (!verifiedProducers.has(key)) {
1002
- throw new Error(`evidence set contains unknown producer subject ${key}`);
1003
- }
1004
- }
1005
-
1006
- const { statement: completenessStatement, identityPolicy: completenessPolicy } = verifySigstoreEvidenceDescriptor(
1007
- {
1008
- evidenceRoot,
1009
- descriptor: evidenceSet.completeness,
1010
- policy,
1011
- predicateType: schemas.DISTRIBUTION_IMAGES_PREDICATE_TYPE,
1012
- channel,
1013
- expectedWorkflowSha: expectedReleaseSourceCommit,
1014
- parseStatement: schemas.parseDistributionImagesStatement,
1015
- policyRoot,
1016
- trustedCosign,
1017
- },
1018
- );
1019
- // After the signature verified: the channel the predicate states is the verifying policy row's, and the
1020
- // predicate completes THIS lock. A kernel refusal is terminal and is surfaced by its code.
1021
- assertKernelPredicateAccepted(
1022
- `distribution completeness for ${imageLock.distributionId}`,
1023
- schemas.distributionImagesPredicateChannelRefusal(completenessStatement.predicate, completenessPolicy),
1024
- );
1025
- assertKernelPredicateAccepted(
1026
- `distribution completeness for ${imageLock.distributionId}`,
1027
- schemas.distributionImagesPredicateLockRefusal(completenessStatement.predicate, distributionLock),
1028
- );
1029
- validateCompletenessStatementBinding({
1030
- statement: completenessStatement,
1031
- distributionLock,
1032
- imageLock,
1033
- verifiedProducers,
1034
- evidenceDescriptors,
1035
- now,
1036
- maxTtlSeconds: policy.maxCompletenessTtlSeconds,
1037
- expectedReleaseSourceCommit,
1038
- evidenceNonces: verifiedNonces,
1039
- });
1040
- verifiedNonces.add(completenessStatement.predicate.nonce);
1041
-
1042
- return {
1043
- distributionLock,
1044
- imageLock,
1045
- producerStatements: verifiedProducers,
1046
- completenessStatement,
1047
- completenessStatementDigest: evidenceSet.completeness.statementDigest,
1048
- verifiedNonces,
1049
- };
1050
- }
1051
-
1052
- export async function verifyImageDeliveryEntitlement(options) {
1053
- assertEvidenceChannel(options.channel);
1054
- const trustedCosign = prepareTrustedCosignBinary({
1055
- cosignBinary: options.cosignBinary,
1056
- policy: options.policy,
1057
- });
1058
- try {
1059
- return await verifyImageDeliveryEntitlementWithCosign({
1060
- ...options,
1061
- trustedCosign,
1062
- });
1063
- } finally {
1064
- trustedCosign.dispose();
1065
- }
1066
- }
1067
-
1068
- async function verifyImageDeliveryEntitlementWithCosign({
1069
- evidenceRoot,
1070
- descriptor,
1071
- policy,
1072
- completenessStatementDigest,
1073
- customerId,
1074
- distributionId,
1075
- distributionLock,
1076
- channel,
1077
- mode,
1078
- targetRegistry,
1079
- now,
1080
- expectedWorkflowSha,
1081
- consumedNonces = new Set(),
1082
- policyRoot = evidenceRoot,
1083
- trustedCosign,
1084
- schemas,
1085
- }) {
1086
- const { statement } = verifySigstoreEvidenceDescriptor({
1087
- evidenceRoot,
1088
- descriptor,
1089
- policy,
1090
- predicateType: schemas.IMAGE_DELIVERY_ENTITLEMENT_PREDICATE_TYPE,
1091
- channel,
1092
- expectedWorkflowSha,
1093
- parseStatement: schemas.parseImageDeliveryEntitlementStatement,
1094
- policyRoot,
1095
- trustedCosign,
1096
- });
1097
- assertKernelPredicateAccepted(
1098
- `delivery entitlement for ${customerId}`,
1099
- schemas.imageDeliveryEntitlementRefusal(statement.predicate, distributionLock),
1100
- );
1101
- validateEntitlementStatementBinding({
1102
- statement,
1103
- completenessStatementDigest,
1104
- customerId,
1105
- distributionId,
1106
- mode,
1107
- targetRegistry,
1108
- now,
1109
- maxTtlSeconds: policy.maxEntitlementTtlSeconds,
1110
- consumedNonces,
1111
- });
1112
- return statement;
1113
- }
1114
-
1115
- /**
1116
- * Repository pins for the sources an EDITION declares itself.
1117
- *
1118
- * The runtime image source index pins the VENDOR fleet — every `repos/…` and
1119
- * `submodules/…` repository the vendor builds images from. A customer edition
1120
- * additionally draws biomes from sources declared in its own manifest
1121
- * (`sources[]`, `kind: git`), and the images built from those have a `repo`
1122
- * the index has never heard of and never will: `<customer>-biomes`, not
1123
- * `repos/xema-base`. Without a pin for it every such subject is refused as
1124
- * "has no committed repository pin", so a customer could verify the vendor's
1125
- * images in its edition and never its own.
1126
- *
1127
- * The pin for an external source is two facts from two records, and each is
1128
- * the record that OWNS the fact:
1129
- *
1130
- * * `repositoryUrl` — the edition manifest's declaration, by source name.
1131
- * The manifest is read from the editions checkout and is HEAD-bound there
1132
- * exactly like the locks (the verifier names it a required edition path).
1133
- * * `sourceCommit` — the image lock's subjects. A declared `ref` may be a
1134
- * branch; the lock records the exact commit the walk materialised, and it
1135
- * is the authority for what was built. Every subject of one source must
1136
- * agree on one commit, or the lock describes a walk that never happened.
1137
- *
1138
- * A declared source that ships no image yields no pin. A source whose name
1139
- * collides with an index pin is refused: the index is the vendor's record and
1140
- * an edition may not restate it. Non-git sources build no images from a
1141
- * repository and yield no pin; a subject naming one stays unpinned and is
1142
- * refused downstream, as before.
1143
- */
1144
- export function externalSourceRepositoryPins({
1145
- distribution,
1146
- imageLock,
1147
- repositoryPins,
1148
- }) {
1149
- const derived = new Map();
1150
- for (const source of distribution.sources ?? []) {
1151
- if (source.kind !== 'git') {continue;}
1152
- if (repositoryPins.has(source.name)) {
1153
- throw new Error(
1154
- `edition source "${source.name}" shadows a repository pin the runtime image source index already commits`,
1155
- );
1156
- }
1157
- const subjects = imageLock.subjects.filter(
1158
- (subject) => subject.repo === source.name,
1159
- );
1160
- if (subjects.length === 0) {continue;}
1161
- const commits = [...new Set(subjects.map((subject) => subject.sourceCommit))];
1162
- if (commits.length !== 1) {
1163
- throw new Error(
1164
- `edition source "${source.name}" is built at ${commits.length} different commits in images.lock.json (${commits.join(', ')}); one source resolves to one commit`,
1165
- );
1166
- }
1167
- derived.set(source.name, {
1168
- repo: source.name,
1169
- repositoryUrl: source.url,
1170
- sourceCommit: commits[0],
1171
- });
1172
- }
1173
- return derived;
1174
- }
1175
-
1176
- /**
1177
- * The ONLY facts image evidence binds from `distribution.lock.json`, read
1178
- * TOLERANTLY and nothing else.
1179
- *
1180
- * WHY THIS IS NOT `schemas.parseDistributionLock`. The standalone verifier is a
1181
- * bundle of the kernel at its contract-authority commit, and that commit's lock
1182
- * schema is the strict WRITER schema of its day. Measured 2026-10-01 against
1183
- * the kernel at `24e9f12` (the authority every committed image lock names): a
1184
- * committed lock parses, and the SAME lock with one additive biome key
1185
- * (`provenance`) is refused — `[biomes.0] Unrecognized key: "provenance"`. So
1186
- * every additive section the resolver ever learns would have made every
1187
- * edition unverifiable until the verifier was rebuilt from a newer kernel, and
1188
- * rebuilding it meant re-pinning the authority, which rewrites
1189
- * `contractAuthority` in every `images.lock.json` and thereby invalidates every
1190
- * signed producer statement and completeness digest. An edition's image
1191
- * evidence would have been unsealed by a change that touched no image.
1192
- *
1193
- * What the evidence actually binds is two fields: the completeness predicate
1194
- * names `distributionId` and `distributionInputHash`
1195
- * (`validateCompletenessStatementBinding`), and every other caller reads the
1196
- * same two. The lock's biome roster is the PRODUCER's contract, graded by
1197
- * dist-check with the current kernel; the verifier never read it. So read
1198
- * exactly those, validate exactly those, and ignore every other key — the
1199
- * tolerant read-only posture `parseDistributionLockForReading` gives a
1200
- * runtime, without depending on which kernel the bundle was built from.
1201
- *
1202
- * Two grammars exist, and which one is accepted is decided by `channel`, the
1203
- * kernel evidence channel (`EVIDENCE_CHANNELS`) the caller operates on; it is
1204
- * required and has no default. An UNSEALED lock (it carries `unsealedSchema`;
1205
- * every edition lock on develop is one by design) is accepted ONLY on the
1206
- * develop channel, read through the kernel's `parseUnsealedDistributionLock`.
1207
- * Every other channel requires a SEALED lock: images sealed over an unsealed
1208
- * lock is the crash state every sealed reader refuses, and a release statement
1209
- * must never verify over it. A SEALED lock must have `schemaVersion` 5 (the
1210
- * kernel's `DISTRIBUTION_LOCK_SCHEMA_VERSIONS`): a pre-v5 lock is refused, with
1211
- * no compatibility path. Both carry `distributionId` and `inputHash`, and
1212
- * sealing preserves them, so either way the binding is the same two fields.
1213
- */
1214
- /** The one evidence channel an unsealed distribution lock is read on. */
1215
- const UNSEALED_LOCK_CHANNEL = 'develop';
1216
-
1217
- /**
1218
- * The channel a distribution lock is read for: one of the kernel's
1219
- * `EVIDENCE_CHANNELS`, stated by the caller. Missing or unknown is refused.
1220
- */
1221
- function assertLockReadingChannel(channel, schemas) {
1222
- if (!schemas) {
1223
- throw new Error('trusted kernel distribution schemas are required');
1224
- }
1225
- if (!schemas.EVIDENCE_CHANNELS.includes(channel)) {
1226
- throw new Error(
1227
- `a distribution lock is read for one evidence channel (${schemas.EVIDENCE_CHANNELS.join(' | ')}); got ${JSON.stringify(channel)}`,
1228
- );
1229
- }
1230
- }
1231
-
1232
- export function readDistributionLockBinding(raw, schemas, channel) {
1233
- assertLockReadingChannel(channel, schemas);
1234
- if (raw === null || typeof raw !== 'object' || Array.isArray(raw)) {
1235
- throw new Error('distribution.lock.json is not a JSON object');
1236
- }
1237
- let source = raw;
1238
- if ('unsealedSchema' in raw) {
1239
- if (channel !== UNSEALED_LOCK_CHANNEL) {
1240
- throw new Error(
1241
- `distribution.lock.json is unsealed; the ${channel} channel accepts only a sealed lock (schemaVersion 5) — ` +
1242
- `an unsealed lock is read on the ${UNSEALED_LOCK_CHANNEL} channel only`,
1243
- );
1244
- }
1245
- source = schemas.parseUnsealedDistributionLock(raw);
1246
- } else if (raw.schemaVersion !== 5) {
1247
- throw new Error(
1248
- `distribution.lock.json is neither an unsealed lock (carrying unsealedSchema) ` +
1249
- `nor a sealed lock (schemaVersion 5); it has schemaVersion ${String(raw.schemaVersion)} (regenerate the lock)`,
1250
- );
1251
- }
1252
- const { distributionId, inputHash } = source;
1253
- // The id is format-checked only. Which edition it must equal is decided by
1254
- // the bindings that USE it — the completeness predicate and the evidence set
1255
- // compare it to the image lock and the signed statement — exactly as before
1256
- // this reader existed; tightening that here would be a second, unasked rule.
1257
- assertCanonicalDistributionId(distributionId);
1258
- if (typeof inputHash !== 'string' || !/^[a-f0-9]{64}$/.test(inputHash)) {
1259
- throw new Error(
1260
- `distribution "${distributionId}" has invalid inputHash "${String(inputHash)}" — ` +
1261
- 'expected 64 lowercase sha256 hex characters',
1262
- );
1263
- }
1264
- return Object.freeze({ distributionId, inputHash });
1265
- }
1266
-
1267
- /**
1268
- * The edition's sealed `distribution.lock.json`, parsed by the kernel's strict lock parser: the document the
1269
- * predicates' `lockDigest` is computed over. Held to the binding rules of {@link readDistributionLockBinding} first.
1270
- */
1271
- export function readEditionDistributionLock(editionsRoot, distributionId, schemas, channel) {
1272
- assertLockReadingChannel(channel, schemas);
1273
- const raw = JSON.parse(
1274
- readFileSync(join(editionsRoot, distributionId, 'distribution.lock.json'), 'utf8'),
1275
- );
1276
- readDistributionLockBinding(raw, schemas, channel);
1277
- // The WHOLE lock in its own grammar, never the two-field binding: the
1278
- // predicate and entitlement refusals recompute distributionLockDigest over
1279
- // what this returns, so an unsealed develop lock is digested as itself.
1280
- return 'unsealedSchema' in raw ? schemas.parseUnsealedDistributionLock(raw) : schemas.parseDistributionLock(raw);
1281
- }
1282
-
1283
- /**
1284
- * Read and validate an edition's two locks plus the runtime image source index
1285
- * they must agree with. The distribution lock is read for `channel`
1286
- * ({@link readDistributionLockBinding}); the rest is {@link loadValidatedImageLocks}.
1287
- */
1288
- export async function loadValidatedLocks(
1289
- distributionId,
1290
- dataRoot,
1291
- schemas,
1292
- { editionsRoot, channel },
1293
- ) {
1294
- if (!schemas) {
1295
- throw new Error('trusted kernel distribution schemas are required');
1296
- }
1297
- const distributionLock = readEditionDistributionLock(
1298
- editionsRoot,
1299
- distributionId,
1300
- schemas,
1301
- channel,
1302
- );
1303
- return {
1304
- distributionLock,
1305
- ...(await loadValidatedImageLocks(distributionId, dataRoot, schemas, { editionsRoot })),
1306
- };
1307
- }
1308
-
1309
- /**
1310
- * Read and validate an edition's image lock plus the runtime image source index
1311
- * it must agree with; the distribution lock is not read.
1312
- *
1313
- * `dataRoot` holds the runtime image source index, read from it always.
1314
- * `editionsRoot` is where `<id>/images.lock.json` and
1315
- * `<id>/xema-distribution.json` are read from. The manifest extends the
1316
- * repository pins with the edition's own declared sources
1317
- * ({@link externalSourceRepositoryPins}); the verifier grades the editions
1318
- * checkout so the files it reads are HEAD-bound.
1319
- */
1320
- export async function loadValidatedImageLocks(
1321
- distributionId,
1322
- dataRoot,
1323
- schemas,
1324
- { editionsRoot },
1325
- ) {
1326
- if (!schemas) {
1327
- throw new Error('trusted kernel distribution schemas are required');
1328
- }
1329
- const imageLock = validateImmutableImageLock(
1330
- schemas.parseImageLock(
1331
- JSON.parse(
1332
- readFileSync(
1333
- join(editionsRoot, distributionId, 'images.lock.json'),
1334
- 'utf8',
1335
- ),
1336
- ),
1337
- ),
1338
- schemas,
1339
- );
1340
- const runtimeSourceIndex = schemas.parseRuntimeImageSourceIndex(
1341
- JSON.parse(
1342
- readFileSync(
1343
- join(dataRoot, 'runtime-image-source-index.json'),
1344
- 'utf8',
1345
- ),
1346
- ),
1347
- );
1348
- if (
1349
- canonicalJson(imageLock.contractAuthority) !==
1350
- canonicalJson(runtimeSourceIndex.contractAuthority)
1351
- ) {
1352
- throw new Error(
1353
- 'images.lock.json kernel contract authority does not exactly match runtime-image-source-index.json',
1354
- );
1355
- }
1356
- // The definition's `sourcePins` (the repositories this edition holds at an exact commit) is parsed by the
1357
- // kernel with the rest of it. Each subject is graded against the EFFECTIVE pin of THIS edition. Pure: no
1358
- // git, no sources root (this runs inside the built verifier).
1359
- const distribution = schemas.parseDistribution(
1360
- JSON.parse(
1361
- readFileSync(
1362
- join(editionsRoot, distributionId, 'xema-distribution.json'),
1363
- 'utf8',
1364
- ),
1365
- ),
1366
- );
1367
- const sourcePins = manifestSourcePins(distribution);
1368
- const repositoryPins = new Map(
1369
- effectiveRepositoryPins(runtimeSourceIndex.repositoryPins, sourcePins, { id: distributionId, contractAuthority: runtimeSourceIndex.contractAuthority }).map((repository) => [
1370
- repository.repo,
1371
- repository,
1372
- ]),
1373
- );
1374
- if (distribution.id !== distributionId) {
1375
- throw new Error(
1376
- `edition manifest at ${editionsRoot} declares id "${distribution.id}", not "${distributionId}"`,
1377
- );
1378
- }
1379
- for (const [repo, pin] of externalSourceRepositoryPins({
1380
- distribution,
1381
- imageLock,
1382
- repositoryPins,
1383
- })) {
1384
- repositoryPins.set(repo, pin);
1385
- }
1386
- // Third-party OCI sources: pinned by the data root's third-party source pins (held to the evidence trust pin by the entry).
1387
- const thirdPartyPins = loadThirdPartySourcePins(dataRoot);
1388
- const thirdPartyRepositoryPins = thirdPartySourceRepositoryPins({
1389
- distribution,
1390
- imageLock,
1391
- repositoryPins,
1392
- thirdPartyPins,
1393
- });
1394
- for (const [repo, pin] of thirdPartyRepositoryPins) {
1395
- repositoryPins.set(repo, pin);
1396
- }
1397
- return {
1398
- schemas,
1399
- imageLock,
1400
- runtimeSourceIndex,
1401
- repositoryPins,
1402
- thirdPartySources: thirdPartySourcesByRepository(thirdPartyRepositoryPins, thirdPartyPins),
1403
- };
1404
- }