@empire-builder-kit/nx 1.0.0-beta.9 → 1.0.0-rc.2

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 (824) hide show
  1. package/NOTICE +6 -0
  2. package/README.md +113 -3
  3. package/executors.json +30 -0
  4. package/package.json +84 -6
  5. package/src/api-contract/baseline-update.d.ts +82 -0
  6. package/src/api-contract/baseline-update.js +225 -0
  7. package/src/api-contract/baseline-update.js.map +1 -0
  8. package/src/api-contract/compatibility.d.ts +30 -0
  9. package/src/api-contract/compatibility.js +643 -0
  10. package/src/api-contract/compatibility.js.map +1 -0
  11. package/src/api-contract/contract-graph.d.ts +35 -0
  12. package/src/api-contract/contract-graph.js +141 -0
  13. package/src/api-contract/contract-graph.js.map +1 -0
  14. package/src/api-contract/evidence.d.ts +23 -0
  15. package/src/api-contract/evidence.js +87 -0
  16. package/src/api-contract/evidence.js.map +1 -0
  17. package/src/api-contract/index.d.ts +6 -0
  18. package/src/api-contract/index.js +10 -0
  19. package/src/api-contract/index.js.map +1 -0
  20. package/src/api-contract/model.d.ts +144 -0
  21. package/src/api-contract/model.fixtures.d.ts +2 -0
  22. package/src/api-contract/model.fixtures.js +81 -0
  23. package/src/api-contract/model.fixtures.js.map +1 -0
  24. package/src/api-contract/model.js +993 -0
  25. package/src/api-contract/model.js.map +1 -0
  26. package/src/api-contract/rollout.d.ts +32 -0
  27. package/src/api-contract/rollout.js +88 -0
  28. package/src/api-contract/rollout.js.map +1 -0
  29. package/src/authorization/compatibility.d.ts +62 -0
  30. package/src/authorization/compatibility.js +175 -0
  31. package/src/authorization/compatibility.js.map +1 -0
  32. package/src/authorization/index.d.ts +1 -0
  33. package/src/authorization/index.js +5 -0
  34. package/src/authorization/index.js.map +1 -0
  35. package/src/blueprints/execution.d.ts +25 -1
  36. package/src/blueprints/execution.js +246 -83
  37. package/src/blueprints/execution.js.map +1 -1
  38. package/src/blueprints/external-sandbox.d.ts +53 -0
  39. package/src/blueprints/external-sandbox.js +1182 -0
  40. package/src/blueprints/external-sandbox.js.map +1 -0
  41. package/src/blueprints/manifest.d.ts +42 -2
  42. package/src/blueprints/manifest.js +82 -27
  43. package/src/blueprints/manifest.js.map +1 -1
  44. package/src/blueprints/resolver.d.ts +14 -5
  45. package/src/blueprints/resolver.js +228 -68
  46. package/src/blueprints/resolver.js.map +1 -1
  47. package/src/cli/agent-command.d.ts +30 -0
  48. package/src/cli/agent-command.js +204 -0
  49. package/src/cli/agent-command.js.map +1 -0
  50. package/src/cli/agent-runtime.d.ts +25 -0
  51. package/src/cli/agent-runtime.js +488 -0
  52. package/src/cli/agent-runtime.js.map +1 -0
  53. package/src/cli/blueprint-authority.d.ts +9 -0
  54. package/src/cli/blueprint-authority.js +43 -0
  55. package/src/cli/blueprint-authority.js.map +1 -0
  56. package/src/cli/blueprint-command.d.ts +24 -0
  57. package/src/cli/blueprint-command.js +63 -0
  58. package/src/cli/blueprint-command.js.map +1 -0
  59. package/src/cli/bootstrap.d.ts +31 -0
  60. package/src/cli/bootstrap.js +165 -0
  61. package/src/cli/bootstrap.js.map +1 -0
  62. package/src/cli/dev-command.d.ts +92 -0
  63. package/src/cli/dev-command.js +561 -0
  64. package/src/cli/dev-command.js.map +1 -0
  65. package/src/cli/main.d.ts +131 -0
  66. package/src/cli/main.js +1199 -0
  67. package/src/cli/main.js.map +1 -0
  68. package/src/cli/output.d.ts +19 -0
  69. package/src/cli/output.js +51 -0
  70. package/src/cli/output.js.map +1 -0
  71. package/src/cli/personal-secret-runtime.d.ts +81 -0
  72. package/src/cli/personal-secret-runtime.js +567 -0
  73. package/src/cli/personal-secret-runtime.js.map +1 -0
  74. package/src/cli/secret-terminal.d.ts +12 -0
  75. package/src/cli/secret-terminal.js +128 -0
  76. package/src/cli/secret-terminal.js.map +1 -0
  77. package/src/container-images.d.ts +1 -0
  78. package/src/container-images.js +5 -0
  79. package/src/container-images.js.map +1 -0
  80. package/src/data-lifecycle/index.d.ts +3 -0
  81. package/src/data-lifecycle/index.js +7 -0
  82. package/src/data-lifecycle/index.js.map +1 -0
  83. package/src/data-lifecycle/model.d.ts +172 -0
  84. package/src/data-lifecycle/model.fixtures.d.ts +2 -0
  85. package/src/data-lifecycle/model.fixtures.js +244 -0
  86. package/src/data-lifecycle/model.fixtures.js.map +1 -0
  87. package/src/data-lifecycle/model.js +95 -0
  88. package/src/data-lifecycle/model.js.map +1 -0
  89. package/src/data-lifecycle/sensitive-artifacts.d.ts +28 -0
  90. package/src/data-lifecycle/sensitive-artifacts.js +146 -0
  91. package/src/data-lifecycle/sensitive-artifacts.js.map +1 -0
  92. package/src/data-lifecycle/validation.d.ts +32 -0
  93. package/src/data-lifecycle/validation.js +837 -0
  94. package/src/data-lifecycle/validation.js.map +1 -0
  95. package/src/database-retirement/contract.d.ts +68 -0
  96. package/src/database-retirement/contract.js +166 -0
  97. package/src/database-retirement/contract.js.map +1 -0
  98. package/src/database-retirement/index.d.ts +1 -0
  99. package/src/database-retirement/index.js +5 -0
  100. package/src/database-retirement/index.js.map +1 -0
  101. package/src/deterministic-order.d.ts +2 -0
  102. package/src/deterministic-order.js +7 -0
  103. package/src/deterministic-order.js.map +1 -0
  104. package/src/developer-agent/context.d.ts +27 -0
  105. package/src/developer-agent/context.js +497 -0
  106. package/src/developer-agent/context.js.map +1 -0
  107. package/src/developer-agent/generator-planning.d.ts +34 -0
  108. package/src/developer-agent/generator-planning.js +645 -0
  109. package/src/developer-agent/generator-planning.js.map +1 -0
  110. package/src/developer-agent/generator-preview.d.ts +8 -0
  111. package/src/developer-agent/generator-preview.js +650 -0
  112. package/src/developer-agent/generator-preview.js.map +1 -0
  113. package/src/developer-agent/git-inspection.d.ts +108 -0
  114. package/src/developer-agent/git-inspection.js +815 -0
  115. package/src/developer-agent/git-inspection.js.map +1 -0
  116. package/src/developer-agent/handoff.d.ts +43 -0
  117. package/src/developer-agent/handoff.js +698 -0
  118. package/src/developer-agent/handoff.js.map +1 -0
  119. package/src/developer-agent/index.d.ts +10 -0
  120. package/src/developer-agent/index.js +14 -0
  121. package/src/developer-agent/index.js.map +1 -0
  122. package/src/developer-agent/model.d.ts +481 -0
  123. package/src/developer-agent/model.js +143 -0
  124. package/src/developer-agent/model.js.map +1 -0
  125. package/src/developer-agent/operation-registry.d.ts +45 -0
  126. package/src/developer-agent/operation-registry.js +1255 -0
  127. package/src/developer-agent/operation-registry.js.map +1 -0
  128. package/src/developer-agent/ordering.d.ts +9 -0
  129. package/src/developer-agent/ordering.js +15 -0
  130. package/src/developer-agent/ordering.js.map +1 -0
  131. package/src/developer-agent/planning.d.ts +18 -0
  132. package/src/developer-agent/planning.js +447 -0
  133. package/src/developer-agent/planning.js.map +1 -0
  134. package/src/developer-agent/preview-changes.d.ts +26 -0
  135. package/src/developer-agent/preview-changes.js +203 -0
  136. package/src/developer-agent/preview-changes.js.map +1 -0
  137. package/src/developer-agent/preview-source.d.ts +2 -0
  138. package/src/developer-agent/preview-source.js +16 -0
  139. package/src/developer-agent/preview-source.js.map +1 -0
  140. package/src/developer-agent/validation.d.ts +18 -0
  141. package/src/developer-agent/validation.js +2617 -0
  142. package/src/developer-agent/validation.js.map +1 -0
  143. package/src/developer-agent/workspace-inspection.d.ts +20 -0
  144. package/src/developer-agent/workspace-inspection.js +1134 -0
  145. package/src/developer-agent/workspace-inspection.js.map +1 -0
  146. package/src/developer-agent/workspace-path.d.ts +6 -0
  147. package/src/developer-agent/workspace-path.js +22 -0
  148. package/src/developer-agent/workspace-path.js.map +1 -0
  149. package/src/executors/blueprint-trust/blueprint-trust.d.ts +29 -0
  150. package/src/executors/blueprint-trust/blueprint-trust.js +115 -0
  151. package/src/executors/blueprint-trust/blueprint-trust.js.map +1 -0
  152. package/src/executors/blueprint-trust/schema.json +27 -0
  153. package/src/executors/blueprint-verification/blueprint-verification.d.ts +13 -0
  154. package/src/executors/blueprint-verification/blueprint-verification.js +110 -0
  155. package/src/executors/blueprint-verification/blueprint-verification.js.map +1 -0
  156. package/src/executors/blueprint-verification/schema.json +44 -0
  157. package/src/executors/deployment-plan/deployment-plan.js +1 -0
  158. package/src/executors/deployment-plan/deployment-plan.js.map +1 -1
  159. package/src/executors/dev-doctor/dev-doctor.d.ts +19 -5
  160. package/src/executors/dev-doctor/dev-doctor.js +186 -32
  161. package/src/executors/dev-doctor/dev-doctor.js.map +1 -1
  162. package/src/executors/dev-doctor/schema.json +1 -6
  163. package/src/executors/dev-setup/dev-setup.d.ts +7 -1
  164. package/src/executors/dev-setup/dev-setup.js +14 -3
  165. package/src/executors/dev-setup/dev-setup.js.map +1 -1
  166. package/src/executors/developer-context/developer-context.d.ts +38 -0
  167. package/src/executors/developer-context/developer-context.js +78 -0
  168. package/src/executors/developer-context/developer-context.js.map +1 -0
  169. package/src/executors/developer-context/schema.json +87 -0
  170. package/src/executors/fleet/fleet.d.ts +12 -43
  171. package/src/executors/fleet/fleet.js +120 -500
  172. package/src/executors/fleet/fleet.js.map +1 -1
  173. package/src/executors/fleet/schema.json +64 -14
  174. package/src/executors/github-bootstrap/github-bootstrap.d.ts +1 -0
  175. package/src/executors/github-bootstrap/github-bootstrap.js +1 -0
  176. package/src/executors/github-bootstrap/github-bootstrap.js.map +1 -1
  177. package/src/executors/github-bootstrap/schema.json +5 -0
  178. package/src/executors/infrastructure-plan/infrastructure-plan.d.ts +144 -0
  179. package/src/executors/infrastructure-plan/infrastructure-plan.js +3320 -0
  180. package/src/executors/infrastructure-plan/infrastructure-plan.js.map +1 -0
  181. package/src/executors/infrastructure-plan/schema.json +78 -0
  182. package/src/executors/secret-guardrails/schema.json +6 -0
  183. package/src/executors/secret-guardrails/secret-guardrails.d.ts +3 -0
  184. package/src/executors/secret-guardrails/secret-guardrails.js +44 -0
  185. package/src/executors/secret-guardrails/secret-guardrails.js.map +1 -0
  186. package/src/executors/secret-metadata/schema.json +31 -0
  187. package/src/executors/secret-metadata/secret-metadata.d.ts +32 -0
  188. package/src/executors/secret-metadata/secret-metadata.js +131 -0
  189. package/src/executors/secret-metadata/secret-metadata.js.map +1 -0
  190. package/src/executors/sst-lifecycle/logging-preflight.d.ts +17 -0
  191. package/src/executors/sst-lifecycle/logging-preflight.js +196 -0
  192. package/src/executors/sst-lifecycle/logging-preflight.js.map +1 -0
  193. package/src/executors/sst-lifecycle/run-sst-command.d.ts +23 -3
  194. package/src/executors/sst-lifecycle/run-sst-command.js +113 -10
  195. package/src/executors/sst-lifecycle/run-sst-command.js.map +1 -1
  196. package/src/executors/sst-lifecycle/schema.json +9 -5
  197. package/src/executors/sst-lifecycle/secret-preflight.d.ts +25 -0
  198. package/src/executors/sst-lifecycle/secret-preflight.js +119 -0
  199. package/src/executors/sst-lifecycle/secret-preflight.js.map +1 -0
  200. package/src/foundation/discovery.d.ts +17 -1
  201. package/src/foundation/discovery.js +16 -1
  202. package/src/foundation/discovery.js.map +1 -1
  203. package/src/foundation/index.d.ts +3 -0
  204. package/src/foundation/index.js +3 -0
  205. package/src/foundation/index.js.map +1 -1
  206. package/src/foundation/local-database-contract.d.ts +1 -0
  207. package/src/foundation/local-database-contract.js +3 -0
  208. package/src/foundation/local-database-contract.js.map +1 -1
  209. package/src/foundation/logging-preflight.d.ts +30 -0
  210. package/src/foundation/logging-preflight.js +138 -0
  211. package/src/foundation/logging-preflight.js.map +1 -0
  212. package/src/foundation/logging.d.ts +70 -0
  213. package/src/foundation/logging.js +133 -0
  214. package/src/foundation/logging.js.map +1 -0
  215. package/src/foundation/preflight.d.ts +9 -0
  216. package/src/foundation/preflight.js +58 -2
  217. package/src/foundation/preflight.js.map +1 -1
  218. package/src/foundation/provision-database-bindings.d.ts +9 -1
  219. package/src/foundation/provision-database-bindings.js +25 -5
  220. package/src/foundation/provision-database-bindings.js.map +1 -1
  221. package/src/foundation/provision-logical-database.d.ts +10 -2
  222. package/src/foundation/provision-logical-database.js +68 -113
  223. package/src/foundation/provision-logical-database.js.map +1 -1
  224. package/src/foundation/router-origin-proof.d.ts +2 -0
  225. package/src/foundation/router-origin-proof.js +25 -0
  226. package/src/foundation/router-origin-proof.js.map +1 -0
  227. package/src/foundation/stages.d.ts +1 -0
  228. package/src/foundation/stages.js +9 -1
  229. package/src/foundation/stages.js.map +1 -1
  230. package/src/frontend-security/index.d.ts +1 -0
  231. package/src/frontend-security/index.js +5 -0
  232. package/src/frontend-security/index.js.map +1 -0
  233. package/src/frontend-security/security-headers.d.ts +50 -0
  234. package/src/frontend-security/security-headers.js +418 -0
  235. package/src/frontend-security/security-headers.js.map +1 -0
  236. package/src/generators/feature-registry.d.ts +13 -0
  237. package/src/generators/feature-registry.js +73 -0
  238. package/src/generators/feature-registry.js.map +1 -0
  239. package/src/generators/function/function.d.ts +1 -1
  240. package/src/generators/function/function.js +51 -6
  241. package/src/generators/function/function.js.map +1 -1
  242. package/src/generators/function/schema.d.ts +1 -0
  243. package/src/generators/function/schema.json +6 -1
  244. package/src/generators/logging-registry.d.ts +13 -0
  245. package/src/generators/logging-registry.js +62 -0
  246. package/src/generators/logging-registry.js.map +1 -0
  247. package/src/generators/post-generation-install.d.ts +67 -0
  248. package/src/generators/post-generation-install.js +3308 -0
  249. package/src/generators/post-generation-install.js.map +1 -0
  250. package/src/generators/preset/generator.js +3 -0
  251. package/src/generators/preset/generator.js.map +1 -1
  252. package/src/generators/preset/tool-versions.d.ts +18 -0
  253. package/src/generators/preset/tool-versions.js +22 -0
  254. package/src/generators/preset/tool-versions.js.map +1 -0
  255. package/src/generators/preset/workspace-files-developer-agent.d.ts +14 -0
  256. package/src/generators/preset/workspace-files-developer-agent.js +511 -0
  257. package/src/generators/preset/workspace-files-developer-agent.js.map +1 -0
  258. package/src/generators/preset/workspace-files-foundation-workload-roles.d.ts +6 -0
  259. package/src/generators/preset/workspace-files-foundation-workload-roles.js +406 -0
  260. package/src/generators/preset/workspace-files-foundation-workload-roles.js.map +1 -0
  261. package/src/generators/preset/workspace-files-performance-cost.d.ts +66 -0
  262. package/src/generators/preset/workspace-files-performance-cost.js +866 -0
  263. package/src/generators/preset/workspace-files-performance-cost.js.map +1 -0
  264. package/src/generators/preset/workspace-files-performance-load.d.ts +73 -0
  265. package/src/generators/preset/workspace-files-performance-load.js +801 -0
  266. package/src/generators/preset/workspace-files-performance-load.js.map +1 -0
  267. package/src/generators/preset/workspace-files-workload-role-baseline.d.ts +9 -0
  268. package/src/generators/preset/workspace-files-workload-role-baseline.js +1102 -0
  269. package/src/generators/preset/workspace-files-workload-role-baseline.js.map +1 -0
  270. package/src/generators/preset/workspace-files.d.ts +14 -1
  271. package/src/generators/preset/workspace-files.js +8189 -245
  272. package/src/generators/preset/workspace-files.js.map +1 -1
  273. package/src/generators/repository-policy/repository-policy.js +3 -47
  274. package/src/generators/repository-policy/repository-policy.js.map +1 -1
  275. package/src/generators/slice/built-in-plan-api-contract-files.d.ts +2 -0
  276. package/src/generators/slice/built-in-plan-api-contract-files.js +2656 -0
  277. package/src/generators/slice/built-in-plan-api-contract-files.js.map +1 -0
  278. package/src/generators/slice/built-in-plan-api-files.d.ts +2 -0
  279. package/src/generators/slice/built-in-plan-api-files.js +1186 -0
  280. package/src/generators/slice/built-in-plan-api-files.js.map +1 -0
  281. package/src/generators/slice/built-in-plan-async-work-files.d.ts +2 -0
  282. package/src/generators/slice/built-in-plan-async-work-files.js +7903 -0
  283. package/src/generators/slice/built-in-plan-async-work-files.js.map +1 -0
  284. package/src/generators/slice/built-in-plan-authorization-files.d.ts +2 -0
  285. package/src/generators/slice/built-in-plan-authorization-files.js +2314 -0
  286. package/src/generators/slice/built-in-plan-authorization-files.js.map +1 -0
  287. package/src/generators/slice/built-in-plan-authorization-infrastructure-files.d.ts +2 -0
  288. package/src/generators/slice/built-in-plan-authorization-infrastructure-files.js +559 -0
  289. package/src/generators/slice/built-in-plan-authorization-infrastructure-files.js.map +1 -0
  290. package/src/generators/slice/built-in-plan-data-deletion-files.d.ts +2 -0
  291. package/src/generators/slice/built-in-plan-data-deletion-files.js +1101 -0
  292. package/src/generators/slice/built-in-plan-data-deletion-files.js.map +1 -0
  293. package/src/generators/slice/built-in-plan-data-export-infrastructure-files.d.ts +2 -0
  294. package/src/generators/slice/built-in-plan-data-export-infrastructure-files.js +249 -0
  295. package/src/generators/slice/built-in-plan-data-export-infrastructure-files.js.map +1 -0
  296. package/src/generators/slice/built-in-plan-data-files.d.ts +2 -0
  297. package/src/generators/slice/built-in-plan-data-files.js +1530 -0
  298. package/src/generators/slice/built-in-plan-data-files.js.map +1 -0
  299. package/src/generators/slice/built-in-plan-data-lifecycle-files.d.ts +2 -0
  300. package/src/generators/slice/built-in-plan-data-lifecycle-files.js +750 -0
  301. package/src/generators/slice/built-in-plan-data-lifecycle-files.js.map +1 -0
  302. package/src/generators/slice/built-in-plan-data-lifecycle-runtime-files.d.ts +2 -0
  303. package/src/generators/slice/built-in-plan-data-lifecycle-runtime-files.js +828 -0
  304. package/src/generators/slice/built-in-plan-data-lifecycle-runtime-files.js.map +1 -0
  305. package/src/generators/slice/built-in-plan-data-retention-job-files.d.ts +2 -0
  306. package/src/generators/slice/built-in-plan-data-retention-job-files.js +2604 -0
  307. package/src/generators/slice/built-in-plan-data-retention-job-files.js.map +1 -0
  308. package/src/generators/slice/built-in-plan-data-retention-launcher-files.d.ts +2 -0
  309. package/src/generators/slice/built-in-plan-data-retention-launcher-files.js +144 -0
  310. package/src/generators/slice/built-in-plan-data-retention-launcher-files.js.map +1 -0
  311. package/src/generators/slice/built-in-plan-data-rights-files.d.ts +2 -0
  312. package/src/generators/slice/built-in-plan-data-rights-files.js +4628 -0
  313. package/src/generators/slice/built-in-plan-data-rights-files.js.map +1 -0
  314. package/src/generators/slice/built-in-plan-database-lifecycle-files.d.ts +2 -0
  315. package/src/generators/slice/built-in-plan-database-lifecycle-files.js +1901 -0
  316. package/src/generators/slice/built-in-plan-database-lifecycle-files.js.map +1 -0
  317. package/src/generators/slice/built-in-plan-database-retirement-rehearsal-files.d.ts +2 -0
  318. package/src/generators/slice/built-in-plan-database-retirement-rehearsal-files.js +485 -0
  319. package/src/generators/slice/built-in-plan-database-retirement-rehearsal-files.js.map +1 -0
  320. package/src/generators/slice/built-in-plan-foundation-files.d.ts +2 -0
  321. package/src/generators/slice/built-in-plan-foundation-files.js +184 -0
  322. package/src/generators/slice/built-in-plan-foundation-files.js.map +1 -0
  323. package/src/generators/slice/built-in-plan-frontend-files.d.ts +2 -0
  324. package/src/generators/slice/built-in-plan-frontend-files.js +2233 -0
  325. package/src/generators/slice/built-in-plan-frontend-files.js.map +1 -0
  326. package/src/generators/slice/built-in-plan-infrastructure-files.d.ts +2 -0
  327. package/src/generators/slice/built-in-plan-infrastructure-files.js +3038 -0
  328. package/src/generators/slice/built-in-plan-infrastructure-files.js.map +1 -0
  329. package/src/generators/slice/built-in-plan-infrastructure-safety-files.d.ts +2 -0
  330. package/src/generators/slice/built-in-plan-infrastructure-safety-files.js +312 -0
  331. package/src/generators/slice/built-in-plan-infrastructure-safety-files.js.map +1 -0
  332. package/src/generators/slice/built-in-plan-metadata-files.d.ts +3 -0
  333. package/src/generators/slice/built-in-plan-metadata-files.js +219 -0
  334. package/src/generators/slice/built-in-plan-metadata-files.js.map +1 -0
  335. package/src/generators/slice/built-in-plan-operations-files.d.ts +2 -0
  336. package/src/generators/slice/built-in-plan-operations-files.js +630 -0
  337. package/src/generators/slice/built-in-plan-operations-files.js.map +1 -0
  338. package/src/generators/slice/built-in-plan-performance-files.d.ts +3 -0
  339. package/src/generators/slice/built-in-plan-performance-files.js +3293 -0
  340. package/src/generators/slice/built-in-plan-performance-files.js.map +1 -0
  341. package/src/generators/slice/built-in-plan-project-files.d.ts +3 -0
  342. package/src/generators/slice/built-in-plan-project-files.js +979 -0
  343. package/src/generators/slice/built-in-plan-project-files.js.map +1 -0
  344. package/src/generators/slice/built-in-plan-release-files.d.ts +2 -0
  345. package/src/generators/slice/built-in-plan-release-files.js +6387 -0
  346. package/src/generators/slice/built-in-plan-release-files.js.map +1 -0
  347. package/src/generators/slice/built-in-plan-reliability-files.d.ts +2 -0
  348. package/src/generators/slice/built-in-plan-reliability-files.js +4499 -0
  349. package/src/generators/slice/built-in-plan-reliability-files.js.map +1 -0
  350. package/src/generators/slice/built-in-plan-secret-runtime-files.d.ts +2 -0
  351. package/src/generators/slice/built-in-plan-secret-runtime-files.js +1004 -0
  352. package/src/generators/slice/built-in-plan-secret-runtime-files.js.map +1 -0
  353. package/src/generators/slice/built-in-plan-shared.d.ts +53 -0
  354. package/src/generators/slice/built-in-plan-shared.js +113 -0
  355. package/src/generators/slice/built-in-plan-shared.js.map +1 -0
  356. package/src/generators/slice/built-in-plan-testing-files.d.ts +2 -0
  357. package/src/generators/slice/built-in-plan-testing-files.js +2356 -0
  358. package/src/generators/slice/built-in-plan-testing-files.js.map +1 -0
  359. package/src/generators/slice/built-in-plan-verification-files.d.ts +2 -0
  360. package/src/generators/slice/built-in-plan-verification-files.js +358 -0
  361. package/src/generators/slice/built-in-plan-verification-files.js.map +1 -0
  362. package/src/generators/slice/built-in-plan-web-files.d.ts +2 -0
  363. package/src/generators/slice/built-in-plan-web-files.js +430 -0
  364. package/src/generators/slice/built-in-plan-web-files.js.map +1 -0
  365. package/src/generators/slice/built-in-plan-workload-role-files.d.ts +2 -0
  366. package/src/generators/slice/built-in-plan-workload-role-files.js +2356 -0
  367. package/src/generators/slice/built-in-plan-workload-role-files.js.map +1 -0
  368. package/src/generators/slice/built-in-plan.d.ts +8 -0
  369. package/src/generators/slice/built-in-plan.js +264 -0
  370. package/src/generators/slice/built-in-plan.js.map +1 -0
  371. package/src/generators/slice/schema.json +1 -1
  372. package/src/generators/slice/slice.d.ts +1 -22
  373. package/src/generators/slice/slice.js +185 -1510
  374. package/src/generators/slice/slice.js.map +1 -1
  375. package/src/generators/upgrade/schema.d.ts +2 -0
  376. package/src/generators/upgrade/schema.json +11 -1
  377. package/src/generators/upgrade/upgrade.d.ts +51 -1
  378. package/src/generators/upgrade/upgrade.js +820 -82
  379. package/src/generators/upgrade/upgrade.js.map +1 -1
  380. package/src/generators/workload/frozen-container.d.ts +8 -0
  381. package/src/generators/workload/frozen-container.js +36 -0
  382. package/src/generators/workload/frozen-container.js.map +1 -0
  383. package/src/generators/workload/performance-registration.d.ts +32 -0
  384. package/src/generators/workload/performance-registration.js +226 -0
  385. package/src/generators/workload/performance-registration.js.map +1 -0
  386. package/src/generators/workload/reliability-registration.d.ts +16 -0
  387. package/src/generators/workload/reliability-registration.js +150 -0
  388. package/src/generators/workload/reliability-registration.js.map +1 -0
  389. package/src/generators/workload/schema.d.ts +1 -0
  390. package/src/generators/workload/schema.json +6 -1
  391. package/src/generators/workload/service-performance-files.d.ts +4 -0
  392. package/src/generators/workload/service-performance-files.js +1846 -0
  393. package/src/generators/workload/service-performance-files.js.map +1 -0
  394. package/src/generators/workload/workload.d.ts +3 -2
  395. package/src/generators/workload/workload.js +1083 -18
  396. package/src/generators/workload/workload.js.map +1 -1
  397. package/src/git-policy/action-pins.d.ts +10 -0
  398. package/src/git-policy/action-pins.js +10 -0
  399. package/src/git-policy/action-pins.js.map +1 -1
  400. package/src/git-policy/github-bootstrap.d.ts +14 -1
  401. package/src/git-policy/github-bootstrap.js +274 -46
  402. package/src/git-policy/github-bootstrap.js.map +1 -1
  403. package/src/index.d.ts +2 -0
  404. package/src/index.js +2 -0
  405. package/src/index.js.map +1 -1
  406. package/src/infrastructure-change/convergence.d.ts +13 -0
  407. package/src/infrastructure-change/convergence.js +85 -0
  408. package/src/infrastructure-change/convergence.js.map +1 -0
  409. package/src/infrastructure-change/drift.d.ts +13 -0
  410. package/src/infrastructure-change/drift.js +112 -0
  411. package/src/infrastructure-change/drift.js.map +1 -0
  412. package/src/infrastructure-change/index.d.ts +7 -0
  413. package/src/infrastructure-change/index.js +11 -0
  414. package/src/infrastructure-change/index.js.map +1 -0
  415. package/src/infrastructure-change/model.d.ts +253 -0
  416. package/src/infrastructure-change/model.js +28 -0
  417. package/src/infrastructure-change/model.js.map +1 -0
  418. package/src/infrastructure-change/normalize.d.ts +12 -0
  419. package/src/infrastructure-change/normalize.js +245 -0
  420. package/src/infrastructure-change/normalize.js.map +1 -0
  421. package/src/infrastructure-change/plan.d.ts +40 -0
  422. package/src/infrastructure-change/plan.js +361 -0
  423. package/src/infrastructure-change/plan.js.map +1 -0
  424. package/src/infrastructure-change/risk.d.ts +7 -0
  425. package/src/infrastructure-change/risk.js +269 -0
  426. package/src/infrastructure-change/risk.js.map +1 -0
  427. package/src/infrastructure-change/summary.d.ts +20 -0
  428. package/src/infrastructure-change/summary.js +130 -0
  429. package/src/infrastructure-change/summary.js.map +1 -0
  430. package/src/local-dev/context-discovery.d.ts +2 -0
  431. package/src/local-dev/context-discovery.js +59 -0
  432. package/src/local-dev/context-discovery.js.map +1 -0
  433. package/src/local-dev/contract-validation.d.ts +15 -0
  434. package/src/local-dev/contract-validation.js +84 -0
  435. package/src/local-dev/contract-validation.js.map +1 -0
  436. package/src/local-dev/contracts.d.ts +10 -1
  437. package/src/local-dev/contracts.js +57 -5
  438. package/src/local-dev/contracts.js.map +1 -1
  439. package/src/local-dev/control-contract.d.ts +67 -0
  440. package/src/local-dev/control-contract.js +180 -0
  441. package/src/local-dev/control-contract.js.map +1 -0
  442. package/src/local-dev/dev-command-core.d.ts +60 -0
  443. package/src/local-dev/dev-command-core.js +89 -0
  444. package/src/local-dev/dev-command-core.js.map +1 -0
  445. package/src/local-dev/effects.d.ts +16 -0
  446. package/src/local-dev/effects.js +63 -0
  447. package/src/local-dev/effects.js.map +1 -0
  448. package/src/local-dev/environment-inspector.d.ts +125 -0
  449. package/src/local-dev/environment-inspector.js +687 -0
  450. package/src/local-dev/environment-inspector.js.map +1 -0
  451. package/src/local-dev/environment-state.d.ts +113 -0
  452. package/src/local-dev/environment-state.js +463 -0
  453. package/src/local-dev/environment-state.js.map +1 -0
  454. package/src/local-dev/errors.d.ts +6 -0
  455. package/src/local-dev/errors.js +41 -0
  456. package/src/local-dev/errors.js.map +1 -0
  457. package/src/local-dev/fleet-client.d.ts +33 -0
  458. package/src/local-dev/fleet-client.js +156 -0
  459. package/src/local-dev/fleet-client.js.map +1 -0
  460. package/src/local-dev/fleet-configuration.d.ts +13 -0
  461. package/src/local-dev/fleet-configuration.js +71 -0
  462. package/src/local-dev/fleet-configuration.js.map +1 -0
  463. package/src/local-dev/fleet-inventory.d.ts +56 -0
  464. package/src/local-dev/fleet-inventory.js +469 -0
  465. package/src/local-dev/fleet-inventory.js.map +1 -0
  466. package/src/local-dev/fleet-ipc.d.ts +28 -0
  467. package/src/local-dev/fleet-ipc.js +267 -0
  468. package/src/local-dev/fleet-ipc.js.map +1 -0
  469. package/src/local-dev/fleet-launcher.d.ts +53 -0
  470. package/src/local-dev/fleet-launcher.js +379 -0
  471. package/src/local-dev/fleet-launcher.js.map +1 -0
  472. package/src/local-dev/fleet-lock.d.ts +41 -0
  473. package/src/local-dev/fleet-lock.js +135 -0
  474. package/src/local-dev/fleet-lock.js.map +1 -0
  475. package/src/local-dev/fleet-logs.d.ts +66 -0
  476. package/src/local-dev/fleet-logs.js +542 -0
  477. package/src/local-dev/fleet-logs.js.map +1 -0
  478. package/src/local-dev/fleet-process.d.ts +50 -0
  479. package/src/local-dev/fleet-process.js +289 -0
  480. package/src/local-dev/fleet-process.js.map +1 -0
  481. package/src/local-dev/fleet-runtime.d.ts +22 -0
  482. package/src/local-dev/fleet-runtime.js +368 -0
  483. package/src/local-dev/fleet-runtime.js.map +1 -0
  484. package/src/local-dev/fleet-session.d.ts +70 -0
  485. package/src/local-dev/fleet-session.js +301 -0
  486. package/src/local-dev/fleet-session.js.map +1 -0
  487. package/src/local-dev/fleet-slice-runner-daemon.d.ts +1 -0
  488. package/src/local-dev/fleet-slice-runner-daemon.js +21 -0
  489. package/src/local-dev/fleet-slice-runner-daemon.js.map +1 -0
  490. package/src/local-dev/fleet-startup.d.ts +22 -0
  491. package/src/local-dev/fleet-startup.js +114 -0
  492. package/src/local-dev/fleet-startup.js.map +1 -0
  493. package/src/local-dev/fleet-state.d.ts +62 -0
  494. package/src/local-dev/fleet-state.js +297 -0
  495. package/src/local-dev/fleet-state.js.map +1 -0
  496. package/src/local-dev/fleet-supervisor-daemon.d.ts +1 -0
  497. package/src/local-dev/fleet-supervisor-daemon.js +41 -0
  498. package/src/local-dev/fleet-supervisor-daemon.js.map +1 -0
  499. package/src/local-dev/fleet-supervisor.d.ts +52 -0
  500. package/src/local-dev/fleet-supervisor.js +384 -0
  501. package/src/local-dev/fleet-supervisor.js.map +1 -0
  502. package/src/local-dev/gateway.js +1 -1
  503. package/src/local-dev/gateway.js.map +1 -1
  504. package/src/local-dev/identity.js +4 -6
  505. package/src/local-dev/identity.js.map +1 -1
  506. package/src/local-dev/index.d.ts +1 -0
  507. package/src/local-dev/index.js +1 -0
  508. package/src/local-dev/index.js.map +1 -1
  509. package/src/local-dev/local-context.d.ts +62 -0
  510. package/src/local-dev/local-context.js +299 -0
  511. package/src/local-dev/local-context.js.map +1 -0
  512. package/src/local-dev/nx-workspace.d.ts +45 -0
  513. package/src/local-dev/nx-workspace.js +228 -0
  514. package/src/local-dev/nx-workspace.js.map +1 -0
  515. package/src/local-dev/personal-secret-ledger.d.ts +75 -0
  516. package/src/local-dev/personal-secret-ledger.js +391 -0
  517. package/src/local-dev/personal-secret-ledger.js.map +1 -0
  518. package/src/local-dev/personal-stage.d.ts +18 -0
  519. package/src/local-dev/personal-stage.js +129 -0
  520. package/src/local-dev/personal-stage.js.map +1 -0
  521. package/src/local-dev/private-state.d.ts +17 -0
  522. package/src/local-dev/private-state.js +254 -0
  523. package/src/local-dev/private-state.js.map +1 -0
  524. package/src/local-dev/process-identity.d.ts +9 -0
  525. package/src/local-dev/process-identity.js +79 -0
  526. package/src/local-dev/process-identity.js.map +1 -0
  527. package/src/local-dev/runtime-paths.d.ts +17 -0
  528. package/src/local-dev/runtime-paths.js +33 -0
  529. package/src/local-dev/runtime-paths.js.map +1 -0
  530. package/src/local-dev/secret-slice-claim.d.ts +17 -0
  531. package/src/local-dev/secret-slice-claim.js +75 -0
  532. package/src/local-dev/secret-slice-claim.js.map +1 -0
  533. package/src/local-dev/slice-claim.d.ts +36 -0
  534. package/src/local-dev/slice-claim.js +199 -0
  535. package/src/local-dev/slice-claim.js.map +1 -0
  536. package/src/local-dev/slice-runner.d.ts +121 -0
  537. package/src/local-dev/slice-runner.js +715 -0
  538. package/src/local-dev/slice-runner.js.map +1 -0
  539. package/src/local-dev/tls.js +51 -17
  540. package/src/local-dev/tls.js.map +1 -1
  541. package/src/ownership/composition.d.ts +5 -2
  542. package/src/ownership/composition.js +26 -3
  543. package/src/ownership/composition.js.map +1 -1
  544. package/src/ownership/hash.d.ts +1 -1
  545. package/src/ownership/hash.js +3 -1
  546. package/src/ownership/hash.js.map +1 -1
  547. package/src/ownership/record.d.ts +32 -1
  548. package/src/ownership/record.js +139 -2
  549. package/src/ownership/record.js.map +1 -1
  550. package/src/performance/cost-collection.d.ts +225 -0
  551. package/src/performance/cost-collection.js +825 -0
  552. package/src/performance/cost-collection.js.map +1 -0
  553. package/src/performance/cost-controls.d.ts +131 -0
  554. package/src/performance/cost-controls.js +336 -0
  555. package/src/performance/cost-controls.js.map +1 -0
  556. package/src/performance/evidence.d.ts +140 -0
  557. package/src/performance/evidence.js +599 -0
  558. package/src/performance/evidence.js.map +1 -0
  559. package/src/performance/index.d.ts +10 -0
  560. package/src/performance/index.js +14 -0
  561. package/src/performance/index.js.map +1 -0
  562. package/src/performance/load-safety.d.ts +84 -0
  563. package/src/performance/load-safety.js +346 -0
  564. package/src/performance/load-safety.js.map +1 -0
  565. package/src/performance/model.d.ts +129 -0
  566. package/src/performance/model.js +452 -0
  567. package/src/performance/model.js.map +1 -0
  568. package/src/performance/pr-artifact-budget.d.ts +42 -0
  569. package/src/performance/pr-artifact-budget.js +151 -0
  570. package/src/performance/pr-artifact-budget.js.map +1 -0
  571. package/src/performance/runner.d.ts +75 -0
  572. package/src/performance/runner.js +227 -0
  573. package/src/performance/runner.js.map +1 -0
  574. package/src/performance/scenario-endpoint.d.ts +1 -0
  575. package/src/performance/scenario-endpoint.js +5 -0
  576. package/src/performance/scenario-endpoint.js.map +1 -0
  577. package/src/performance/scenario.d.ts +193 -0
  578. package/src/performance/scenario.js +736 -0
  579. package/src/performance/scenario.js.map +1 -0
  580. package/src/performance/test-fixtures.d.ts +7 -0
  581. package/src/performance/test-fixtures.js +169 -0
  582. package/src/performance/test-fixtures.js.map +1 -0
  583. package/src/performance/unit-cost.d.ts +105 -0
  584. package/src/performance/unit-cost.js +364 -0
  585. package/src/performance/unit-cost.js.map +1 -0
  586. package/src/release/index.d.ts +4 -0
  587. package/src/release/index.js +8 -0
  588. package/src/release/index.js.map +1 -0
  589. package/src/release/lifecycle.d.ts +132 -0
  590. package/src/release/lifecycle.js +411 -0
  591. package/src/release/lifecycle.js.map +1 -0
  592. package/src/release/manifest.d.ts +148 -0
  593. package/src/release/manifest.js +503 -0
  594. package/src/release/manifest.js.map +1 -0
  595. package/src/release/rollout.d.ts +170 -0
  596. package/src/release/rollout.js +578 -0
  597. package/src/release/rollout.js.map +1 -0
  598. package/src/release/source-authority.d.ts +19 -0
  599. package/src/release/source-authority.js +195 -0
  600. package/src/release/source-authority.js.map +1 -0
  601. package/src/repository-policy/deployment-plan.d.ts +2 -1
  602. package/src/repository-policy/deployment-plan.js +2 -0
  603. package/src/repository-policy/deployment-plan.js.map +1 -1
  604. package/src/repository-policy/policy.d.ts +1 -1
  605. package/src/repository-policy/policy.js +29 -25
  606. package/src/repository-policy/policy.js.map +1 -1
  607. package/src/schemas/aggregate-count-evidence-v1.json +135 -0
  608. package/src/schemas/api-contract-baseline-v1.json +674 -0
  609. package/src/schemas/api-contract-compatibility-report-v1.json +126 -0
  610. package/src/schemas/aws-billing-actual-evidence-v1.json +407 -0
  611. package/src/schemas/blueprint-v1.json +18 -1
  612. package/src/schemas/data-lifecycle-policy-v1.json +517 -0
  613. package/src/schemas/generated-ownership-v2.json +22 -0
  614. package/src/schemas/performance-policy-v1.json +335 -0
  615. package/src/schemas/repository-policy-v1.json +1 -0
  616. package/src/schemas/testing-evidence-quarantine-v1.json +168 -0
  617. package/src/schemas/testing-evidence-result-v1.json +319 -0
  618. package/src/secrets/adapters.d.ts +49 -0
  619. package/src/secrets/adapters.js +184 -0
  620. package/src/secrets/adapters.js.map +1 -0
  621. package/src/secrets/aws-control-plane.d.ts +20 -0
  622. package/src/secrets/aws-control-plane.js +255 -0
  623. package/src/secrets/aws-control-plane.js.map +1 -0
  624. package/src/secrets/declaration-verification.d.ts +11 -0
  625. package/src/secrets/declaration-verification.js +68 -0
  626. package/src/secrets/declaration-verification.js.map +1 -0
  627. package/src/secrets/guardrails.d.ts +26 -0
  628. package/src/secrets/guardrails.js +328 -0
  629. package/src/secrets/guardrails.js.map +1 -0
  630. package/src/secrets/index.d.ts +12 -0
  631. package/src/secrets/index.js +16 -0
  632. package/src/secrets/index.js.map +1 -0
  633. package/src/secrets/metadata.d.ts +48 -0
  634. package/src/secrets/metadata.js +171 -0
  635. package/src/secrets/metadata.js.map +1 -0
  636. package/src/secrets/model.d.ts +49 -0
  637. package/src/secrets/model.js +125 -0
  638. package/src/secrets/model.js.map +1 -0
  639. package/src/secrets/operator.d.ts +101 -0
  640. package/src/secrets/operator.js +229 -0
  641. package/src/secrets/operator.js.map +1 -0
  642. package/src/secrets/permissions.d.ts +34 -0
  643. package/src/secrets/permissions.js +86 -0
  644. package/src/secrets/permissions.js.map +1 -0
  645. package/src/secrets/personal-command.d.ts +83 -0
  646. package/src/secrets/personal-command.js +197 -0
  647. package/src/secrets/personal-command.js.map +1 -0
  648. package/src/secrets/personal-ledger.d.ts +21 -0
  649. package/src/secrets/personal-ledger.js +135 -0
  650. package/src/secrets/personal-ledger.js.map +1 -0
  651. package/src/secrets/registry.d.ts +9 -0
  652. package/src/secrets/registry.js +86 -0
  653. package/src/secrets/registry.js.map +1 -0
  654. package/src/secrets/verification.d.ts +18 -0
  655. package/src/secrets/verification.js +139 -0
  656. package/src/secrets/verification.js.map +1 -0
  657. package/src/secrets/workload-access.d.ts +46 -0
  658. package/src/secrets/workload-access.js +163 -0
  659. package/src/secrets/workload-access.js.map +1 -0
  660. package/src/supply-chain/action-pins.d.ts +26 -0
  661. package/src/supply-chain/action-pins.js +208 -0
  662. package/src/supply-chain/action-pins.js.map +1 -0
  663. package/src/supply-chain/blueprint-trust-git.d.ts +130 -0
  664. package/src/supply-chain/blueprint-trust-git.js +1581 -0
  665. package/src/supply-chain/blueprint-trust-git.js.map +1 -0
  666. package/src/supply-chain/blueprint-trust-process.d.ts +4 -0
  667. package/src/supply-chain/blueprint-trust-process.js +88 -0
  668. package/src/supply-chain/blueprint-trust-process.js.map +1 -0
  669. package/src/supply-chain/blueprint-trust.d.ts +354 -0
  670. package/src/supply-chain/blueprint-trust.js +1558 -0
  671. package/src/supply-chain/blueprint-trust.js.map +1 -0
  672. package/src/supply-chain/blueprint-verification-authority.d.ts +62 -0
  673. package/src/supply-chain/blueprint-verification-authority.js +588 -0
  674. package/src/supply-chain/blueprint-verification-authority.js.map +1 -0
  675. package/src/supply-chain/blueprint-verification-execution.d.ts +68 -0
  676. package/src/supply-chain/blueprint-verification-execution.js +624 -0
  677. package/src/supply-chain/blueprint-verification-execution.js.map +1 -0
  678. package/src/supply-chain/build-output.d.ts +35 -0
  679. package/src/supply-chain/build-output.js +398 -0
  680. package/src/supply-chain/build-output.js.map +1 -0
  681. package/src/supply-chain/common.d.ts +21 -0
  682. package/src/supply-chain/common.js +107 -0
  683. package/src/supply-chain/common.js.map +1 -0
  684. package/src/supply-chain/container-artifact-contract.d.ts +23 -0
  685. package/src/supply-chain/container-artifact-contract.js +208 -0
  686. package/src/supply-chain/container-artifact-contract.js.map +1 -0
  687. package/src/supply-chain/container-release.d.ts +119 -0
  688. package/src/supply-chain/container-release.js +496 -0
  689. package/src/supply-chain/container-release.js.map +1 -0
  690. package/src/supply-chain/ecr-applicability.d.ts +19 -0
  691. package/src/supply-chain/ecr-applicability.js +103 -0
  692. package/src/supply-chain/ecr-applicability.js.map +1 -0
  693. package/src/supply-chain/ecr-scanning.d.ts +83 -0
  694. package/src/supply-chain/ecr-scanning.js +321 -0
  695. package/src/supply-chain/ecr-scanning.js.map +1 -0
  696. package/src/supply-chain/ecs-deployed-image.d.ts +85 -0
  697. package/src/supply-chain/ecs-deployed-image.js +300 -0
  698. package/src/supply-chain/ecs-deployed-image.js.map +1 -0
  699. package/src/supply-chain/errors.d.ts +6 -0
  700. package/src/supply-chain/errors.js +15 -0
  701. package/src/supply-chain/errors.js.map +1 -0
  702. package/src/supply-chain/generated-blueprint-trust-command.d.ts +4 -0
  703. package/src/supply-chain/generated-blueprint-trust-command.js +1362 -0
  704. package/src/supply-chain/generated-blueprint-trust-command.js.map +1 -0
  705. package/src/supply-chain/generated-command.d.ts +1 -0
  706. package/src/supply-chain/generated-command.js +687 -0
  707. package/src/supply-chain/generated-command.js.map +1 -0
  708. package/src/supply-chain/generated-container-release-command.d.ts +16 -0
  709. package/src/supply-chain/generated-container-release-command.js +2087 -0
  710. package/src/supply-chain/generated-container-release-command.js.map +1 -0
  711. package/src/supply-chain/generated-ecr-collector-command.d.ts +21 -0
  712. package/src/supply-chain/generated-ecr-collector-command.js +1338 -0
  713. package/src/supply-chain/generated-ecr-collector-command.js.map +1 -0
  714. package/src/supply-chain/generated-files.d.ts +13 -0
  715. package/src/supply-chain/generated-files.js +401 -0
  716. package/src/supply-chain/generated-files.js.map +1 -0
  717. package/src/supply-chain/generated-scanner-command.d.ts +1 -0
  718. package/src/supply-chain/generated-scanner-command.js +718 -0
  719. package/src/supply-chain/generated-scanner-command.js.map +1 -0
  720. package/src/supply-chain/index.d.ts +28 -0
  721. package/src/supply-chain/index.js +35 -0
  722. package/src/supply-chain/index.js.map +1 -0
  723. package/src/supply-chain/inventory.d.ts +79 -0
  724. package/src/supply-chain/inventory.js +717 -0
  725. package/src/supply-chain/inventory.js.map +1 -0
  726. package/src/supply-chain/license-expression.d.ts +7 -0
  727. package/src/supply-chain/license-expression.js +128 -0
  728. package/src/supply-chain/license-expression.js.map +1 -0
  729. package/src/supply-chain/pnpm-toolchain-authority.d.ts +31 -0
  730. package/src/supply-chain/pnpm-toolchain-authority.js +316 -0
  731. package/src/supply-chain/pnpm-toolchain-authority.js.map +1 -0
  732. package/src/supply-chain/policy.d.ts +105 -0
  733. package/src/supply-chain/policy.js +301 -0
  734. package/src/supply-chain/policy.js.map +1 -0
  735. package/src/supply-chain/publication.d.ts +48 -0
  736. package/src/supply-chain/publication.js +85 -0
  737. package/src/supply-chain/publication.js.map +1 -0
  738. package/src/supply-chain/sbom.d.ts +228 -0
  739. package/src/supply-chain/sbom.js +826 -0
  740. package/src/supply-chain/sbom.js.map +1 -0
  741. package/src/supply-chain/scanner.d.ts +77 -0
  742. package/src/supply-chain/scanner.js +502 -0
  743. package/src/supply-chain/scanner.js.map +1 -0
  744. package/src/supply-chain/vendored-source.d.ts +95 -0
  745. package/src/supply-chain/vendored-source.js +315 -0
  746. package/src/supply-chain/vendored-source.js.map +1 -0
  747. package/src/testing-evidence/fixture-scope.d.ts +52 -0
  748. package/src/testing-evidence/fixture-scope.js +140 -0
  749. package/src/testing-evidence/fixture-scope.js.map +1 -0
  750. package/src/testing-evidence/index.d.ts +5 -0
  751. package/src/testing-evidence/index.js +9 -0
  752. package/src/testing-evidence/index.js.map +1 -0
  753. package/src/testing-evidence/quarantine.d.ts +48 -0
  754. package/src/testing-evidence/quarantine.js +253 -0
  755. package/src/testing-evidence/quarantine.js.map +1 -0
  756. package/src/testing-evidence/result.d.ts +108 -0
  757. package/src/testing-evidence/result.js +571 -0
  758. package/src/testing-evidence/result.js.map +1 -0
  759. package/src/testing-evidence/runner-adapter.d.ts +51 -0
  760. package/src/testing-evidence/runner-adapter.js +288 -0
  761. package/src/testing-evidence/runner-adapter.js.map +1 -0
  762. package/src/testing-evidence/sensitive-artifacts.d.ts +13 -0
  763. package/src/testing-evidence/sensitive-artifacts.js +93 -0
  764. package/src/testing-evidence/sensitive-artifacts.js.map +1 -0
  765. package/src/work-markers/work-markers.js +4 -3
  766. package/src/work-markers/work-markers.js.map +1 -1
  767. package/src/workload-roles/account-baseline.d.ts +132 -0
  768. package/src/workload-roles/account-baseline.js +743 -0
  769. package/src/workload-roles/account-baseline.js.map +1 -0
  770. package/src/workload-roles/authority.d.ts +38 -0
  771. package/src/workload-roles/authority.js +156 -0
  772. package/src/workload-roles/authority.js.map +1 -0
  773. package/src/workload-roles/aws-adapter.d.ts +99 -0
  774. package/src/workload-roles/aws-adapter.js +416 -0
  775. package/src/workload-roles/aws-adapter.js.map +1 -0
  776. package/src/workload-roles/aws-internal-handler.d.ts +27 -0
  777. package/src/workload-roles/aws-internal-handler.js +58 -0
  778. package/src/workload-roles/aws-internal-handler.js.map +1 -0
  779. package/src/workload-roles/aws-s3-state.d.ts +52 -0
  780. package/src/workload-roles/aws-s3-state.js +164 -0
  781. package/src/workload-roles/aws-s3-state.js.map +1 -0
  782. package/src/workload-roles/aws-sdk-control-plane.d.ts +12 -0
  783. package/src/workload-roles/aws-sdk-control-plane.js +291 -0
  784. package/src/workload-roles/aws-sdk-control-plane.js.map +1 -0
  785. package/src/workload-roles/boundary.d.ts +33 -0
  786. package/src/workload-roles/boundary.js +130 -0
  787. package/src/workload-roles/boundary.js.map +1 -0
  788. package/src/workload-roles/convergence.d.ts +66 -0
  789. package/src/workload-roles/convergence.js +186 -0
  790. package/src/workload-roles/convergence.js.map +1 -0
  791. package/src/workload-roles/effective-policy.d.ts +51 -0
  792. package/src/workload-roles/effective-policy.js +183 -0
  793. package/src/workload-roles/effective-policy.js.map +1 -0
  794. package/src/workload-roles/handler.d.ts +43 -0
  795. package/src/workload-roles/handler.js +130 -0
  796. package/src/workload-roles/handler.js.map +1 -0
  797. package/src/workload-roles/history.d.ts +47 -0
  798. package/src/workload-roles/history.js +324 -0
  799. package/src/workload-roles/history.js.map +1 -0
  800. package/src/workload-roles/index.d.ts +17 -0
  801. package/src/workload-roles/index.js +21 -0
  802. package/src/workload-roles/index.js.map +1 -0
  803. package/src/workload-roles/injection.d.ts +119 -0
  804. package/src/workload-roles/injection.js +495 -0
  805. package/src/workload-roles/injection.js.map +1 -0
  806. package/src/workload-roles/manifest.d.ts +54 -0
  807. package/src/workload-roles/manifest.js +343 -0
  808. package/src/workload-roles/manifest.js.map +1 -0
  809. package/src/workload-roles/provisioner.d.ts +70 -0
  810. package/src/workload-roles/provisioner.js +231 -0
  811. package/src/workload-roles/provisioner.js.map +1 -0
  812. package/src/workload-roles/registration.d.ts +101 -0
  813. package/src/workload-roles/registration.js +457 -0
  814. package/src/workload-roles/registration.js.map +1 -0
  815. package/src/workload-roles/stage-boundary.d.ts +31 -0
  816. package/src/workload-roles/stage-boundary.js +208 -0
  817. package/src/workload-roles/stage-boundary.js.map +1 -0
  818. package/src/workload-roles/standard-slice.d.ts +54 -0
  819. package/src/workload-roles/standard-slice.js +252 -0
  820. package/src/workload-roles/standard-slice.js.map +1 -0
  821. package/migrations/standard-pre-v1-to-v1.md +0 -11
  822. package/src/foundation/aurora-logical-database.d.ts +0 -76
  823. package/src/foundation/aurora-logical-database.js +0 -419
  824. package/src/foundation/aurora-logical-database.js.map +0 -1
@@ -0,0 +1,2356 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.renderStandardSliceWorkloadRoleFiles = renderStandardSliceWorkloadRoleFiles;
4
+ /** @internal */
5
+ function renderStandardSliceWorkloadRoleFiles(name, workspace) {
6
+ return {
7
+ 'infra/workload-roles/candidate.ts': `import { createDatabaseBindingPlan } from '@empire-builder-kit/nx/foundation';
8
+ import type { WorkloadSecretReferenceInput } from '@empire-builder-kit/nx/secrets';
9
+ import {
10
+ createStandardSliceWorkloadRoleCandidate,
11
+ createStandardSliceWorkloadRoleTopology as createWorkloadRoleTopology,
12
+ type RegisteredWorkloadRoleManifestDocument,
13
+ type StandardSliceServiceAdapterMetadata,
14
+ type StandardSliceWorkloadExtension,
15
+ } from '@empire-builder-kit/nx/workload-roles';
16
+ import databaseBindings from '../../database/bindings.json';
17
+ import performanceOperations from '../../operations/performance.json';
18
+ import {
19
+ createStandardSliceWorkloadRoleIntents,
20
+ type StandardSliceWorkloadRoleIntentContext,
21
+ } from './effective-intent.js';
22
+
23
+ export const STANDARD_SLICE_WORKLOAD_EXTENSIONS = [
24
+ // <ebk:workload-role-extensions:start>
25
+ // <ebk:workload-role-extensions:end>
26
+ ] as const satisfies readonly StandardSliceWorkloadExtension[];
27
+
28
+ function standardSliceServiceAdapterMetadata(
29
+ value: unknown,
30
+ ): StandardSliceServiceAdapterMetadata {
31
+ if (value === null || typeof value !== 'object' || Array.isArray(value)) {
32
+ throw new Error('Performance operations must be an object.');
33
+ }
34
+ const load = (value as { load?: unknown }).load;
35
+ if (load === null || typeof load !== 'object' || Array.isArray(load)) {
36
+ throw new Error('Performance operations load authority must be an object.');
37
+ }
38
+ const owner = (load as { serviceAdapterOwner?: unknown })
39
+ .serviceAdapterOwner;
40
+ const status = (load as { serviceAdapterStatus?: unknown })
41
+ .serviceAdapterStatus;
42
+ if (
43
+ (status === 'requires-adopter-service-runtime-endpoint' &&
44
+ owner === null) ||
45
+ (status === 'managed-generated-service-runtime-endpoint' &&
46
+ typeof owner === 'string' &&
47
+ owner.length > 0)
48
+ ) {
49
+ return { owner, status };
50
+ }
51
+ throw new Error(
52
+ 'Performance operations Service adapter authority is inconsistent.',
53
+ );
54
+ }
55
+
56
+ const STANDARD_SLICE_SERVICE_ADAPTER =
57
+ standardSliceServiceAdapterMetadata(performanceOperations);
58
+
59
+ function provisionedDatabaseIdentifiers(stage: string) {
60
+ return createDatabaseBindingPlan(databaseBindings, {
61
+ slice: '${name}',
62
+ stage,
63
+ }).provisioned;
64
+ }
65
+
66
+ export function createStandardSliceWorkloadRoleTopology(stage: string) {
67
+ return createWorkloadRoleTopology({
68
+ databaseIdentifiers: provisionedDatabaseIdentifiers(stage),
69
+ extensions: STANDARD_SLICE_WORKLOAD_EXTENSIONS,
70
+ serviceAdapter: STANDARD_SLICE_SERVICE_ADAPTER,
71
+ slice: '${name}',
72
+ });
73
+ }
74
+
75
+ export function createStandardSliceCandidate(options: {
76
+ accountId: string;
77
+ candidateIdentity: string;
78
+ intentContext: StandardSliceWorkloadRoleIntentContext;
79
+ partition: string;
80
+ secretReferences: readonly WorkloadSecretReferenceInput[];
81
+ stage: string;
82
+ }) {
83
+ const topology = createStandardSliceWorkloadRoleTopology(options.stage);
84
+ return createStandardSliceWorkloadRoleCandidate({
85
+ accountId: options.accountId,
86
+ candidateIdentity: options.candidateIdentity,
87
+ databaseIdentifiers: provisionedDatabaseIdentifiers(options.stage),
88
+ extensions: STANDARD_SLICE_WORKLOAD_EXTENSIONS,
89
+ intentsByRole: createStandardSliceWorkloadRoleIntents(
90
+ options.intentContext,
91
+ topology,
92
+ options.secretReferences,
93
+ ),
94
+ partition: options.partition,
95
+ serviceAdapter: STANDARD_SLICE_SERVICE_ADAPTER,
96
+ slice: '${name}',
97
+ stage: options.stage,
98
+ });
99
+ }
100
+
101
+ export function recreateRegisteredStandardSliceCandidate(
102
+ document: RegisteredWorkloadRoleManifestDocument,
103
+ intentContext: StandardSliceWorkloadRoleIntentContext,
104
+ secretReferences: readonly WorkloadSecretReferenceInput[],
105
+ ) {
106
+ return createStandardSliceCandidate({
107
+ accountId: document.accountId,
108
+ candidateIdentity: document.manifest.candidate.identity,
109
+ intentContext,
110
+ partition: document.partition,
111
+ secretReferences,
112
+ stage: document.manifest.candidate.stage,
113
+ });
114
+ }
115
+ `,
116
+ 'infra/workload-roles/effective-intent.ts': `import { createHash } from 'node:crypto';
117
+ import { createDatabaseBindingPlan } from '@empire-builder-kit/nx/foundation';
118
+ import {
119
+ createSecretWorkloadAccessPlan,
120
+ parseSecretWorkloadAccessRegistry,
121
+ toOperatorSecretMetadataDeclarations,
122
+ validateSecretWorkloadAccessTargets,
123
+ type SecretMetadataDeclaration,
124
+ type SecretWorkloadAccessPlanEntry,
125
+ type WorkloadSecretReferenceInput,
126
+ } from '@empire-builder-kit/nx/secrets';
127
+ import { containerReleaseRepositoryName } from '@empire-builder-kit/nx/supply-chain';
128
+ import {
129
+ standardSliceWorkloadRoleName,
130
+ type StandardSliceWorkloadExtensionKind,
131
+ type StandardSliceWorkloadRoleTopology,
132
+ type WorkloadRolePermissionIntent,
133
+ } from '@empire-builder-kit/nx/workload-roles';
134
+ import databaseBindings from '../../database/bindings.json';
135
+ import { Secrets } from '../../secrets/declarations.js';
136
+ import secretWorkloadAccess from '../../secrets/workload-access.json';
137
+
138
+ export interface StandardSliceWorkloadRoleIntentContribution {
139
+ intents: readonly WorkloadRolePermissionIntent[];
140
+ roleId: string;
141
+ }
142
+
143
+ export interface StandardSliceWorkloadRoleIntentContext {
144
+ accountId: string;
145
+ clusterName: string;
146
+ clusterResourceId: string;
147
+ eventBusArn: string;
148
+ identityUserPoolArn: string;
149
+ masterSecretArn: string;
150
+ partition: string;
151
+ region: string;
152
+ stage: string;
153
+ }
154
+
155
+ const SECRET_LINKABLE_WORKLOAD_SURFACES = new Set([
156
+ 'api-route',
157
+ 'bootstrap-task',
158
+ 'job-task',
159
+ 'lambda-function',
160
+ 'migration-task',
161
+ 'next-image-optimizer',
162
+ 'next-revalidation-seeder',
163
+ 'next-revalidation-subscriber',
164
+ 'next-server',
165
+ 'queue-consumer',
166
+ 'retirement-task',
167
+ 'service-task',
168
+ ]);
169
+
170
+ function requireSecretAccessBindings(
171
+ stage: string,
172
+ topology: StandardSliceWorkloadRoleTopology,
173
+ ) {
174
+ const access = parseSecretWorkloadAccessRegistry(secretWorkloadAccess);
175
+ const declarations = toOperatorSecretMetadataDeclarations(Secrets);
176
+ const declarationsByName = new Map(
177
+ declarations.map((declaration) => [
178
+ declaration.logicalName,
179
+ declaration,
180
+ ]),
181
+ );
182
+ const validatedAccess = validateSecretWorkloadAccessTargets({
183
+ access,
184
+ allowedWorkloads: topology.roles
185
+ .filter((role) =>
186
+ SECRET_LINKABLE_WORKLOAD_SURFACES.has(role.surface),
187
+ )
188
+ .map((role) => role.id),
189
+ });
190
+ for (const binding of validatedAccess.bindings) {
191
+ const declaration = declarationsByName.get(binding.logicalName);
192
+ if (!declaration) {
193
+ throw new Error(
194
+ 'Secret workload access must select one declared, linkable Standard Slice workload.',
195
+ );
196
+ }
197
+ }
198
+ return {
199
+ access: validatedAccess,
200
+ declarations,
201
+ declarationsByName,
202
+ };
203
+ }
204
+
205
+ export function standardSliceBoundOperatorSecretDeclarations(
206
+ stage: string,
207
+ topology: StandardSliceWorkloadRoleTopology,
208
+ ): readonly SecretMetadataDeclaration[] {
209
+ const { access, declarationsByName } = requireSecretAccessBindings(
210
+ stage,
211
+ topology,
212
+ );
213
+ return Object.freeze(
214
+ [...new Set(access.bindings.map(({ logicalName }) => logicalName))]
215
+ .sort((left, right) => (left < right ? -1 : left > right ? 1 : 0))
216
+ .map((logicalName) => {
217
+ const declaration = declarationsByName.get(logicalName);
218
+ if (!declaration) {
219
+ throw new Error(
220
+ 'Secret workload access references an undeclared operator secret.',
221
+ );
222
+ }
223
+ return declaration;
224
+ })
225
+ .filter((declaration) => declaration.requiredStages.includes(stage)),
226
+ );
227
+ }
228
+
229
+ export function standardSliceSecretAccessPlan(
230
+ context: StandardSliceWorkloadRoleIntentContext,
231
+ topology: StandardSliceWorkloadRoleTopology,
232
+ references: readonly WorkloadSecretReferenceInput[],
233
+ ): readonly SecretWorkloadAccessPlanEntry[] {
234
+ const { access, declarations } = requireSecretAccessBindings(
235
+ context.stage,
236
+ topology,
237
+ );
238
+ return createSecretWorkloadAccessPlan({
239
+ access,
240
+ declarations,
241
+ references,
242
+ stage: context.stage,
243
+ });
244
+ }
245
+
246
+ function stableName(maxLength: number, ...parts: string[]): string {
247
+ const value = parts.join('-').toLowerCase();
248
+ if (value.length <= maxLength) return value;
249
+ const digest = createHash('sha256')
250
+ .update(value, 'utf8')
251
+ .digest('hex')
252
+ .slice(0, 12);
253
+ return value.slice(0, maxLength - digest.length - 1) + '-' + digest;
254
+ }
255
+
256
+ export function standardSliceResourceNames(context: {
257
+ accountId: string;
258
+ stage: string;
259
+ }) {
260
+ return {
261
+ asyncRecoveryLedger: stableName(
262
+ 255,
263
+ 'ebk',
264
+ context.stage,
265
+ '${name}',
266
+ 'async-recovery-ledger',
267
+ ),
268
+ asyncTargetDlq: stableName(
269
+ 80,
270
+ 'ebk',
271
+ context.stage,
272
+ '${name}',
273
+ 'async-target-dlq',
274
+ ),
275
+ dataExportBucket: stableName(
276
+ 63,
277
+ 'ebk',
278
+ context.accountId,
279
+ context.stage,
280
+ '${name}',
281
+ 'data-export',
282
+ ),
283
+ dataExportCleanupRule: stableName(
284
+ 64,
285
+ 'ebk',
286
+ context.stage,
287
+ '${name}',
288
+ 'data-export-cleanup',
289
+ ),
290
+ dataExportKeyAlias:
291
+ 'alias/' +
292
+ stableName(
293
+ 250,
294
+ 'ebk',
295
+ context.stage,
296
+ '${name}',
297
+ 'data-export',
298
+ ),
299
+ dataRetentionTaskFamily: standardSliceExtensionTaskFamily(
300
+ context.stage,
301
+ 'data-retention',
302
+ 'job',
303
+ ),
304
+ dataRetentionMaintenanceTaskFamily: standardSliceExtensionTaskFamily(
305
+ context.stage,
306
+ 'data-retention-maintenance',
307
+ 'job',
308
+ ),
309
+ dataRetentionMaintenanceRule: stableName(
310
+ 64,
311
+ 'ebk',
312
+ context.stage,
313
+ '${name}',
314
+ 'data-retention-maintenance',
315
+ ),
316
+ databaseTaskFamily(database: string, kind: 'bootstrap' | 'migration' | 'retirement') {
317
+ return standardSliceDatabaseTaskFamily(context.stage, database, kind);
318
+ },
319
+ eventDlq: stableName(80, 'ebk', context.stage, '${name}', 'event-dlq'),
320
+ eventQueue: stableName(80, 'ebk', context.stage, '${name}', 'event-queue'),
321
+ providerDlq: stableName(
322
+ 80,
323
+ 'ebk',
324
+ context.stage,
325
+ '${name}',
326
+ 'provider-dlq',
327
+ ),
328
+ providerQueue: stableName(
329
+ 80,
330
+ 'ebk',
331
+ context.stage,
332
+ '${name}',
333
+ 'provider-queue',
334
+ ),
335
+ workflowTaskFunction: stableName(
336
+ 64,
337
+ 'ebk',
338
+ context.stage,
339
+ '${name}',
340
+ 'async-workflow-task',
341
+ ),
342
+ extensionTaskFamily(id: string, kind: 'job' | 'service') {
343
+ return standardSliceExtensionTaskFamily(context.stage, id, kind);
344
+ },
345
+ webAssetsBucket: stableName(
346
+ 63,
347
+ 'ebk',
348
+ context.accountId,
349
+ context.stage,
350
+ '${name}',
351
+ 'web-assets',
352
+ ),
353
+ webRevalidationQueue:
354
+ stableName(
355
+ 75,
356
+ 'ebk',
357
+ context.stage,
358
+ '${name}',
359
+ 'web-revalidation',
360
+ ) + '.fifo',
361
+ webRevalidationTable: stableName(
362
+ 255,
363
+ 'ebk',
364
+ context.stage,
365
+ '${name}',
366
+ 'web-revalidation',
367
+ ),
368
+ };
369
+ }
370
+
371
+ export function standardSliceDatabaseTaskFamily(
372
+ stage: string,
373
+ database: string,
374
+ kind: 'bootstrap' | 'migration' | 'retirement',
375
+ ) {
376
+ return stableName(
377
+ 255,
378
+ 'ebk',
379
+ stage,
380
+ '${name}',
381
+ 'database',
382
+ database,
383
+ kind,
384
+ );
385
+ }
386
+
387
+ export function standardSliceExtensionTaskFamily(
388
+ stage: string,
389
+ id: string,
390
+ kind: 'job' | 'service',
391
+ ) {
392
+ return stableName(255, 'ebk', stage, '${name}', id, kind);
393
+ }
394
+
395
+ export function standardSliceServicePerformanceReservationTableName(
396
+ stage: string,
397
+ id: string,
398
+ ) {
399
+ return stableName(
400
+ 255,
401
+ 'ebk',
402
+ stage,
403
+ '${name}',
404
+ id,
405
+ 'service-performance-reservations',
406
+ );
407
+ }
408
+
409
+ const roleId = (resource: string) => '${name}.' + resource;
410
+ const arn = (
411
+ context: StandardSliceWorkloadRoleIntentContext,
412
+ service: string,
413
+ resource: string,
414
+ ) =>
415
+ 'arn:' +
416
+ context.partition +
417
+ ':' +
418
+ service +
419
+ ':' +
420
+ context.region +
421
+ ':' +
422
+ context.accountId +
423
+ ':' +
424
+ resource;
425
+
426
+ function intent(
427
+ id: string,
428
+ source: WorkloadRolePermissionIntent['source'],
429
+ actions: string[],
430
+ resources: string[],
431
+ wildcardResourceJustification?: string,
432
+ ): WorkloadRolePermissionIntent {
433
+ return {
434
+ actions,
435
+ id,
436
+ resources,
437
+ source,
438
+ ...(wildcardResourceJustification
439
+ ? { wildcardResourceJustification }
440
+ : {}),
441
+ };
442
+ }
443
+
444
+ function logIntent(
445
+ context: StandardSliceWorkloadRoleIntentContext,
446
+ id: string,
447
+ component: string,
448
+ resource?: string,
449
+ ) {
450
+ const suffix = resource ? '/' + resource : '';
451
+ return intent(
452
+ id + '.structured-logging',
453
+ { kind: 'framework', name: 'structured-logging' },
454
+ ['logs:CreateLogStream', 'logs:PutLogEvents'],
455
+ [
456
+ arn(
457
+ context,
458
+ 'logs',
459
+ 'log-group:/ebk/' +
460
+ context.stage +
461
+ '/${name}/' +
462
+ component +
463
+ suffix +
464
+ ':*',
465
+ ),
466
+ ],
467
+ );
468
+ }
469
+
470
+ function lambdaVpcIntent(
471
+ id: string,
472
+ ): WorkloadRolePermissionIntent {
473
+ return intent(
474
+ id + '.vpc-network-interface',
475
+ { kind: 'framework', name: 'lambda-vpc' },
476
+ [
477
+ 'ec2:AssignPrivateIpAddresses',
478
+ 'ec2:CreateNetworkInterface',
479
+ 'ec2:DeleteNetworkInterface',
480
+ 'ec2:DescribeNetworkInterfaces',
481
+ 'ec2:DescribeSubnets',
482
+ 'ec2:UnassignPrivateIpAddresses',
483
+ ],
484
+ ['*'],
485
+ 'Lambda VPC network-interface APIs do not support useful resource scoping.',
486
+ );
487
+ }
488
+
489
+ function secretArn(
490
+ context: StandardSliceWorkloadRoleIntentContext,
491
+ database: string,
492
+ kind: 'readonly' | 'readwrite',
493
+ ) {
494
+ return arn(
495
+ context,
496
+ 'secretsmanager',
497
+ 'secret:ebk/' +
498
+ context.stage +
499
+ '/${name}/database/' +
500
+ database +
501
+ '/' +
502
+ kind +
503
+ '-*',
504
+ );
505
+ }
506
+
507
+ function machineAuthorizationSecretArn(
508
+ context: StandardSliceWorkloadRoleIntentContext,
509
+ ) {
510
+ return arn(
511
+ context,
512
+ 'secretsmanager',
513
+ 'secret:ebk/' +
514
+ context.stage +
515
+ '/${name}/authorization/machine-client-*',
516
+ );
517
+ }
518
+
519
+ function dataExportStorageIntents(
520
+ context: StandardSliceWorkloadRoleIntentContext,
521
+ id: string,
522
+ access: 'cleanup' | 'full',
523
+ ): WorkloadRolePermissionIntent[] {
524
+ const names = standardSliceResourceNames(context);
525
+ const bucketArn =
526
+ 'arn:' + context.partition + ':s3:::' + names.dataExportBucket;
527
+ const intents: WorkloadRolePermissionIntent[] = [
528
+ {
529
+ ...intent(
530
+ id + '.list-export-versions',
531
+ { kind: 'permissions', name: 'confidential-data-export' },
532
+ ['s3:ListBucketVersions'],
533
+ [bucketArn],
534
+ ),
535
+ conditions: {
536
+ StringLike: {
537
+ 's3:prefix': [
538
+ 'confidential-exports/',
539
+ 'confidential-exports/*',
540
+ ],
541
+ },
542
+ },
543
+ },
544
+ intent(
545
+ id + '.export-objects',
546
+ { kind: 'permissions', name: 'confidential-data-export' },
547
+ access === 'full'
548
+ ? [
549
+ 's3:DeleteObjectVersion',
550
+ 's3:GetObject',
551
+ 's3:GetObjectVersion',
552
+ 's3:PutObject',
553
+ ]
554
+ : ['s3:DeleteObjectVersion'],
555
+ [bucketArn + '/confidential-exports/*'],
556
+ ),
557
+ ];
558
+ if (access === 'full') {
559
+ intents.push({
560
+ ...intent(
561
+ id + '.export-key',
562
+ { kind: 'permissions', name: 'confidential-data-export' },
563
+ ['kms:Decrypt', 'kms:Encrypt', 'kms:GenerateDataKey'],
564
+ [arn(context, 'kms', 'key/*')],
565
+ ),
566
+ conditions: {
567
+ 'ForAnyValue:StringEquals': {
568
+ 'kms:ResourceAliases': names.dataExportKeyAlias,
569
+ },
570
+ },
571
+ });
572
+ }
573
+ return intents;
574
+ }
575
+
576
+ function executionIntents(
577
+ context: StandardSliceWorkloadRoleIntentContext,
578
+ role: string,
579
+ component: string,
580
+ artifactId: string,
581
+ resource?: string,
582
+ exactDevelopment = false,
583
+ ) {
584
+ const protectedImage =
585
+ context.stage === 'staging' ||
586
+ context.stage === 'production' ||
587
+ (context.stage === 'development' && exactDevelopment);
588
+ const repository = protectedImage
589
+ ? containerReleaseRepositoryName({
590
+ artifactId,
591
+ slice: '${name}',
592
+ stage: context.stage,
593
+ })
594
+ : 'sst-asset';
595
+ return [
596
+ intent(
597
+ role + '.ecr-authorization',
598
+ { kind: 'framework', name: 'container-image-pull' },
599
+ ['ecr:GetAuthorizationToken'],
600
+ ['*'],
601
+ 'Amazon ECR authorization tokens are account-scoped and require Resource star.',
602
+ ),
603
+ intent(
604
+ role + '.ecr-image-pull',
605
+ { kind: 'framework', name: 'sst-container-image' },
606
+ [
607
+ 'ecr:BatchCheckLayerAvailability',
608
+ 'ecr:BatchGetImage',
609
+ 'ecr:GetDownloadUrlForLayer',
610
+ ],
611
+ [arn(context, 'ecr', 'repository/' + repository)],
612
+ ),
613
+ logIntent(context, role, component, resource),
614
+ ];
615
+ }
616
+
617
+ function roleArn(
618
+ context: StandardSliceWorkloadRoleIntentContext,
619
+ resource: string,
620
+ ) {
621
+ return (
622
+ 'arn:' +
623
+ context.partition +
624
+ ':iam::' +
625
+ context.accountId +
626
+ ':role/' +
627
+ standardSliceWorkloadRoleName(context.stage, '${name}', resource)
628
+ );
629
+ }
630
+
631
+ function passRoleIntent(
632
+ context: StandardSliceWorkloadRoleIntentContext,
633
+ id: string,
634
+ resources: string[],
635
+ sourceName = 'database-lifecycle-orchestration',
636
+ ): WorkloadRolePermissionIntent {
637
+ return {
638
+ ...intent(
639
+ id + '.pass-task-roles',
640
+ { kind: 'framework', name: sourceName },
641
+ ['iam:PassRole'],
642
+ resources,
643
+ ),
644
+ conditions: {
645
+ StringEquals: {
646
+ 'iam:PassedToService': 'ecs-tasks.amazonaws.com',
647
+ },
648
+ },
649
+ };
650
+ }
651
+
652
+ function stateMachineLoggingIntent(id: string) {
653
+ return intent(
654
+ id + '.state-machine-logging',
655
+ { kind: 'framework', name: 'step-functions-logging' },
656
+ [
657
+ 'logs:CreateLogDelivery',
658
+ 'logs:DeleteLogDelivery',
659
+ 'logs:DescribeLogGroups',
660
+ 'logs:DescribeResourcePolicies',
661
+ 'logs:GetLogDelivery',
662
+ 'logs:ListLogDeliveries',
663
+ 'logs:PutResourcePolicy',
664
+ 'logs:UpdateLogDelivery',
665
+ ],
666
+ ['*'],
667
+ 'CloudWatch Logs delivery control-plane APIs require Resource star.',
668
+ );
669
+ }
670
+
671
+ function databaseContributions(
672
+ context: StandardSliceWorkloadRoleIntentContext,
673
+ database: string,
674
+ ): StandardSliceWorkloadRoleIntentContribution[] {
675
+ const names = standardSliceResourceNames(context);
676
+ const identifiers = createDatabaseBindingPlan(databaseBindings, {
677
+ slice: '${name}',
678
+ stage: context.stage,
679
+ }).identifiers[database];
680
+ if (!identifiers) {
681
+ throw new Error('Generated database workload-role intent is undeclared.');
682
+ }
683
+ const prefix = 'database-' + database;
684
+ const bootstrapTaskId = roleId(prefix + '-bootstrap-task');
685
+ const bootstrapExecutionId = roleId(prefix + '-bootstrap-execution');
686
+ const migrationTaskId = roleId(prefix + '-migration-task');
687
+ const migrationExecutionId = roleId(prefix + '-migration-execution');
688
+ const migrationOrchestrationId = roleId(prefix + '-migration-orchestration');
689
+ const taskDefinition = (kind: 'bootstrap' | 'migration' | 'retirement') =>
690
+ arn(
691
+ context,
692
+ 'ecs',
693
+ 'task-definition/' + names.databaseTaskFamily(database, kind) + ':*',
694
+ );
695
+ const taskRoleResources = (kind: 'bootstrap' | 'migration' | 'retirement') => [
696
+ roleArn(context, prefix + '-' + kind + '-execution'),
697
+ roleArn(context, prefix + '-' + kind + '-task'),
698
+ ];
699
+ const databaseUserArn = arn(
700
+ context,
701
+ 'rds-db',
702
+ 'dbuser:' + context.clusterResourceId + '/' + identifiers.migratorRole,
703
+ );
704
+ const migrationOrchestration = [
705
+ intent(
706
+ migrationOrchestrationId + '.run-tasks',
707
+ { kind: 'framework', name: 'database-lifecycle-orchestration' },
708
+ ['ecs:RunTask'],
709
+ [taskDefinition('bootstrap'), taskDefinition('migration')],
710
+ ),
711
+ intent(
712
+ migrationOrchestrationId + '.observe-tasks',
713
+ { kind: 'framework', name: 'database-lifecycle-orchestration' },
714
+ ['ecs:DescribeTasks', 'ecs:StopTask'],
715
+ [
716
+ arn(
717
+ context,
718
+ 'ecs',
719
+ 'task/' + context.clusterName + '/*',
720
+ ),
721
+ ],
722
+ ),
723
+ intent(
724
+ migrationOrchestrationId + '.managed-events-rule',
725
+ { kind: 'framework', name: 'database-lifecycle-orchestration' },
726
+ ['events:DescribeRule', 'events:PutRule', 'events:PutTargets'],
727
+ [
728
+ arn(
729
+ context,
730
+ 'events',
731
+ 'rule/StepFunctionsGetEventsForECSTaskRule',
732
+ ),
733
+ ],
734
+ ),
735
+ passRoleIntent(
736
+ context,
737
+ migrationOrchestrationId,
738
+ [
739
+ ...taskRoleResources('bootstrap'),
740
+ ...taskRoleResources('migration'),
741
+ ],
742
+ ),
743
+ stateMachineLoggingIntent(migrationOrchestrationId),
744
+ ];
745
+ const contributions: StandardSliceWorkloadRoleIntentContribution[] = [
746
+ {
747
+ intents: [
748
+ intent(
749
+ bootstrapTaskId + '.database-secrets',
750
+ { kind: 'permissions', name: 'database-bootstrap' },
751
+ [
752
+ 'secretsmanager:GetSecretValue',
753
+ 'secretsmanager:PutSecretValue',
754
+ ],
755
+ [
756
+ context.masterSecretArn,
757
+ secretArn(context, database, 'readonly'),
758
+ secretArn(context, database, 'readwrite'),
759
+ ],
760
+ ),
761
+ intent(
762
+ bootstrapTaskId + '.database-connect',
763
+ { kind: 'permissions', name: 'database-bootstrap' },
764
+ ['rds-db:connect'],
765
+ [databaseUserArn],
766
+ ),
767
+ ],
768
+ roleId: bootstrapTaskId,
769
+ },
770
+ {
771
+ intents: executionIntents(
772
+ context,
773
+ bootstrapExecutionId,
774
+ 'database-bootstrap',
775
+ '${name}.job.database-migration',
776
+ database,
777
+ ),
778
+ roleId: bootstrapExecutionId,
779
+ },
780
+ {
781
+ intents: [
782
+ intent(
783
+ migrationTaskId + '.database-connect',
784
+ { kind: 'permissions', name: 'database-migration' },
785
+ ['rds-db:connect'],
786
+ [databaseUserArn],
787
+ ),
788
+ ],
789
+ roleId: migrationTaskId,
790
+ },
791
+ {
792
+ intents: executionIntents(
793
+ context,
794
+ migrationExecutionId,
795
+ 'database-migration',
796
+ '${name}.job.database-migration',
797
+ database,
798
+ ),
799
+ roleId: migrationExecutionId,
800
+ },
801
+ {
802
+ intents: migrationOrchestration,
803
+ roleId: migrationOrchestrationId,
804
+ },
805
+ ];
806
+ if (database !== 'retirement_rehearsal') return contributions;
807
+
808
+ const retirementTaskId = roleId(prefix + '-retirement-task');
809
+ const retirementExecutionId = roleId(prefix + '-retirement-execution');
810
+ const retirementOrchestrationId = roleId(
811
+ prefix + '-retirement-orchestration',
812
+ );
813
+ const allDatabases = createDatabaseBindingPlan(databaseBindings, {
814
+ slice: '${name}',
815
+ stage: context.stage,
816
+ }).provisioned;
817
+ contributions.push(
818
+ {
819
+ intents: [
820
+ intent(
821
+ retirementTaskId + '.master-secret',
822
+ { kind: 'permissions', name: 'database-retirement-rehearsal' },
823
+ ['secretsmanager:GetSecretValue'],
824
+ [context.masterSecretArn],
825
+ ),
826
+ intent(
827
+ retirementTaskId + '.secret-metadata',
828
+ { kind: 'permissions', name: 'database-retirement-rehearsal' },
829
+ ['secretsmanager:DescribeSecret'],
830
+ allDatabases.flatMap((identifier) => [
831
+ secretArn(context, identifier, 'readonly'),
832
+ secretArn(context, identifier, 'readwrite'),
833
+ ]),
834
+ ),
835
+ intent(
836
+ retirementTaskId + '.delete-target-secrets',
837
+ { kind: 'permissions', name: 'database-retirement-rehearsal' },
838
+ ['secretsmanager:DeleteSecret'],
839
+ [
840
+ secretArn(context, database, 'readonly'),
841
+ secretArn(context, database, 'readwrite'),
842
+ ],
843
+ ),
844
+ intent(
845
+ retirementTaskId + '.task-callback',
846
+ { kind: 'framework', name: 'database-retirement-callback' },
847
+ ['states:SendTaskFailure', 'states:SendTaskSuccess'],
848
+ ['*'],
849
+ 'Step Functions callback task-token APIs require Resource star.',
850
+ ),
851
+ ],
852
+ roleId: retirementTaskId,
853
+ },
854
+ {
855
+ intents: executionIntents(
856
+ context,
857
+ retirementExecutionId,
858
+ 'database-retirement',
859
+ '${name}.job.database-retirement',
860
+ database,
861
+ true,
862
+ ),
863
+ roleId: retirementExecutionId,
864
+ },
865
+ {
866
+ intents: [
867
+ intent(
868
+ retirementOrchestrationId + '.run-task',
869
+ { kind: 'framework', name: 'database-retirement-orchestration' },
870
+ ['ecs:RunTask'],
871
+ [taskDefinition('retirement')],
872
+ ),
873
+ intent(
874
+ retirementOrchestrationId + '.observe-task',
875
+ {
876
+ kind: 'framework',
877
+ name: 'database-retirement-orchestration',
878
+ },
879
+ ['ecs:DescribeTasks', 'ecs:StopTask'],
880
+ [arn(context, 'ecs', 'task/' + context.clusterName + '/*')],
881
+ ),
882
+ intent(
883
+ retirementOrchestrationId + '.managed-events-rule',
884
+ {
885
+ kind: 'framework',
886
+ name: 'database-retirement-orchestration',
887
+ },
888
+ ['events:DescribeRule', 'events:PutRule', 'events:PutTargets'],
889
+ [
890
+ arn(
891
+ context,
892
+ 'events',
893
+ 'rule/StepFunctionsGetEventsForECSTaskRule',
894
+ ),
895
+ ],
896
+ ),
897
+ passRoleIntent(
898
+ context,
899
+ retirementOrchestrationId,
900
+ taskRoleResources('retirement'),
901
+ ),
902
+ stateMachineLoggingIntent(retirementOrchestrationId),
903
+ ],
904
+ roleId: retirementOrchestrationId,
905
+ },
906
+ );
907
+ return contributions;
908
+ }
909
+
910
+ function dataRetentionContributions(
911
+ context: StandardSliceWorkloadRoleIntentContext,
912
+ database: string,
913
+ ): StandardSliceWorkloadRoleIntentContribution[] {
914
+ const names = standardSliceResourceNames(context);
915
+ const taskId = roleId('data-retention-job-task');
916
+ const executionId = roleId('data-retention-job-execution');
917
+ const orchestrationId = roleId('data-retention-job-orchestration');
918
+ const maintenanceTaskId = roleId(
919
+ 'data-retention-maintenance-job-task',
920
+ );
921
+ const maintenanceExecutionId = roleId(
922
+ 'data-retention-maintenance-job-execution',
923
+ );
924
+ const maintenanceLauncherId = roleId(
925
+ 'data-retention-maintenance-launcher',
926
+ );
927
+ const taskDefinition = arn(
928
+ context,
929
+ 'ecs',
930
+ 'task-definition/' + names.dataRetentionTaskFamily + ':*',
931
+ );
932
+ const maintenanceTaskDefinition = arn(
933
+ context,
934
+ 'ecs',
935
+ 'task-definition/' + names.dataRetentionMaintenanceTaskFamily + ':*',
936
+ );
937
+ return [
938
+ {
939
+ intents: [
940
+ intent(
941
+ taskId + '.database-secret',
942
+ { kind: 'secret-link', name: 'primary-database' },
943
+ ['secretsmanager:GetSecretValue'],
944
+ [secretArn(context, database, 'readwrite')],
945
+ ),
946
+ intent(
947
+ taskId + '.event-bus',
948
+ { kind: 'link', name: 'foundation-event-bus' },
949
+ ['events:PutEvents'],
950
+ [context.eventBusArn],
951
+ ),
952
+ intent(
953
+ taskId + '.task-callback',
954
+ { kind: 'framework', name: 'data-retention-callback' },
955
+ ['states:SendTaskFailure', 'states:SendTaskSuccess'],
956
+ ['*'],
957
+ 'Step Functions callback task-token APIs require Resource star.',
958
+ ),
959
+ ],
960
+ roleId: taskId,
961
+ },
962
+ {
963
+ intents: executionIntents(
964
+ context,
965
+ executionId,
966
+ 'job-data-retention',
967
+ '${name}.job.data-retention',
968
+ ),
969
+ roleId: executionId,
970
+ },
971
+ {
972
+ intents: [
973
+ intent(
974
+ orchestrationId + '.run-task',
975
+ { kind: 'framework', name: 'data-retention-orchestration' },
976
+ ['ecs:RunTask'],
977
+ [taskDefinition],
978
+ ),
979
+ intent(
980
+ orchestrationId + '.observe-task',
981
+ { kind: 'framework', name: 'data-retention-orchestration' },
982
+ ['ecs:DescribeTasks', 'ecs:StopTask'],
983
+ [arn(context, 'ecs', 'task/' + context.clusterName + '/*')],
984
+ ),
985
+ intent(
986
+ orchestrationId + '.managed-events-rule',
987
+ { kind: 'framework', name: 'data-retention-orchestration' },
988
+ ['events:DescribeRule', 'events:PutRule', 'events:PutTargets'],
989
+ [
990
+ arn(
991
+ context,
992
+ 'events',
993
+ 'rule/StepFunctionsGetEventsForECSTaskRule',
994
+ ),
995
+ ],
996
+ ),
997
+ passRoleIntent(context, orchestrationId, [
998
+ roleArn(context, 'data-retention-job-execution'),
999
+ roleArn(context, 'data-retention-job-task'),
1000
+ ]),
1001
+ stateMachineLoggingIntent(orchestrationId),
1002
+ ],
1003
+ roleId: orchestrationId,
1004
+ },
1005
+ {
1006
+ intents: [
1007
+ logIntent(
1008
+ context,
1009
+ maintenanceLauncherId,
1010
+ 'job-data-retention-maintenance-launcher',
1011
+ ),
1012
+ {
1013
+ ...intent(
1014
+ maintenanceLauncherId + '.run-maintenance-task',
1015
+ {
1016
+ kind: 'framework',
1017
+ name: 'data-retention-maintenance-launcher',
1018
+ },
1019
+ ['ecs:RunTask'],
1020
+ [maintenanceTaskDefinition],
1021
+ ),
1022
+ conditions: {
1023
+ ArnEquals: {
1024
+ 'ecs:cluster': arn(
1025
+ context,
1026
+ 'ecs',
1027
+ 'cluster/' + context.clusterName,
1028
+ ),
1029
+ },
1030
+ },
1031
+ },
1032
+ passRoleIntent(
1033
+ context,
1034
+ maintenanceLauncherId,
1035
+ [
1036
+ roleArn(
1037
+ context,
1038
+ 'data-retention-maintenance-job-execution',
1039
+ ),
1040
+ roleArn(context, 'data-retention-maintenance-job-task'),
1041
+ ],
1042
+ 'data-retention-maintenance-launcher',
1043
+ ),
1044
+ ],
1045
+ roleId: maintenanceLauncherId,
1046
+ },
1047
+ {
1048
+ intents: [
1049
+ intent(
1050
+ maintenanceTaskId + '.database-secret',
1051
+ { kind: 'secret-link', name: 'primary-database' },
1052
+ ['secretsmanager:GetSecretValue'],
1053
+ [secretArn(context, database, 'readwrite')],
1054
+ ),
1055
+ ],
1056
+ roleId: maintenanceTaskId,
1057
+ },
1058
+ {
1059
+ intents: executionIntents(
1060
+ context,
1061
+ maintenanceExecutionId,
1062
+ 'job-data-retention-maintenance',
1063
+ '${name}.job.data-retention',
1064
+ ),
1065
+ roleId: maintenanceExecutionId,
1066
+ },
1067
+ ];
1068
+ }
1069
+
1070
+ export function extensionWorkloadRoleIntentContributions(
1071
+ context: StandardSliceWorkloadRoleIntentContext,
1072
+ topology: StandardSliceWorkloadRoleTopology,
1073
+ id: string,
1074
+ kind: StandardSliceWorkloadExtensionKind,
1075
+ ): StandardSliceWorkloadRoleIntentContribution[] {
1076
+ if (kind === 'function') {
1077
+ const extensionRoleId = roleId(id + '-function');
1078
+ return [{
1079
+ intents: [logIntent(context, extensionRoleId, 'function-' + id)],
1080
+ roleId: extensionRoleId,
1081
+ }];
1082
+ }
1083
+ const taskRoleId = roleId(id + '-' + kind + '-task');
1084
+ const executionRoleId = roleId(id + '-' + kind + '-execution');
1085
+ const activeConfigurationIntent = {
1086
+ ...intent(
1087
+ taskRoleId + '.active-configuration',
1088
+ { kind: 'link', name: 'active-configuration' },
1089
+ [
1090
+ 'appconfig:GetLatestConfiguration',
1091
+ 'appconfig:StartConfigurationSession',
1092
+ ],
1093
+ [
1094
+ arn(
1095
+ context,
1096
+ 'appconfig',
1097
+ 'application/*/environment/*/configuration/*',
1098
+ ),
1099
+ ],
1100
+ ),
1101
+ conditions: {
1102
+ StringEquals: {
1103
+ 'aws:ResourceTag/ebk:slice': '${name}',
1104
+ 'aws:ResourceTag/ebk:stage': context.stage,
1105
+ },
1106
+ },
1107
+ };
1108
+ const serviceBaseIntents = [
1109
+ activeConfigurationIntent,
1110
+ intent(
1111
+ taskRoleId + '.ecs-exec',
1112
+ { kind: 'framework', name: 'service-ecs-exec' },
1113
+ [
1114
+ 'ssmmessages:CreateControlChannel',
1115
+ 'ssmmessages:CreateDataChannel',
1116
+ 'ssmmessages:OpenControlChannel',
1117
+ 'ssmmessages:OpenDataChannel',
1118
+ ],
1119
+ ['*'],
1120
+ 'ECS Exec session-channel APIs require Resource star.',
1121
+ ),
1122
+ ];
1123
+ const taskContributions: StandardSliceWorkloadRoleIntentContribution[] =
1124
+ kind === 'service'
1125
+ ? topology.serviceAdapterOwner === id
1126
+ ? [
1127
+ {
1128
+ intents: serviceBaseIntents,
1129
+ roleId: taskRoleId,
1130
+ },
1131
+ {
1132
+ intents: [
1133
+ ...serviceBaseIntents,
1134
+ intent(
1135
+ roleId(id + '-service-performance-task') +
1136
+ '.performance-reservations',
1137
+ { kind: 'framework', name: 'protected-performance-load' },
1138
+ [
1139
+ 'dynamodb:GetItem',
1140
+ 'dynamodb:PutItem',
1141
+ 'dynamodb:TransactWriteItems',
1142
+ ],
1143
+ [
1144
+ arn(
1145
+ context,
1146
+ 'dynamodb',
1147
+ 'table/' +
1148
+ standardSliceServicePerformanceReservationTableName(
1149
+ context.stage,
1150
+ id,
1151
+ ),
1152
+ ),
1153
+ ],
1154
+ ),
1155
+ ],
1156
+ roleId: roleId(id + '-service-performance-task'),
1157
+ },
1158
+ ]
1159
+ : [{ intents: serviceBaseIntents, roleId: taskRoleId }]
1160
+ : [{ intents: [activeConfigurationIntent], roleId: taskRoleId }];
1161
+ return [
1162
+ ...taskContributions,
1163
+ {
1164
+ intents: executionIntents(
1165
+ context,
1166
+ executionRoleId,
1167
+ kind + '-' + id,
1168
+ '${name}.' + kind + '.' + id,
1169
+ ),
1170
+ roleId: executionRoleId,
1171
+ },
1172
+ ];
1173
+ }
1174
+
1175
+ export function createStandardSliceWorkloadRoleIntents(
1176
+ context: StandardSliceWorkloadRoleIntentContext,
1177
+ topology: StandardSliceWorkloadRoleTopology,
1178
+ secretReferences: readonly WorkloadSecretReferenceInput[],
1179
+ ) {
1180
+ const plan = createDatabaseBindingPlan(databaseBindings, {
1181
+ slice: '${name}',
1182
+ stage: context.stage,
1183
+ });
1184
+ const activeDatabase = plan.active.primary;
1185
+ if (!activeDatabase) {
1186
+ throw new Error('Primary database binding is required for role intent.');
1187
+ }
1188
+ const names = standardSliceResourceNames(context);
1189
+ const lambda = (
1190
+ resource: string,
1191
+ component: string,
1192
+ extra: readonly WorkloadRolePermissionIntent[] = [],
1193
+ ): StandardSliceWorkloadRoleIntentContribution => {
1194
+ const id = roleId(resource);
1195
+ return { intents: [logIntent(context, id, component), ...extra], roleId: id };
1196
+ };
1197
+ const nextTable = arn(
1198
+ context,
1199
+ 'dynamodb',
1200
+ 'table/' + names.webRevalidationTable,
1201
+ );
1202
+ const nextQueue = arn(context, 'sqs', names.webRevalidationQueue);
1203
+ const contributions: StandardSliceWorkloadRoleIntentContribution[] = [
1204
+ lambda('api-data-rights', 'data-rights', [
1205
+ intent(
1206
+ roleId('api-data-rights') + '.database-secret',
1207
+ { kind: 'secret-link', name: 'primary-database' },
1208
+ ['secretsmanager:GetSecretValue'],
1209
+ [secretArn(context, activeDatabase, 'readwrite')],
1210
+ ),
1211
+ intent(
1212
+ roleId('api-data-rights') + '.event-bus',
1213
+ { kind: 'link', name: 'foundation-event-bus' },
1214
+ ['events:PutEvents'],
1215
+ [context.eventBusArn],
1216
+ ),
1217
+ ...dataExportStorageIntents(
1218
+ context,
1219
+ roleId('api-data-rights'),
1220
+ 'full',
1221
+ ),
1222
+ lambdaVpcIntent(roleId('api-data-rights')),
1223
+ ]),
1224
+ lambda('api-delegations', 'authorization-delegations', [
1225
+ intent(
1226
+ roleId('api-delegations') + '.database-secret',
1227
+ { kind: 'secret-link', name: 'primary-database' },
1228
+ ['secretsmanager:GetSecretValue'],
1229
+ [secretArn(context, activeDatabase, 'readwrite')],
1230
+ ),
1231
+ lambdaVpcIntent(roleId('api-delegations')),
1232
+ ]),
1233
+ lambda('api-health', 'api-health'),
1234
+ lambda(
1235
+ 'api-machine-authorization-proof',
1236
+ 'machine-authorization-proof-target',
1237
+ [
1238
+ intent(
1239
+ roleId('api-machine-authorization-proof') + '.database-secret',
1240
+ { kind: 'secret-link', name: 'primary-database' },
1241
+ ['secretsmanager:GetSecretValue'],
1242
+ [secretArn(context, activeDatabase, 'readwrite')],
1243
+ ),
1244
+ lambdaVpcIntent(roleId('api-machine-authorization-proof')),
1245
+ ],
1246
+ ),
1247
+ lambda('api-protected', 'api-protected', [
1248
+ intent(
1249
+ roleId('api-protected') + '.database-secret',
1250
+ { kind: 'secret-link', name: 'primary-database' },
1251
+ ['secretsmanager:GetSecretValue'],
1252
+ [secretArn(context, activeDatabase, 'readwrite')],
1253
+ ),
1254
+ lambdaVpcIntent(roleId('api-protected')),
1255
+ ]),
1256
+ lambda('api-database-health', 'database-health', [
1257
+ intent(
1258
+ roleId('api-database-health') + '.database-secret',
1259
+ { kind: 'secret-link', name: 'primary-database' },
1260
+ ['secretsmanager:GetSecretValue'],
1261
+ [secretArn(context, activeDatabase, 'readwrite')],
1262
+ ),
1263
+ lambdaVpcIntent(roleId('api-database-health')),
1264
+ ]),
1265
+ lambda('api-database-records', 'database-records', [
1266
+ logIntent(
1267
+ context,
1268
+ roleId('api-database-records') + '.data-retention-review',
1269
+ 'data-retention-review',
1270
+ ),
1271
+ intent(
1272
+ roleId('api-database-records') + '.database-secret',
1273
+ { kind: 'secret-link', name: 'primary-database' },
1274
+ ['secretsmanager:GetSecretValue'],
1275
+ [secretArn(context, activeDatabase, 'readwrite')],
1276
+ ),
1277
+ intent(
1278
+ roleId('api-database-records') + '.event-bus',
1279
+ { kind: 'link', name: 'foundation-event-bus' },
1280
+ ['events:PutEvents'],
1281
+ [context.eventBusArn],
1282
+ ),
1283
+ lambdaVpcIntent(roleId('api-database-records')),
1284
+ ]),
1285
+ lambda('api-publish-created', 'event-publisher', [
1286
+ intent(
1287
+ roleId('api-publish-created') + '.database-secret',
1288
+ { kind: 'secret-link', name: 'primary-database' },
1289
+ ['secretsmanager:GetSecretValue'],
1290
+ [secretArn(context, activeDatabase, 'readwrite')],
1291
+ ),
1292
+ intent(
1293
+ roleId('api-publish-created') + '.event-bus',
1294
+ { kind: 'link', name: 'foundation-event-bus' },
1295
+ ['events:PutEvents'],
1296
+ [context.eventBusArn],
1297
+ ),
1298
+ lambdaVpcIntent(roleId('api-publish-created')),
1299
+ ]),
1300
+ lambda('async-outbox-relay', 'async-outbox-relay', [
1301
+ intent(
1302
+ roleId('async-outbox-relay') + '.database-secret',
1303
+ { kind: 'secret-link', name: 'primary-database' },
1304
+ ['secretsmanager:GetSecretValue'],
1305
+ [secretArn(context, activeDatabase, 'readwrite')],
1306
+ ),
1307
+ intent(
1308
+ roleId('async-outbox-relay') + '.event-bus',
1309
+ { kind: 'link', name: 'foundation-event-bus' },
1310
+ ['events:PutEvents'],
1311
+ [context.eventBusArn],
1312
+ ),
1313
+ lambdaVpcIntent(roleId('async-outbox-relay')),
1314
+ ]),
1315
+ lambda('async-inbox-cleanup', 'async-inbox-cleanup', [
1316
+ intent(
1317
+ roleId('async-inbox-cleanup') + '.database-secret',
1318
+ { kind: 'secret-link', name: 'primary-database' },
1319
+ ['secretsmanager:GetSecretValue'],
1320
+ [secretArn(context, activeDatabase, 'readwrite')],
1321
+ ),
1322
+ lambdaVpcIntent(roleId('async-inbox-cleanup')),
1323
+ ]),
1324
+ lambda('async-provider-worker', 'async-provider-worker', [
1325
+ {
1326
+ ...intent(
1327
+ roleId('async-provider-worker') + '.active-configuration',
1328
+ { kind: 'link', name: 'active-configuration' },
1329
+ [
1330
+ 'appconfig:GetLatestConfiguration',
1331
+ 'appconfig:StartConfigurationSession',
1332
+ ],
1333
+ [
1334
+ arn(
1335
+ context,
1336
+ 'appconfig',
1337
+ 'application/*/environment/*/configuration/*',
1338
+ ),
1339
+ ],
1340
+ ),
1341
+ conditions: {
1342
+ StringEquals: {
1343
+ 'aws:ResourceTag/ebk:slice': '${name}',
1344
+ 'aws:ResourceTag/ebk:stage': context.stage,
1345
+ },
1346
+ },
1347
+ },
1348
+ intent(
1349
+ roleId('async-provider-worker') + '.database-secret',
1350
+ { kind: 'secret-link', name: 'primary-database' },
1351
+ ['secretsmanager:GetSecretValue'],
1352
+ [secretArn(context, activeDatabase, 'readwrite')],
1353
+ ),
1354
+ intent(
1355
+ roleId('async-provider-worker') + '.queue-consume',
1356
+ { kind: 'permissions', name: 'provider-queue-subscription' },
1357
+ [
1358
+ 'sqs:ChangeMessageVisibility',
1359
+ 'sqs:DeleteMessage',
1360
+ 'sqs:GetQueueAttributes',
1361
+ 'sqs:GetQueueUrl',
1362
+ 'sqs:ReceiveMessage',
1363
+ ],
1364
+ [arn(context, 'sqs', names.providerQueue)],
1365
+ ),
1366
+ lambdaVpcIntent(roleId('async-provider-worker')),
1367
+ ]),
1368
+ lambda('async-schedule-target', 'async-schedule-target', [
1369
+ intent(
1370
+ roleId('async-schedule-target') + '.provider-queue',
1371
+ { kind: 'link', name: 'provider-queue' },
1372
+ ['sqs:SendMessage'],
1373
+ [arn(context, 'sqs', names.providerQueue)],
1374
+ ),
1375
+ ]),
1376
+ lambda('async-webhook-ingress', 'async-webhook-ingress', [
1377
+ intent(
1378
+ roleId('async-webhook-ingress') + '.provider-queue',
1379
+ { kind: 'link', name: 'provider-queue' },
1380
+ ['sqs:SendMessage'],
1381
+ [arn(context, 'sqs', names.providerQueue)],
1382
+ ),
1383
+ intent(
1384
+ roleId('async-webhook-ingress') + '.receipt-ledger',
1385
+ { kind: 'framework', name: 'async-webhook-receipt-ledger' },
1386
+ ['dynamodb:GetItem', 'dynamodb:PutItem', 'dynamodb:UpdateItem'],
1387
+ [
1388
+ arn(
1389
+ context,
1390
+ 'dynamodb',
1391
+ 'table/' + names.asyncRecoveryLedger,
1392
+ ),
1393
+ ],
1394
+ ),
1395
+ ]),
1396
+ {
1397
+ intents: [
1398
+ intent(
1399
+ roleId('async-workflow-orchestration') + '.workflow-task',
1400
+ { kind: 'permissions', name: 'async-workflow-task' },
1401
+ ['lambda:InvokeFunction'],
1402
+ [
1403
+ arn(
1404
+ context,
1405
+ 'lambda',
1406
+ 'function:' + names.workflowTaskFunction,
1407
+ ),
1408
+ ],
1409
+ ),
1410
+ ],
1411
+ roleId: roleId('async-workflow-orchestration'),
1412
+ },
1413
+ lambda('async-workflow-task', 'async-workflow-task', [
1414
+ intent(
1415
+ roleId('async-workflow-task') + '.cancellation-ledger',
1416
+ { kind: 'framework', name: 'async-workflow-cancellation-ledger' },
1417
+ ['dynamodb:GetItem', 'dynamodb:PutItem', 'dynamodb:UpdateItem'],
1418
+ [
1419
+ arn(
1420
+ context,
1421
+ 'dynamodb',
1422
+ 'table/' + names.asyncRecoveryLedger,
1423
+ ),
1424
+ ],
1425
+ ),
1426
+ ]),
1427
+ {
1428
+ intents: [
1429
+ intent(
1430
+ roleId('configuration-monitor') + '.describe-alarms',
1431
+ { kind: 'framework', name: 'appconfig-alarm-monitor' },
1432
+ ['cloudwatch:DescribeAlarms'],
1433
+ ['*'],
1434
+ 'CloudWatch DescribeAlarms does not support resource-level permissions.',
1435
+ ),
1436
+ ],
1437
+ roleId: roleId('configuration-monitor'),
1438
+ },
1439
+ lambda('data-export-cleanup', 'job-data-export-cleanup', [
1440
+ intent(
1441
+ roleId('data-export-cleanup') + '.database-secret',
1442
+ { kind: 'secret-link', name: 'primary-database' },
1443
+ ['secretsmanager:GetSecretValue'],
1444
+ [secretArn(context, activeDatabase, 'readwrite')],
1445
+ ),
1446
+ ...dataExportStorageIntents(
1447
+ context,
1448
+ roleId('data-export-cleanup'),
1449
+ 'cleanup',
1450
+ ),
1451
+ lambdaVpcIntent(roleId('data-export-cleanup')),
1452
+ ]),
1453
+ lambda('event-consumer', 'event-consumer', [
1454
+ intent(
1455
+ roleId('event-consumer') + '.database-secret',
1456
+ { kind: 'secret-link', name: 'primary-database' },
1457
+ ['secretsmanager:GetSecretValue'],
1458
+ [secretArn(context, activeDatabase, 'readwrite')],
1459
+ ),
1460
+ intent(
1461
+ roleId('event-consumer') + '.queue-consume',
1462
+ { kind: 'permissions', name: 'event-queue-subscription' },
1463
+ [
1464
+ 'sqs:ChangeMessageVisibility',
1465
+ 'sqs:DeleteMessage',
1466
+ 'sqs:GetQueueAttributes',
1467
+ 'sqs:GetQueueUrl',
1468
+ 'sqs:ReceiveMessage',
1469
+ ],
1470
+ [arn(context, 'sqs', names.eventQueue)],
1471
+ ),
1472
+ lambdaVpcIntent(roleId('event-consumer')),
1473
+ ]),
1474
+ lambda('machine-client-provisioner', 'machine-client-provisioner', [
1475
+ intent(
1476
+ roleId('machine-client-provisioner') + '.cognito-client',
1477
+ {
1478
+ kind: 'permissions',
1479
+ name: 'machine-client-provisioning',
1480
+ },
1481
+ [
1482
+ 'cognito-idp:CreateUserPoolClient',
1483
+ 'cognito-idp:DeleteUserPoolClient',
1484
+ 'cognito-idp:DescribeUserPoolClient',
1485
+ 'cognito-idp:ListUserPoolClients',
1486
+ ],
1487
+ [context.identityUserPoolArn],
1488
+ ),
1489
+ intent(
1490
+ roleId('machine-client-provisioner') + '.machine-secret',
1491
+ {
1492
+ kind: 'permissions',
1493
+ name: 'machine-client-provisioning',
1494
+ },
1495
+ [
1496
+ 'secretsmanager:GetSecretValue',
1497
+ 'secretsmanager:PutSecretValue',
1498
+ 'secretsmanager:UpdateSecretVersionStage',
1499
+ ],
1500
+ [machineAuthorizationSecretArn(context)],
1501
+ ),
1502
+ ]),
1503
+ lambda(
1504
+ 'machine-authorization-proof',
1505
+ 'machine-authorization-proof',
1506
+ [
1507
+ intent(
1508
+ roleId('machine-authorization-proof') + '.machine-secret',
1509
+ {
1510
+ kind: 'permissions',
1511
+ name: 'machine-authorization-proof',
1512
+ },
1513
+ ['secretsmanager:GetSecretValue'],
1514
+ [machineAuthorizationSecretArn(context)],
1515
+ ),
1516
+ ],
1517
+ ),
1518
+ lambda('web-image-optimizer', 'next-image-optimizer', [
1519
+ intent(
1520
+ roleId('web-image-optimizer') + '.assets',
1521
+ { kind: 'framework', name: 'next-image-optimizer' },
1522
+ ['s3:GetObject'],
1523
+ [
1524
+ 'arn:' +
1525
+ context.partition +
1526
+ ':s3:::' +
1527
+ names.webAssetsBucket +
1528
+ '/*',
1529
+ ],
1530
+ ),
1531
+ ]),
1532
+ lambda('web-revalidation-seeder', 'next-revalidation-seeder', [
1533
+ intent(
1534
+ roleId('web-revalidation-seeder') + '.tag-cache',
1535
+ { kind: 'framework', name: 'next-revalidation-seeder' },
1536
+ [
1537
+ 'dynamodb:BatchWriteItem',
1538
+ 'dynamodb:DescribeTable',
1539
+ 'dynamodb:PutItem',
1540
+ ],
1541
+ [nextTable],
1542
+ ),
1543
+ ]),
1544
+ lambda(
1545
+ 'web-revalidation-subscriber',
1546
+ 'next-revalidation-subscriber',
1547
+ [
1548
+ intent(
1549
+ roleId('web-revalidation-subscriber') + '.queue-consume',
1550
+ { kind: 'framework', name: 'next-revalidation-subscriber' },
1551
+ [
1552
+ 'sqs:ChangeMessageVisibility',
1553
+ 'sqs:DeleteMessage',
1554
+ 'sqs:GetQueueAttributes',
1555
+ 'sqs:GetQueueUrl',
1556
+ 'sqs:ReceiveMessage',
1557
+ ],
1558
+ [nextQueue],
1559
+ ),
1560
+ ],
1561
+ ),
1562
+ lambda('web-server', 'next-server', [
1563
+ {
1564
+ ...intent(
1565
+ roleId('web-server') + '.active-configuration',
1566
+ { kind: 'link', name: 'active-configuration' },
1567
+ [
1568
+ 'appconfig:GetLatestConfiguration',
1569
+ 'appconfig:StartConfigurationSession',
1570
+ ],
1571
+ [
1572
+ arn(
1573
+ context,
1574
+ 'appconfig',
1575
+ 'application/*/environment/*/configuration/*',
1576
+ ),
1577
+ ],
1578
+ ),
1579
+ conditions: {
1580
+ StringEquals: {
1581
+ 'aws:ResourceTag/ebk:slice': '${name}',
1582
+ 'aws:ResourceTag/ebk:stage': context.stage,
1583
+ },
1584
+ },
1585
+ },
1586
+ intent(
1587
+ roleId('web-server') + '.cache-assets',
1588
+ { kind: 'framework', name: 'next-server-cache' },
1589
+ ['s3:DeleteObject', 's3:GetObject', 's3:ListBucket', 's3:PutObject'],
1590
+ [
1591
+ 'arn:' + context.partition + ':s3:::' + names.webAssetsBucket,
1592
+ 'arn:' + context.partition + ':s3:::' + names.webAssetsBucket + '/*',
1593
+ ],
1594
+ ),
1595
+ intent(
1596
+ roleId('web-server') + '.tag-cache',
1597
+ { kind: 'framework', name: 'next-server-cache' },
1598
+ [
1599
+ 'dynamodb:BatchGetItem',
1600
+ 'dynamodb:BatchWriteItem',
1601
+ 'dynamodb:ConditionCheckItem',
1602
+ 'dynamodb:DeleteItem',
1603
+ 'dynamodb:DescribeTable',
1604
+ 'dynamodb:GetItem',
1605
+ 'dynamodb:GetRecords',
1606
+ 'dynamodb:GetShardIterator',
1607
+ 'dynamodb:PutItem',
1608
+ 'dynamodb:Query',
1609
+ 'dynamodb:Scan',
1610
+ 'dynamodb:UpdateItem',
1611
+ ],
1612
+ [nextTable, nextTable + '/*'],
1613
+ ),
1614
+ intent(
1615
+ roleId('web-server') + '.revalidation-queue',
1616
+ { kind: 'framework', name: 'next-server-cache' },
1617
+ ['sqs:GetQueueAttributes', 'sqs:GetQueueUrl', 'sqs:SendMessage'],
1618
+ [nextQueue],
1619
+ ),
1620
+ intent(
1621
+ roleId('web-server') + '.database-secret',
1622
+ { kind: 'secret-link', name: 'primary-database' },
1623
+ ['secretsmanager:GetSecretValue'],
1624
+ [secretArn(context, activeDatabase, 'readwrite')],
1625
+ ),
1626
+ intent(
1627
+ roleId('web-server') + '.invalidate-cdn',
1628
+ { kind: 'framework', name: 'next-server-cache' },
1629
+ ['cloudfront:CreateInvalidation'],
1630
+ [
1631
+ 'arn:' +
1632
+ context.partition +
1633
+ ':cloudfront::' +
1634
+ context.accountId +
1635
+ ':distribution/*',
1636
+ ],
1637
+ ),
1638
+ lambdaVpcIntent(roleId('web-server')),
1639
+ ]),
1640
+ ...plan.provisioned.flatMap((database) =>
1641
+ databaseContributions(context, database),
1642
+ ),
1643
+ ...dataRetentionContributions(context, activeDatabase),
1644
+ // <ebk:workload-role-intent-contributions:start>
1645
+ // <ebk:workload-role-intent-contributions:end>
1646
+ ];
1647
+ const secretAccess = new Map(
1648
+ standardSliceSecretAccessPlan(
1649
+ context,
1650
+ topology,
1651
+ secretReferences,
1652
+ ).map((entry) => [entry.workload, entry]),
1653
+ );
1654
+ const uncomposedSecretAccess = new Set(secretAccess.keys());
1655
+ const contributionsWithSecretAccess = contributions.map((contribution) => {
1656
+ const entries: SecretWorkloadAccessPlanEntry[] = [];
1657
+ const direct = secretAccess.get(contribution.roleId);
1658
+ if (direct) {
1659
+ entries.push(direct);
1660
+ uncomposedSecretAccess.delete(contribution.roleId);
1661
+ }
1662
+ const performanceMatch = /^(.*)-service-performance-task$/.exec(
1663
+ contribution.roleId,
1664
+ );
1665
+ if (performanceMatch?.[1]) {
1666
+ const base = secretAccess.get(
1667
+ performanceMatch[1] + '-service-task',
1668
+ );
1669
+ if (base) entries.push(base);
1670
+ }
1671
+ if (entries.length === 0) return contribution;
1672
+ return {
1673
+ ...contribution,
1674
+ intents: [
1675
+ ...contribution.intents,
1676
+ ...entries.flatMap((entry) => entry.intent.links).map((link) =>
1677
+ intent(
1678
+ 'operator-secret.' +
1679
+ createHash('sha256')
1680
+ .update(
1681
+ contribution.roleId +
1682
+ '\\0' +
1683
+ link.link.properties.logicalName,
1684
+ 'utf8',
1685
+ )
1686
+ .digest('hex')
1687
+ .slice(0, 32),
1688
+ {
1689
+ kind: 'secret-link',
1690
+ name: link.link.properties.logicalName,
1691
+ },
1692
+ [...link.permission.Action],
1693
+ [...link.permission.Resource],
1694
+ ),
1695
+ ),
1696
+ ],
1697
+ };
1698
+ });
1699
+ if (uncomposedSecretAccess.size > 0) {
1700
+ throw new Error(
1701
+ 'Secret workload access did not compose into an exact Standard Slice role.',
1702
+ );
1703
+ }
1704
+ return composeStandardSliceWorkloadRoleIntentSource(
1705
+ topology,
1706
+ contributionsWithSecretAccess,
1707
+ );
1708
+ }
1709
+
1710
+ /**
1711
+ * Composes the exact framework/link/permission/secret-link provenance emitted
1712
+ * by resource renderers. Missing, duplicate, and undeclared role IDs fail
1713
+ * before candidate digest construction. An explicit empty intent array is a
1714
+ * valid deny-all policy for a role that calls no AWS APIs.
1715
+ */
1716
+ export function composeStandardSliceWorkloadRoleIntentSource(
1717
+ topology: StandardSliceWorkloadRoleTopology,
1718
+ contributions: readonly StandardSliceWorkloadRoleIntentContribution[],
1719
+ ): Readonly<Record<string, readonly WorkloadRolePermissionIntent[]>> {
1720
+ const expected = new Set(topology.roles.map(({ id }) => id));
1721
+ const source: Record<string, readonly WorkloadRolePermissionIntent[]> = {};
1722
+ for (const contribution of contributions) {
1723
+ if (
1724
+ !expected.has(contribution.roleId) ||
1725
+ Object.prototype.hasOwnProperty.call(source, contribution.roleId)
1726
+ ) {
1727
+ throw new Error(
1728
+ 'Standard Slice workload-role intent source is incomplete, duplicated, or substituted.',
1729
+ );
1730
+ }
1731
+ source[contribution.roleId] = contribution.intents;
1732
+ }
1733
+ const missing = [...expected].filter(
1734
+ (roleId) => !Object.prototype.hasOwnProperty.call(source, roleId),
1735
+ );
1736
+ if (missing.length > 0) {
1737
+ throw new Error(
1738
+ 'Standard Slice workload-role intent source is missing: ' +
1739
+ missing.sort().join(', '),
1740
+ );
1741
+ }
1742
+ return source;
1743
+ }
1744
+ `,
1745
+ 'infra/workload-roles/injection.ts': `import {
1746
+ createRawAppConfigMonitorRoleInput,
1747
+ createRawStepFunctionsRoleInput,
1748
+ createSstFargateRoleInput,
1749
+ createSstFunctionRoleInput,
1750
+ type ExactProvisionedWorkloadRoleRegistry,
1751
+ } from '@empire-builder-kit/nx/workload-roles';
1752
+
1753
+ const roleId = (resource: string) => '${name}.' + resource;
1754
+
1755
+ export function createStandardSliceWorkloadRoleBindings(
1756
+ registry: ExactProvisionedWorkloadRoleRegistry,
1757
+ ) {
1758
+ const functionRole = (resource: string) =>
1759
+ createSstFunctionRoleInput(registry, roleId(resource));
1760
+ const fargateRoles = (resource: string, kind: 'bootstrap' | 'job' | 'migration' | 'retirement' | 'service') =>
1761
+ createSstFargateRoleInput(registry, {
1762
+ executionRoleId: roleId(resource + '-' + kind + '-execution'),
1763
+ taskRoleId: roleId(resource + '-' + kind + '-task'),
1764
+ });
1765
+ const servicePerformanceRoles = (resource: string) =>
1766
+ createSstFargateRoleInput(registry, {
1767
+ executionRoleId: roleId(resource + '-service-execution'),
1768
+ taskRoleId: roleId(resource + '-service-performance-task'),
1769
+ });
1770
+ const orchestrationRole = (
1771
+ database: string,
1772
+ kind: 'migration' | 'retirement',
1773
+ ) =>
1774
+ createRawStepFunctionsRoleInput(
1775
+ registry,
1776
+ roleId('database-' + database + '-' + kind + '-orchestration'),
1777
+ );
1778
+
1779
+ return {
1780
+ api: {
1781
+ dataRights: functionRole('api-data-rights'),
1782
+ databaseHealth: functionRole('api-database-health'),
1783
+ databaseRecords: functionRole('api-database-records'),
1784
+ delegations: functionRole('api-delegations'),
1785
+ health: functionRole('api-health'),
1786
+ machineAuthorizationProof: functionRole(
1787
+ 'api-machine-authorization-proof',
1788
+ ),
1789
+ protected: functionRole('api-protected'),
1790
+ publishCreated: functionRole('api-publish-created'),
1791
+ },
1792
+ authorization: {
1793
+ provisioner: functionRole('machine-client-provisioner'),
1794
+ proof: functionRole('machine-authorization-proof'),
1795
+ },
1796
+ configuration: {
1797
+ monitor: createRawAppConfigMonitorRoleInput(
1798
+ registry,
1799
+ roleId('configuration-monitor'),
1800
+ ),
1801
+ },
1802
+ async: {
1803
+ inboxCleanup: functionRole('async-inbox-cleanup'),
1804
+ outboxRelay: functionRole('async-outbox-relay'),
1805
+ providerWorker: functionRole('async-provider-worker'),
1806
+ scheduleTarget: functionRole('async-schedule-target'),
1807
+ webhookIngress: functionRole('async-webhook-ingress'),
1808
+ workflowOrchestration: createRawStepFunctionsRoleInput(
1809
+ registry,
1810
+ roleId('async-workflow-orchestration'),
1811
+ ),
1812
+ workflowTask: functionRole('async-workflow-task'),
1813
+ },
1814
+ database(database: string) {
1815
+ const resource = 'database-' + database;
1816
+ const retirement =
1817
+ database === 'retirement_rehearsal'
1818
+ ? {
1819
+ orchestration: orchestrationRole(database, 'retirement'),
1820
+ task: fargateRoles(resource, 'retirement'),
1821
+ }
1822
+ : undefined;
1823
+ return {
1824
+ bootstrap: fargateRoles(resource, 'bootstrap'),
1825
+ migration: fargateRoles(resource, 'migration'),
1826
+ migrationOrchestration: orchestrationRole(database, 'migration'),
1827
+ retirement,
1828
+ };
1829
+ },
1830
+ dataRetention: {
1831
+ maintenance: {
1832
+ launcher: functionRole('data-retention-maintenance-launcher'),
1833
+ task: fargateRoles('data-retention-maintenance', 'job'),
1834
+ },
1835
+ orchestration: createRawStepFunctionsRoleInput(
1836
+ registry,
1837
+ roleId('data-retention-job-orchestration'),
1838
+ ),
1839
+ task: fargateRoles('data-retention', 'job'),
1840
+ },
1841
+ dataExport: {
1842
+ cleanup: functionRole('data-export-cleanup'),
1843
+ },
1844
+ extension: {
1845
+ function(id: string) {
1846
+ return functionRole(id + '-function');
1847
+ },
1848
+ job(id: string) {
1849
+ return fargateRoles(id, 'job');
1850
+ },
1851
+ service(id: string) {
1852
+ return fargateRoles(id, 'service');
1853
+ },
1854
+ servicePerformance(id: string) {
1855
+ return servicePerformanceRoles(id);
1856
+ },
1857
+ },
1858
+ next: {
1859
+ imageOptimizer: functionRole('web-image-optimizer'),
1860
+ revalidationSeeder: functionRole('web-revalidation-seeder'),
1861
+ revalidationSubscriber: functionRole(
1862
+ 'web-revalidation-subscriber',
1863
+ ),
1864
+ server: functionRole('web-server'),
1865
+ },
1866
+ queue: {
1867
+ eventConsumer: functionRole('event-consumer'),
1868
+ },
1869
+ };
1870
+ }
1871
+ `,
1872
+ 'infra/workload-roles/report.ts': `import {
1873
+ createRegisteredWorkloadRoleManifestDocument,
1874
+ digestWorkloadRoleManifest,
1875
+ workloadRoleProvisionerAliasArn,
1876
+ } from '@empire-builder-kit/nx/workload-roles';
1877
+ import { createStandardSliceCandidate } from './candidate.js';
1878
+ import { discoverStandardSliceWorkloadRoleCandidate } from './preflight.js';
1879
+
1880
+ /**
1881
+ * Builds the exact registered candidate document from generated intent and
1882
+ * read-only AWS discovery. It does not read an existing workload-role
1883
+ * registration and has no mutation client.
1884
+ */
1885
+ export async function reportWorkloadRoleCandidate(options: {
1886
+ candidateIdentity: string;
1887
+ region: string;
1888
+ stage: string;
1889
+ }) {
1890
+ const discovery =
1891
+ await discoverStandardSliceWorkloadRoleCandidate(options);
1892
+ const candidate = createStandardSliceCandidate({
1893
+ accountId: discovery.accountId,
1894
+ candidateIdentity: discovery.candidateIdentity,
1895
+ intentContext: discovery.intentContext,
1896
+ partition: discovery.partition,
1897
+ secretReferences: discovery.secretReferences,
1898
+ stage: discovery.stage,
1899
+ });
1900
+ const manifestDigest = digestWorkloadRoleManifest(candidate.manifest);
1901
+ return createRegisteredWorkloadRoleManifestDocument({
1902
+ accountId: discovery.accountId,
1903
+ intentsByRole: candidate.intentsByRole,
1904
+ manifest: candidate.manifest,
1905
+ partition: discovery.partition,
1906
+ project: '${name}',
1907
+ provisionerFunctionArn: workloadRoleProvisionerAliasArn({
1908
+ accountId: discovery.accountId,
1909
+ manifestDigest,
1910
+ partition: discovery.partition,
1911
+ project: '${name}',
1912
+ region: discovery.region,
1913
+ stage: discovery.stage,
1914
+ }),
1915
+ });
1916
+ }
1917
+ `,
1918
+ 'infra/workload-roles/preflight.ts': `import {
1919
+ DescribeSecretCommand,
1920
+ SecretsManagerClient,
1921
+ } from '@aws-sdk/client-secrets-manager';
1922
+ import { GetObjectCommand, S3Client } from '@aws-sdk/client-s3';
1923
+ import { GetParameterCommand, SSMClient } from '@aws-sdk/client-ssm';
1924
+ import { GetCallerIdentityCommand, STSClient } from '@aws-sdk/client-sts';
1925
+ import {
1926
+ foundationSsmPath,
1927
+ resolveFoundationStages,
1928
+ } from '@empire-builder-kit/nx/foundation';
1929
+ import {
1930
+ canonicalOperatorSecretName,
1931
+ canonicalOperatorSecretTags,
1932
+ isExactSecretArn,
1933
+ isRotationCompliant,
1934
+ validateObservedSecretMetadata,
1935
+ type SecretManagementScope,
1936
+ type SecretMetadataDeclaration,
1937
+ type WorkloadSecretReferenceInput,
1938
+ } from '@empire-builder-kit/nx/secrets';
1939
+ import {
1940
+ digestWorkloadRoleManifest,
1941
+ provisionedWorkloadRoleRegistrationObjectKey,
1942
+ registeredWorkloadRoleManifestObjectKey,
1943
+ requireRegisteredWorkloadRoleManifestDocument,
1944
+ requireWorkloadRoleStorageRegistration,
1945
+ validateWorkloadRolePreflight,
1946
+ workloadRoleStorageRegistrationPath,
1947
+ } from '@empire-builder-kit/nx/workload-roles';
1948
+ import {
1949
+ createStandardSliceWorkloadRoleTopology,
1950
+ recreateRegisteredStandardSliceCandidate,
1951
+ } from './candidate.js';
1952
+ import {
1953
+ standardSliceBoundOperatorSecretDeclarations,
1954
+ standardSliceSecretAccessPlan,
1955
+ } from './effective-intent.js';
1956
+ import { createStandardSliceWorkloadRoleBindings } from './injection.js';
1957
+
1958
+ function requiredRegion(): string {
1959
+ const value = (
1960
+ process.env.AWS_REGION ??
1961
+ process.env.AWS_DEFAULT_REGION ??
1962
+ ''
1963
+ ).trim();
1964
+ if (!/^[a-z]{2}(?:-gov)?-[a-z]+-\\d$/.test(value)) {
1965
+ throw new Error(
1966
+ 'Protected workload-role preflight requires one explicit AWS Region.',
1967
+ );
1968
+ }
1969
+ return value;
1970
+ }
1971
+
1972
+ function requiredCandidateIdentity(): string {
1973
+ const value = process.env.EBK_CANDIDATE_IDENTITY?.trim();
1974
+ if (!value || !/^[a-z0-9][a-z0-9._-]{0,127}$/.test(value)) {
1975
+ throw new Error(
1976
+ 'EBK_CANDIDATE_IDENTITY must name the exact protected candidate.',
1977
+ );
1978
+ }
1979
+ return value;
1980
+ }
1981
+
1982
+ async function readParameterValue(
1983
+ ssm: SSMClient,
1984
+ path: string,
1985
+ ): Promise<string> {
1986
+ const response = await ssm.send(
1987
+ new GetParameterCommand({ Name: path, WithDecryption: false }),
1988
+ );
1989
+ const value = response.Parameter?.Value;
1990
+ if (!value) {
1991
+ throw new Error('Required workload-role registration is absent.');
1992
+ }
1993
+ return value;
1994
+ }
1995
+
1996
+ async function readFixedParameter(
1997
+ ssm: SSMClient,
1998
+ path: string,
1999
+ ): Promise<unknown> {
2000
+ const value = await readParameterValue(ssm, path);
2001
+ try {
2002
+ return JSON.parse(value) as unknown;
2003
+ } catch {
2004
+ throw new Error('Required workload-role registration is malformed.');
2005
+ }
2006
+ }
2007
+
2008
+ async function readFixedObject(
2009
+ s3: S3Client,
2010
+ bucketName: string,
2011
+ key: string,
2012
+ ): Promise<unknown> {
2013
+ const response = await s3.send(
2014
+ new GetObjectCommand({ Bucket: bucketName, Key: key }),
2015
+ );
2016
+ if (!response.Body) {
2017
+ throw new Error('Required workload-role object is absent.');
2018
+ }
2019
+ try {
2020
+ return JSON.parse(await response.Body.transformToString()) as unknown;
2021
+ } catch {
2022
+ throw new Error('Required workload-role object is malformed.');
2023
+ }
2024
+ }
2025
+
2026
+ async function observeOperatorSecretReferences(input: {
2027
+ accountId: string;
2028
+ client: SecretsManagerClient;
2029
+ declarations: readonly SecretMetadataDeclaration[];
2030
+ partition: string;
2031
+ region: string;
2032
+ stage: string;
2033
+ }): Promise<readonly WorkloadSecretReferenceInput[]> {
2034
+ const scope: SecretManagementScope = {
2035
+ slice: '${name}',
2036
+ stage: input.stage,
2037
+ workspace: '${workspace}',
2038
+ };
2039
+ return Object.freeze(
2040
+ await Promise.all(
2041
+ input.declarations.map(async (declaration) => {
2042
+ const name = canonicalOperatorSecretName(
2043
+ scope,
2044
+ declaration.logicalName,
2045
+ );
2046
+ const response = await input.client.send(
2047
+ new DescribeSecretCommand({ SecretId: name }),
2048
+ );
2049
+ const arn = response.ARN ?? '';
2050
+ const arnPrefix =
2051
+ 'arn:' +
2052
+ input.partition +
2053
+ ':secretsmanager:' +
2054
+ input.region +
2055
+ ':' +
2056
+ input.accountId +
2057
+ ':secret:' +
2058
+ name +
2059
+ '-';
2060
+ const suffix = arn.startsWith(arnPrefix)
2061
+ ? arn.slice(arnPrefix.length)
2062
+ : '';
2063
+ const tags: Record<string, string> = {};
2064
+ for (const tag of response.Tags ?? []) {
2065
+ if (
2066
+ !tag.Key ||
2067
+ tag.Value === undefined ||
2068
+ Object.prototype.hasOwnProperty.call(tags, tag.Key)
2069
+ ) {
2070
+ throw new Error(
2071
+ 'Protected operator-secret metadata is malformed.',
2072
+ );
2073
+ }
2074
+ tags[tag.Key] = tag.Value;
2075
+ }
2076
+ const versionStages = Object.values(
2077
+ response.VersionIdsToStages ?? {},
2078
+ ).flatMap((stages) => stages ?? []);
2079
+ const observed = {
2080
+ arn,
2081
+ name: response.Name ?? '',
2082
+ rotationEnabled: response.RotationEnabled === true,
2083
+ tags,
2084
+ versionStages,
2085
+ };
2086
+ validateObservedSecretMetadata(observed);
2087
+ const expectedTags = canonicalOperatorSecretTags(
2088
+ scope,
2089
+ declaration,
2090
+ );
2091
+ if (
2092
+ response.DeletedDate ||
2093
+ observed.name !== name ||
2094
+ !isExactSecretArn(arn) ||
2095
+ !/^[A-Za-z0-9]{6}$/.test(suffix) ||
2096
+ !versionStages.includes('AWSCURRENT') ||
2097
+ !isRotationCompliant(declaration, observed) ||
2098
+ Object.entries(expectedTags).some(
2099
+ ([key, value]) => tags[key] !== value,
2100
+ )
2101
+ ) {
2102
+ throw new Error(
2103
+ 'Protected operator-secret metadata is not deployment ready.',
2104
+ );
2105
+ }
2106
+ return {
2107
+ logicalName: declaration.logicalName,
2108
+ provider: 'aws-secrets-manager' as const,
2109
+ secretArn: arn,
2110
+ };
2111
+ }),
2112
+ ),
2113
+ );
2114
+ }
2115
+
2116
+ export async function discoverStandardSliceWorkloadRoleCandidate(options: {
2117
+ candidateIdentity: string;
2118
+ region: string;
2119
+ stage: string;
2120
+ }) {
2121
+ if (
2122
+ !/^[a-z0-9][a-z0-9._-]{0,127}$/.test(options.candidateIdentity) ||
2123
+ !/^[a-z]{2}(?:-gov)?-[a-z]+-\\d$/.test(options.region) ||
2124
+ !['development', 'staging', 'production'].includes(options.stage)
2125
+ ) {
2126
+ throw new Error(
2127
+ 'Protected workload-role candidate discovery input is invalid.',
2128
+ );
2129
+ }
2130
+ const secrets = new SecretsManagerClient({ region: options.region });
2131
+ const ssm = new SSMClient({ region: options.region });
2132
+ const identity = await new STSClient({ region: options.region }).send(
2133
+ new GetCallerIdentityCommand({}),
2134
+ );
2135
+ const accountId = identity.Account;
2136
+ const partition = /^arn:([^:]+):/.exec(identity.Arn ?? '')?.[1];
2137
+ if (
2138
+ !accountId ||
2139
+ !/^\\d{12}$/.test(accountId) ||
2140
+ !partition ||
2141
+ !['aws', 'aws-cn', 'aws-us-gov'].includes(partition)
2142
+ ) {
2143
+ throw new Error(
2144
+ 'Protected workload-role candidate discovery could not prove the current AWS account and partition.',
2145
+ );
2146
+ }
2147
+ const foundationStage = resolveFoundationStages({
2148
+ consumerStage: options.stage,
2149
+ foundationStage: process.env.EBK_FOUNDATION_STAGE,
2150
+ }).foundationStage;
2151
+ const [
2152
+ clusterId,
2153
+ clusterResourceId,
2154
+ eventBusArn,
2155
+ identityUserPoolArn,
2156
+ masterSecretArn,
2157
+ ] = await Promise.all([
2158
+ readParameterValue(
2159
+ ssm,
2160
+ foundationSsmPath(foundationStage, 'clusterId'),
2161
+ ),
2162
+ readParameterValue(
2163
+ ssm,
2164
+ foundationSsmPath(foundationStage, 'databaseClusterResourceId'),
2165
+ ),
2166
+ readParameterValue(
2167
+ ssm,
2168
+ foundationSsmPath(foundationStage, 'eventBusArn'),
2169
+ ),
2170
+ readParameterValue(
2171
+ ssm,
2172
+ foundationSsmPath(foundationStage, 'identityUserPoolArn'),
2173
+ ),
2174
+ readParameterValue(
2175
+ ssm,
2176
+ foundationSsmPath(foundationStage, 'databaseMasterSecretArn'),
2177
+ ),
2178
+ ]);
2179
+ const clusterArnPrefix =
2180
+ 'arn:' +
2181
+ partition +
2182
+ ':ecs:' +
2183
+ options.region +
2184
+ ':' +
2185
+ accountId +
2186
+ ':cluster/';
2187
+ if (
2188
+ !clusterId.startsWith(clusterArnPrefix) ||
2189
+ !/^[A-Za-z0-9_-]{1,255}$/.test(clusterId.slice(clusterArnPrefix.length))
2190
+ ) {
2191
+ throw new Error(
2192
+ 'Foundation cluster registration differs from the active AWS identity.',
2193
+ );
2194
+ }
2195
+ const userPoolArnPrefix =
2196
+ 'arn:' +
2197
+ partition +
2198
+ ':cognito-idp:' +
2199
+ options.region +
2200
+ ':' +
2201
+ accountId +
2202
+ ':userpool/';
2203
+ if (
2204
+ !identityUserPoolArn.startsWith(userPoolArnPrefix) ||
2205
+ !/^[A-Za-z0-9_-]+$/.test(
2206
+ identityUserPoolArn.slice(userPoolArnPrefix.length),
2207
+ )
2208
+ ) {
2209
+ throw new Error(
2210
+ 'Foundation identity registration differs from the active AWS identity.',
2211
+ );
2212
+ }
2213
+ const intentContext = {
2214
+ accountId,
2215
+ clusterName: clusterId.slice(clusterArnPrefix.length),
2216
+ clusterResourceId,
2217
+ eventBusArn,
2218
+ identityUserPoolArn,
2219
+ masterSecretArn,
2220
+ partition,
2221
+ region: options.region,
2222
+ stage: options.stage,
2223
+ };
2224
+ const topology = createStandardSliceWorkloadRoleTopology(options.stage);
2225
+ const secretReferences = await observeOperatorSecretReferences({
2226
+ accountId,
2227
+ client: secrets,
2228
+ declarations: standardSliceBoundOperatorSecretDeclarations(
2229
+ options.stage,
2230
+ topology,
2231
+ ),
2232
+ partition,
2233
+ region: options.region,
2234
+ stage: options.stage,
2235
+ });
2236
+ return {
2237
+ accountId,
2238
+ candidateIdentity: options.candidateIdentity,
2239
+ intentContext,
2240
+ partition,
2241
+ region: options.region,
2242
+ secretReferences,
2243
+ stage: options.stage,
2244
+ topology,
2245
+ };
2246
+ }
2247
+
2248
+ /**
2249
+ * Must run and resolve before importing infra/index.ts or constructing any SST
2250
+ * component. It reads one protected SSM pointer and two digest-keyed S3
2251
+ * objects, then returns the sole role registry, injection bindings, and
2252
+ * ordinary deployment-authority plan.
2253
+ */
2254
+ export async function preflightStandardSliceWorkloadRoles(stage: string) {
2255
+ const region = requiredRegion();
2256
+ const s3 = new S3Client({ region });
2257
+ const ssm = new SSMClient({ region });
2258
+ const candidateIdentity = requiredCandidateIdentity();
2259
+ const discovery = await discoverStandardSliceWorkloadRoleCandidate({
2260
+ candidateIdentity,
2261
+ region,
2262
+ stage,
2263
+ });
2264
+ const storageValue = await readFixedParameter(
2265
+ ssm,
2266
+ workloadRoleStorageRegistrationPath(stage, '${name}'),
2267
+ );
2268
+ const storage = requireWorkloadRoleStorageRegistration(storageValue);
2269
+ if (
2270
+ storage.candidateIdentity !== candidateIdentity ||
2271
+ storage.project !== '${name}' ||
2272
+ storage.stage !== stage
2273
+ ) {
2274
+ throw new Error(
2275
+ 'Protected workload-role storage registration differs from this deployment.',
2276
+ );
2277
+ }
2278
+ const registeredValue = await readFixedObject(
2279
+ s3,
2280
+ storage.bucketName,
2281
+ registeredWorkloadRoleManifestObjectKey({
2282
+ manifestDigest: storage.manifestDigest,
2283
+ project: '${name}',
2284
+ provisionerFunctionArn: storage.provisionerFunctionArn,
2285
+ stage,
2286
+ }),
2287
+ );
2288
+ const registered =
2289
+ requireRegisteredWorkloadRoleManifestDocument(registeredValue);
2290
+ if (
2291
+ registered.accountId !== discovery.accountId ||
2292
+ registered.partition !== discovery.partition
2293
+ ) {
2294
+ throw new Error(
2295
+ 'Protected workload-role registration differs from the active AWS identity.',
2296
+ );
2297
+ }
2298
+ const recreated = recreateRegisteredStandardSliceCandidate(
2299
+ registered,
2300
+ discovery.intentContext,
2301
+ discovery.secretReferences,
2302
+ );
2303
+ if (
2304
+ digestWorkloadRoleManifest(recreated.manifest) !== registered.manifestDigest ||
2305
+ registered.manifestDigest !== storage.manifestDigest ||
2306
+ JSON.stringify(recreated.intentsByRole) !==
2307
+ JSON.stringify(registered.intentsByRole)
2308
+ ) {
2309
+ throw new Error(
2310
+ 'Protected workload-role registration differs from generated Standard Slice intent.',
2311
+ );
2312
+ }
2313
+ const provisionedValue = await readFixedObject(
2314
+ s3,
2315
+ storage.bucketName,
2316
+ provisionedWorkloadRoleRegistrationObjectKey({
2317
+ manifestDigest: storage.manifestDigest,
2318
+ project: '${name}',
2319
+ provisionerFunctionArn: storage.provisionerFunctionArn,
2320
+ stage,
2321
+ }),
2322
+ );
2323
+ const preflight = validateWorkloadRolePreflight({
2324
+ expectedCandidateIdentity: candidateIdentity,
2325
+ expectedProject: '${name}',
2326
+ expectedStage: stage,
2327
+ provisionedRegistration: provisionedValue,
2328
+ registeredManifest: registeredValue,
2329
+ storageRegistration: storage,
2330
+ });
2331
+ return {
2332
+ authorityPlan: preflight.authorityPlan,
2333
+ bindings: createStandardSliceWorkloadRoleBindings(preflight.registry),
2334
+ intentContext: discovery.intentContext,
2335
+ registry: preflight.registry,
2336
+ secretAccess: standardSliceSecretAccessPlan(
2337
+ discovery.intentContext,
2338
+ discovery.topology,
2339
+ discovery.secretReferences,
2340
+ ),
2341
+ };
2342
+ }
2343
+
2344
+ export type StandardSliceWorkloadRolePreflight = Awaited<
2345
+ ReturnType<typeof preflightStandardSliceWorkloadRoles>
2346
+ >;
2347
+ `,
2348
+ 'infra/workload-roles/index.ts': `export * from './candidate.js';
2349
+ export * from './effective-intent.js';
2350
+ export * from './injection.js';
2351
+ export * from './preflight.js';
2352
+ export * from './report.js';
2353
+ `,
2354
+ };
2355
+ }
2356
+ //# sourceMappingURL=built-in-plan-workload-role-files.js.map