@empire-builder-kit/nx 1.0.0-rc.30 → 1.0.0-rc.32

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 (310) hide show
  1. package/executors.json +8 -3
  2. package/package.json +14 -7
  3. package/src/aws/child-environment.d.ts +10 -0
  4. package/src/aws/child-environment.js +77 -0
  5. package/src/aws/child-environment.js.map +1 -0
  6. package/src/aws/identity.d.ts +13 -0
  7. package/src/aws/identity.js +41 -0
  8. package/src/aws/identity.js.map +1 -0
  9. package/src/aws-authority/index.d.ts +1 -0
  10. package/src/aws-authority/index.js +5 -0
  11. package/src/aws-authority/index.js.map +1 -0
  12. package/src/aws-authority/stage-authority.d.ts +240 -0
  13. package/src/aws-authority/stage-authority.js +2968 -0
  14. package/src/aws-authority/stage-authority.js.map +1 -0
  15. package/src/cli/main.d.ts +2 -0
  16. package/src/cli/main.js +11 -0
  17. package/src/cli/main.js.map +1 -1
  18. package/src/developer-agent/generator-planning.js +4 -4
  19. package/src/developer-agent/generator-planning.js.map +1 -1
  20. package/src/developer-agent/operation-registry.js +14 -6
  21. package/src/developer-agent/operation-registry.js.map +1 -1
  22. package/src/developer-agent/workspace-inspection.js +11 -2
  23. package/src/developer-agent/workspace-inspection.js.map +1 -1
  24. package/src/executors/deployment-plan/deployment-plan.js +1 -1
  25. package/src/executors/deployment-plan/deployment-plan.js.map +1 -1
  26. package/src/executors/foundation-preflight/foundation-preflight.d.ts +0 -1
  27. package/src/executors/foundation-preflight/foundation-preflight.js.map +1 -1
  28. package/src/executors/foundation-preflight/schema.json +0 -5
  29. package/src/executors/foundation-profile-preflight/foundation-profile-preflight.d.ts +12 -3
  30. package/src/executors/foundation-profile-preflight/foundation-profile-preflight.js +95 -32
  31. package/src/executors/foundation-profile-preflight/foundation-profile-preflight.js.map +1 -1
  32. package/src/executors/foundation-profile-preflight/production-database-safeguard.d.ts +64 -0
  33. package/src/executors/foundation-profile-preflight/production-database-safeguard.js +221 -0
  34. package/src/executors/foundation-profile-preflight/production-database-safeguard.js.map +1 -0
  35. package/src/executors/foundation-profile-preflight/schema.json +1 -6
  36. package/src/executors/foundation-remove-preflight/foundation-remove-preflight.d.ts +11 -1
  37. package/src/executors/foundation-remove-preflight/foundation-remove-preflight.js +44 -21
  38. package/src/executors/foundation-remove-preflight/foundation-remove-preflight.js.map +1 -1
  39. package/src/executors/foundation-remove-preflight/schema.json +6 -1
  40. package/src/executors/github-bootstrap/github-bootstrap.d.ts +1 -0
  41. package/src/executors/github-bootstrap/github-bootstrap.js +1 -0
  42. package/src/executors/github-bootstrap/github-bootstrap.js.map +1 -1
  43. package/src/executors/github-bootstrap/schema.json +7 -1
  44. package/src/executors/infrastructure-plan/infrastructure-plan.d.ts +27 -369
  45. package/src/executors/infrastructure-plan/infrastructure-plan.js +237 -5470
  46. package/src/executors/infrastructure-plan/infrastructure-plan.js.map +1 -1
  47. package/src/executors/infrastructure-plan/schema.json +8 -64
  48. package/src/executors/local-deploy/federated-credential-transport.d.ts +48 -0
  49. package/src/executors/local-deploy/federated-credential-transport.js +252 -0
  50. package/src/executors/local-deploy/federated-credential-transport.js.map +1 -0
  51. package/src/executors/local-deploy/local-approval.d.ts +4 -9
  52. package/src/executors/local-deploy/local-approval.js +3 -7
  53. package/src/executors/local-deploy/local-approval.js.map +1 -1
  54. package/src/executors/local-deploy/local-deploy.d.ts +60 -43
  55. package/src/executors/local-deploy/local-deploy.js +955 -804
  56. package/src/executors/local-deploy/local-deploy.js.map +1 -1
  57. package/src/executors/local-deploy/schema.json +3 -20
  58. package/src/executors/refresh/refresh.js +2 -2
  59. package/src/executors/refresh/refresh.js.map +1 -1
  60. package/src/executors/remove/remove.js +2 -2
  61. package/src/executors/remove/remove.js.map +1 -1
  62. package/src/executors/router-waf-rehearsal/router-waf-rehearsal.d.ts +27 -1
  63. package/src/executors/router-waf-rehearsal/router-waf-rehearsal.js +907 -22
  64. package/src/executors/router-waf-rehearsal/router-waf-rehearsal.js.map +1 -1
  65. package/src/executors/router-waf-rehearsal/schema.json +17 -2
  66. package/src/executors/secret-initialize/schema.json +42 -0
  67. package/src/executors/secret-initialize/secret-initialize.d.ts +32 -0
  68. package/src/executors/secret-initialize/secret-initialize.js +243 -0
  69. package/src/executors/secret-initialize/secret-initialize.js.map +1 -0
  70. package/src/executors/secret-metadata/secret-metadata.d.ts +4 -1
  71. package/src/executors/secret-metadata/secret-metadata.js +76 -29
  72. package/src/executors/secret-metadata/secret-metadata.js.map +1 -1
  73. package/src/executors/sst-lifecycle/generated-secret-retirement.d.ts +53 -0
  74. package/src/executors/sst-lifecycle/generated-secret-retirement.js +192 -0
  75. package/src/executors/sst-lifecycle/generated-secret-retirement.js.map +1 -0
  76. package/src/executors/sst-lifecycle/governed-native-operation.d.ts +46 -0
  77. package/src/executors/sst-lifecycle/governed-native-operation.js +153 -0
  78. package/src/executors/sst-lifecycle/governed-native-operation.js.map +1 -0
  79. package/src/executors/sst-lifecycle/run-sst-command.d.ts +27 -7
  80. package/src/executors/sst-lifecycle/run-sst-command.js +474 -89
  81. package/src/executors/sst-lifecycle/run-sst-command.js.map +1 -1
  82. package/src/executors/sst-lifecycle/schema.json +0 -5
  83. package/src/executors/sst-lifecycle/secret-preflight.d.ts +2 -0
  84. package/src/executors/sst-lifecycle/secret-preflight.js +13 -7
  85. package/src/executors/sst-lifecycle/secret-preflight.js.map +1 -1
  86. package/src/executors/unlock/unlock.js +2 -2
  87. package/src/executors/unlock/unlock.js.map +1 -1
  88. package/src/foundation/provision-logical-database.js +2 -0
  89. package/src/foundation/provision-logical-database.js.map +1 -1
  90. package/src/foundation/router-waf-rate-rehearsal.d.ts +97 -0
  91. package/src/foundation/router-waf-rate-rehearsal.js +210 -0
  92. package/src/foundation/router-waf-rate-rehearsal.js.map +1 -0
  93. package/src/foundation/router-waf.d.ts +59 -9
  94. package/src/foundation/router-waf.js +427 -32
  95. package/src/foundation/router-waf.js.map +1 -1
  96. package/src/foundation/stages.d.ts +1 -0
  97. package/src/foundation/stages.js +11 -0
  98. package/src/foundation/stages.js.map +1 -1
  99. package/src/generators/formatting.d.ts +8 -0
  100. package/src/generators/formatting.js +118 -0
  101. package/src/generators/formatting.js.map +1 -0
  102. package/src/generators/function/function.js +37 -17
  103. package/src/generators/function/function.js.map +1 -1
  104. package/src/generators/post-generation-install.js +2 -2
  105. package/src/generators/post-generation-install.js.map +1 -1
  106. package/src/generators/preset/generator.js +28 -8
  107. package/src/generators/preset/generator.js.map +1 -1
  108. package/src/generators/preset/schema.d.ts +3 -0
  109. package/src/generators/preset/schema.json +5 -5
  110. package/src/generators/preset/workspace-files-developer-agent.js +15 -7
  111. package/src/generators/preset/workspace-files-developer-agent.js.map +1 -1
  112. package/src/generators/preset/workspace-files-ecr-inspector.d.ts +18 -0
  113. package/src/generators/preset/workspace-files-ecr-inspector.js +298 -0
  114. package/src/generators/preset/workspace-files-ecr-inspector.js.map +1 -0
  115. package/src/generators/preset/workspace-files-performance-cost.d.ts +2 -2
  116. package/src/generators/preset/workspace-files-performance-cost.js +8 -8
  117. package/src/generators/preset/workspace-files-performance-cost.js.map +1 -1
  118. package/src/generators/preset/workspace-files-performance-load.d.ts +1 -1
  119. package/src/generators/preset/workspace-files-performance-load.js +29 -24
  120. package/src/generators/preset/workspace-files-performance-load.js.map +1 -1
  121. package/src/generators/preset/workspace-files-stage-authority.d.ts +6 -0
  122. package/src/generators/preset/workspace-files-stage-authority.js +479 -0
  123. package/src/generators/preset/workspace-files-stage-authority.js.map +1 -0
  124. package/src/generators/preset/workspace-files-thin-deploy.d.ts +40 -0
  125. package/src/generators/preset/workspace-files-thin-deploy.js +1500 -0
  126. package/src/generators/preset/workspace-files-thin-deploy.js.map +1 -0
  127. package/src/generators/preset/workspace-files-thin-docs.d.ts +5 -0
  128. package/src/generators/preset/workspace-files-thin-docs.js +240 -0
  129. package/src/generators/preset/workspace-files-thin-docs.js.map +1 -0
  130. package/src/generators/preset/workspace-files-thin-release.d.ts +14 -0
  131. package/src/generators/preset/workspace-files-thin-release.js +26 -0
  132. package/src/generators/preset/workspace-files-thin-release.js.map +1 -0
  133. package/src/generators/preset/workspace-files.d.ts +2 -1
  134. package/src/generators/preset/workspace-files.js +448 -680
  135. package/src/generators/preset/workspace-files.js.map +1 -1
  136. package/src/generators/repository-policy/repository-policy.js +149 -19
  137. package/src/generators/repository-policy/repository-policy.js.map +1 -1
  138. package/src/generators/repository-policy/schema.d.ts +2 -0
  139. package/src/generators/repository-policy/schema.json +11 -1
  140. package/src/generators/repository-policy/tree-policy.d.ts +3 -0
  141. package/src/generators/repository-policy/tree-policy.js +25 -0
  142. package/src/generators/repository-policy/tree-policy.js.map +1 -0
  143. package/src/generators/slice/built-in-plan-api-files.js +1 -0
  144. package/src/generators/slice/built-in-plan-api-files.js.map +1 -1
  145. package/src/generators/slice/built-in-plan-async-work-files.js +41 -0
  146. package/src/generators/slice/built-in-plan-async-work-files.js.map +1 -1
  147. package/src/generators/slice/built-in-plan-authorization-infrastructure-files.js +6 -0
  148. package/src/generators/slice/built-in-plan-authorization-infrastructure-files.js.map +1 -1
  149. package/src/generators/slice/built-in-plan-data-export-infrastructure-files.js +5 -31
  150. package/src/generators/slice/built-in-plan-data-export-infrastructure-files.js.map +1 -1
  151. package/src/generators/slice/built-in-plan-data-files.d.ts +1 -1
  152. package/src/generators/slice/built-in-plan-data-files.js +89 -30
  153. package/src/generators/slice/built-in-plan-data-files.js.map +1 -1
  154. package/src/generators/slice/built-in-plan-data-lifecycle-runtime-files.js +19 -0
  155. package/src/generators/slice/built-in-plan-data-lifecycle-runtime-files.js.map +1 -1
  156. package/src/generators/slice/built-in-plan-data-retention-launcher-files.js +21 -3
  157. package/src/generators/slice/built-in-plan-data-retention-launcher-files.js.map +1 -1
  158. package/src/generators/slice/built-in-plan-database-retirement-rehearsal-files.js +20 -1
  159. package/src/generators/slice/built-in-plan-database-retirement-rehearsal-files.js.map +1 -1
  160. package/src/generators/slice/built-in-plan-foundation-files.js +3 -5
  161. package/src/generators/slice/built-in-plan-foundation-files.js.map +1 -1
  162. package/src/generators/slice/built-in-plan-frontend-files.js +5 -1
  163. package/src/generators/slice/built-in-plan-frontend-files.js.map +1 -1
  164. package/src/generators/slice/built-in-plan-infrastructure-files.d.ts +1 -1
  165. package/src/generators/slice/built-in-plan-infrastructure-files.js +199 -188
  166. package/src/generators/slice/built-in-plan-infrastructure-files.js.map +1 -1
  167. package/src/generators/slice/built-in-plan-metadata-files.js +13 -0
  168. package/src/generators/slice/built-in-plan-metadata-files.js.map +1 -1
  169. package/src/generators/slice/built-in-plan-native-runtime-authority-files.d.ts +2 -0
  170. package/src/generators/slice/built-in-plan-native-runtime-authority-files.js +307 -0
  171. package/src/generators/slice/built-in-plan-native-runtime-authority-files.js.map +1 -0
  172. package/src/generators/slice/built-in-plan-operations-files.js +65 -51
  173. package/src/generators/slice/built-in-plan-operations-files.js.map +1 -1
  174. package/src/generators/slice/built-in-plan-performance-files.js +97 -19
  175. package/src/generators/slice/built-in-plan-performance-files.js.map +1 -1
  176. package/src/generators/slice/built-in-plan-project-files.js +9 -68
  177. package/src/generators/slice/built-in-plan-project-files.js.map +1 -1
  178. package/src/generators/slice/built-in-plan-secret-runtime-files.d.ts +1 -1
  179. package/src/generators/slice/built-in-plan-secret-runtime-files.js +87 -76
  180. package/src/generators/slice/built-in-plan-secret-runtime-files.js.map +1 -1
  181. package/src/generators/slice/built-in-plan-testing-files.js +94 -47
  182. package/src/generators/slice/built-in-plan-testing-files.js.map +1 -1
  183. package/src/generators/slice/built-in-plan-thin-release-files.d.ts +11 -0
  184. package/src/generators/slice/built-in-plan-thin-release-files.js +129 -0
  185. package/src/generators/slice/built-in-plan-thin-release-files.js.map +1 -0
  186. package/src/generators/slice/built-in-plan-verification-files.js +6 -2
  187. package/src/generators/slice/built-in-plan-verification-files.js.map +1 -1
  188. package/src/generators/slice/built-in-plan-web-files.js +4 -2
  189. package/src/generators/slice/built-in-plan-web-files.js.map +1 -1
  190. package/src/generators/slice/built-in-plan-workload-role-files.js +26 -4
  191. package/src/generators/slice/built-in-plan-workload-role-files.js.map +1 -1
  192. package/src/generators/slice/built-in-plan.d.ts +1 -0
  193. package/src/generators/slice/built-in-plan.js +28 -11
  194. package/src/generators/slice/built-in-plan.js.map +1 -1
  195. package/src/generators/slice/slice.js +30 -32
  196. package/src/generators/slice/slice.js.map +1 -1
  197. package/src/generators/upgrade/upgrade.d.ts +1 -1
  198. package/src/generators/upgrade/upgrade.js +200 -48
  199. package/src/generators/upgrade/upgrade.js.map +1 -1
  200. package/src/generators/workload/performance-registration.d.ts +1 -0
  201. package/src/generators/workload/performance-registration.js +9 -11
  202. package/src/generators/workload/performance-registration.js.map +1 -1
  203. package/src/generators/workload/service-performance-files.d.ts +1 -0
  204. package/src/generators/workload/service-performance-files.js +27 -7
  205. package/src/generators/workload/service-performance-files.js.map +1 -1
  206. package/src/generators/workload/workload.d.ts +1 -1
  207. package/src/generators/workload/workload.js +55 -28
  208. package/src/generators/workload/workload.js.map +1 -1
  209. package/src/git-policy/github-bootstrap.d.ts +28 -7
  210. package/src/git-policy/github-bootstrap.js +205 -163
  211. package/src/git-policy/github-bootstrap.js.map +1 -1
  212. package/src/index.d.ts +1 -0
  213. package/src/index.js +1 -0
  214. package/src/index.js.map +1 -1
  215. package/src/local-dev/private-state.d.ts +3 -0
  216. package/src/local-dev/private-state.js +17 -5
  217. package/src/local-dev/private-state.js.map +1 -1
  218. package/src/local-dev/tls.js +5 -1
  219. package/src/local-dev/tls.js.map +1 -1
  220. package/src/performance/cost-collection.d.ts +1 -1
  221. package/src/performance/cost-collection.js +4 -2
  222. package/src/performance/cost-collection.js.map +1 -1
  223. package/src/performance/cost-controls.d.ts +3 -1
  224. package/src/performance/cost-controls.js +9 -4
  225. package/src/performance/cost-controls.js.map +1 -1
  226. package/src/performance/evidence.d.ts +1 -1
  227. package/src/performance/evidence.js +5 -3
  228. package/src/performance/evidence.js.map +1 -1
  229. package/src/performance/load-safety.js +5 -3
  230. package/src/performance/load-safety.js.map +1 -1
  231. package/src/performance/model.d.ts +2 -2
  232. package/src/performance/model.js +4 -3
  233. package/src/performance/model.js.map +1 -1
  234. package/src/release/index.d.ts +0 -2
  235. package/src/release/index.js +0 -2
  236. package/src/release/index.js.map +1 -1
  237. package/src/release/source-authority.d.ts +4 -5
  238. package/src/release/source-authority.js +13 -123
  239. package/src/release/source-authority.js.map +1 -1
  240. package/src/repository-policy/aurora-preflight.d.ts +1 -1
  241. package/src/repository-policy/aurora-preflight.js +4 -1
  242. package/src/repository-policy/aurora-preflight.js.map +1 -1
  243. package/src/repository-policy/policy.d.ts +21 -2
  244. package/src/repository-policy/policy.js +290 -25
  245. package/src/repository-policy/policy.js.map +1 -1
  246. package/src/schemas/performance-policy-v1.json +3 -1
  247. package/src/schemas/repository-policy-v1.json +46 -2
  248. package/src/secrets/adapters.d.ts +7 -2
  249. package/src/secrets/adapters.js +34 -3
  250. package/src/secrets/adapters.js.map +1 -1
  251. package/src/secrets/aws-control-plane.d.ts +10 -1
  252. package/src/secrets/aws-control-plane.js +67 -0
  253. package/src/secrets/aws-control-plane.js.map +1 -1
  254. package/src/secrets/generated-aws-control-plane.d.ts +23 -0
  255. package/src/secrets/generated-aws-control-plane.js +259 -0
  256. package/src/secrets/generated-aws-control-plane.js.map +1 -0
  257. package/src/secrets/metadata.js +38 -10
  258. package/src/secrets/metadata.js.map +1 -1
  259. package/src/secrets/model.d.ts +8 -1
  260. package/src/secrets/model.js +24 -3
  261. package/src/secrets/model.js.map +1 -1
  262. package/src/secrets/operator.d.ts +89 -3
  263. package/src/secrets/operator.js +422 -9
  264. package/src/secrets/operator.js.map +1 -1
  265. package/src/secrets/registry.d.ts +2 -1
  266. package/src/secrets/registry.js +18 -1
  267. package/src/secrets/registry.js.map +1 -1
  268. package/src/secrets/workload-access.js +10 -2
  269. package/src/secrets/workload-access.js.map +1 -1
  270. package/src/supply-chain/action-pins.js +61 -7
  271. package/src/supply-chain/action-pins.js.map +1 -1
  272. package/src/supply-chain/build-output-bounds.d.ts +2 -0
  273. package/src/supply-chain/build-output-bounds.js +12 -0
  274. package/src/supply-chain/build-output-bounds.js.map +1 -0
  275. package/src/supply-chain/build-output.js +2 -4
  276. package/src/supply-chain/build-output.js.map +1 -1
  277. package/src/supply-chain/ecr-scanning.d.ts +5 -3
  278. package/src/supply-chain/ecr-scanning.js +11 -7
  279. package/src/supply-chain/ecr-scanning.js.map +1 -1
  280. package/src/supply-chain/ecs-deployed-image.d.ts +5 -3
  281. package/src/supply-chain/ecs-deployed-image.js +6 -4
  282. package/src/supply-chain/ecs-deployed-image.js.map +1 -1
  283. package/src/supply-chain/generated-container-release-command.js +849 -44
  284. package/src/supply-chain/generated-container-release-command.js.map +1 -1
  285. package/src/supply-chain/generated-ecr-collector-command.d.ts +0 -1
  286. package/src/supply-chain/generated-ecr-collector-command.js +188 -91
  287. package/src/supply-chain/generated-ecr-collector-command.js.map +1 -1
  288. package/src/supply-chain/generated-files.js +4 -3
  289. package/src/supply-chain/generated-files.js.map +1 -1
  290. package/src/supply-chain/index.d.ts +1 -1
  291. package/src/supply-chain/index.js +2 -1
  292. package/src/supply-chain/index.js.map +1 -1
  293. package/src/workload-roles/index.d.ts +10 -17
  294. package/src/workload-roles/index.js +5 -18
  295. package/src/workload-roles/index.js.map +1 -1
  296. package/src/workspace-deployment/identity.d.ts +3 -0
  297. package/src/workspace-deployment/identity.js +22 -0
  298. package/src/workspace-deployment/identity.js.map +1 -0
  299. package/src/workspace-deployment/index.d.ts +3 -0
  300. package/src/workspace-deployment/index.js +7 -0
  301. package/src/workspace-deployment/index.js.map +1 -0
  302. package/src/workspace-deployment/migration-evidence.d.ts +29 -0
  303. package/src/workspace-deployment/migration-evidence.js +83 -0
  304. package/src/workspace-deployment/migration-evidence.js.map +1 -0
  305. package/src/workspace-deployment/migration.d.ts +27 -0
  306. package/src/workspace-deployment/migration.js +109 -0
  307. package/src/workspace-deployment/migration.js.map +1 -0
  308. package/src/workspace-deployment/ownership.d.ts +81 -0
  309. package/src/workspace-deployment/ownership.js +381 -0
  310. package/src/workspace-deployment/ownership.js.map +1 -0
@@ -3,7 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.renderProductInfrastructureFiles = renderProductInfrastructureFiles;
4
4
  const built_in_plan_shared_js_1 = require("./built-in-plan-shared.js");
5
5
  /** @internal */
6
- function renderProductInfrastructureFiles(name, pascalName, workspace) {
6
+ function renderProductInfrastructureFiles(name, pascalName, workspace, protectedRuntimeStages = ['staging', 'production']) {
7
7
  const identifierPrefix = (0, built_in_plan_shared_js_1.lowerCamelIdentifier)(pascalName);
8
8
  const recordExportWorkflowName = (0, built_in_plan_shared_js_1.stableGeneratedName)(40, name);
9
9
  return {
@@ -434,22 +434,79 @@ export function removeFinderMetadataFromBuiltFunction(rootPath: string): number
434
434
  }
435
435
  return removedFinderMetadata;
436
436
  }
437
+ `,
438
+ 'infra/deployment-receipt.ts': `export interface SuccessfulDeploymentReceiptExpectation {
439
+ account: string;
440
+ project: string;
441
+ region: string;
442
+ sourceCommit: string;
443
+ stage: 'development' | 'staging' | 'production';
444
+ }
445
+
446
+ export function validateSuccessfulDeploymentReceipt(
447
+ value: unknown,
448
+ expected: SuccessfulDeploymentReceiptExpectation,
449
+ ) {
450
+ const receipt = value as {
451
+ account?: unknown;
452
+ authority?: unknown;
453
+ children?: Array<{
454
+ outcome?: unknown;
455
+ project?: unknown;
456
+ target?: unknown;
457
+ }>;
458
+ kind?: unknown;
459
+ migrations?: Record<string, unknown>;
460
+ outcome?: unknown;
461
+ profile?: unknown;
462
+ region?: unknown;
463
+ schemaVersion?: unknown;
464
+ smoke?: Record<string, unknown>;
465
+ source?: { clean?: unknown; commit?: unknown };
466
+ stage?: unknown;
467
+ };
468
+ const deploymentChildren = Array.isArray(receipt?.children)
469
+ ? receipt.children.filter(
470
+ ({ outcome, project, target }) =>
471
+ outcome === 'succeeded' &&
472
+ project === expected.project &&
473
+ target === 'deploy',
474
+ )
475
+ : [];
476
+ if (
477
+ receipt?.kind !== 'ebk-deployment-receipt' ||
478
+ receipt.schemaVersion !== 1 ||
479
+ receipt.outcome !== 'succeeded' ||
480
+ !['local', 'github'].includes(String(receipt.authority)) ||
481
+ !['starter', 'production-isolated', 'fully-isolated'].includes(
482
+ String(receipt.profile),
483
+ ) ||
484
+ receipt.account !== expected.account ||
485
+ receipt.region !== expected.region ||
486
+ receipt.stage !== expected.stage ||
487
+ receipt.source?.clean !== true ||
488
+ receipt.source.commit !== expected.sourceCommit ||
489
+ !Array.isArray(receipt.children) ||
490
+ receipt.children.some(({ outcome }) => outcome !== 'succeeded') ||
491
+ deploymentChildren.length !== 1 ||
492
+ receipt.migrations?.[expected.project] !== 'completed-by-deploy-target' ||
493
+ receipt.smoke?.[expected.project] !== 'passed'
494
+ ) {
495
+ throw new Error(
496
+ 'Protected performance load requires one successful exact-source native deployment receipt.',
497
+ );
498
+ }
499
+ return Object.freeze(receipt);
500
+ }
437
501
  `,
438
502
  'infra/product.ts': `import {
439
503
  createManagedLogGroupContract,
440
504
  createRouterOriginProofInjection,
441
505
  provisionDatabaseBindings,
442
506
  } from '@empire-builder-kit/nx/foundation';
443
- import { validateReleaseManifest } from '@empire-builder-kit/nx/release';
444
507
  import * as random from '@pulumi/random';
445
508
  import { createHash } from 'node:crypto';
446
- import {
447
- lstatSync,
448
- readFileSync,
449
- readdirSync,
450
- realpathSync,
451
- } from 'node:fs';
452
- import { fileURLToPath } from 'node:url';
509
+ import { readFileSync } from 'node:fs';
453
510
  import {
454
511
  ${identifierPrefix}CleanupRecordExport,
455
512
  ${identifierPrefix}DatabaseHealth,
@@ -488,11 +545,12 @@ import {
488
545
  } from './foundation.js';
489
546
  import { createVpcRouteFunctionMaterializer } from './route-function-materialization.js';
490
547
  import { removeFinderMetadataFromBuiltFunction } from './next-build-authority.js';
548
+ import {
549
+ createStandardSliceNativeRuntimeAuthority,
550
+ } from './native-runtime-authority/index.js';
491
551
  import {
492
552
  standardSliceDatabaseTaskFamily,
493
- standardSliceResourceNames,
494
- } from './workload-roles/effective-intent.js';
495
- import type { StandardSliceWorkloadRolePreflight } from './workload-roles/preflight.js';
553
+ } from './native-runtime-authority/effective-intent.js';
496
554
  import { createStandardSliceSecretLinks } from './personal-secrets.js';
497
555
  import { create${pascalName}PerformanceCostControls } from './performance-cost-controls.js';
498
556
  import {
@@ -506,6 +564,7 @@ import { resolveStandardContainerImage } from './container-images.js';
506
564
  import {
507
565
  defineEventConsumerAlarms,
508
566
  } from '@empire-builder-kit/runtime/observability';
567
+ import { validateSuccessfulDeploymentReceipt } from './deployment-receipt.js';
509
568
  // <ebk:composition-imports:start>
510
569
  // <ebk:composition-imports:end>
511
570
 
@@ -520,11 +579,12 @@ function protectedPerformanceDeploymentAuthority(input: {
520
579
  );
521
580
  }
522
581
  if (input.enabled === 'false') return undefined;
523
- if (input.stage !== 'staging' && input.stage !== 'production') {
582
+ if (!${JSON.stringify(protectedRuntimeStages)}.includes(input.stage)) {
524
583
  throw new Error(
525
- 'Protected performance load can be deployed only to staging or production.',
584
+ 'Protected performance load requires one active rehearsal or production stage.',
526
585
  );
527
586
  }
587
+ const stage = input.stage as 'development' | 'production' | 'staging';
528
588
  const accountId = process.env.AWS_EXPECTED_ACCOUNT_ID?.trim() ?? '';
529
589
  const region = process.env.AWS_REGION?.trim() ?? '';
530
590
  if (
@@ -560,60 +620,38 @@ function protectedPerformanceDeploymentAuthority(input: {
560
620
  'Protected performance load requires the exact deployed release candidate.',
561
621
  );
562
622
  }
563
- const releaseManifestDirectory = new URL(
564
- '../.ebk/evidence/release-manifests/',
565
- import.meta.url,
566
- );
567
- const releaseManifestNames = readdirSync(releaseManifestDirectory).filter(
568
- (entry) => /^release-[a-f0-9]{24}[.]json$/.test(entry),
569
- );
570
- if (releaseManifestNames.length !== 1) {
571
- throw new Error(
572
- 'Protected performance load requires one exact deployed release manifest.',
573
- );
574
- }
575
- const releaseManifestUrl = new URL(
576
- releaseManifestNames[0]!,
577
- releaseManifestDirectory,
623
+ const deploymentReceiptBytes = readFileSync(
624
+ new URL(
625
+ '../../../.ebk/evidence/deployment/latest.json',
626
+ import.meta.url,
627
+ ),
578
628
  );
579
- const releaseManifestPath = fileURLToPath(releaseManifestUrl);
580
- const releaseManifestMetadata = lstatSync(releaseManifestPath);
581
- if (
582
- !releaseManifestMetadata.isFile() ||
583
- releaseManifestMetadata.isSymbolicLink() ||
584
- releaseManifestMetadata.size <= 0 ||
585
- releaseManifestMetadata.size > 10 * 1024 * 1024 ||
586
- realpathSync(releaseManifestPath) !== releaseManifestPath
587
- ) {
588
- throw new Error(
589
- 'Protected performance load release manifest is not one bounded canonical file.',
590
- );
591
- }
592
- const releaseManifest = validateReleaseManifest(
593
- JSON.parse(readFileSync(releaseManifestPath, 'utf8')),
629
+ validateSuccessfulDeploymentReceipt(
630
+ JSON.parse(deploymentReceiptBytes.toString('utf8')),
594
631
  {
595
- requireSupplyChain: true,
632
+ account: accountId,
633
+ project: '${name}',
634
+ region,
596
635
  sourceCommit: input.releaseSourceCommit,
636
+ stage,
597
637
  },
598
638
  );
599
- if (releaseManifestNames[0] !== releaseManifest.releaseId + '.json') {
600
- throw new Error(
601
- 'Protected performance load release manifest path differs from its identity.',
602
- );
603
- }
639
+ const deploymentReceiptDigest = createHash('sha256')
640
+ .update(deploymentReceiptBytes)
641
+ .digest('hex');
604
642
  return Object.freeze({
605
643
  candidateDigest: createHash('sha256')
606
644
  .update(candidateBytes)
607
645
  .digest('hex'),
608
- releaseId: releaseManifest.releaseId,
609
- releaseMaterialDigest: releaseManifest.materialDigest,
646
+ releaseId: 'release-' + deploymentReceiptDigest.slice(0, 24),
647
+ releaseMaterialDigest: deploymentReceiptDigest,
610
648
  target: Object.freeze({
611
649
  accountFingerprint:
612
650
  'sha256:' +
613
651
  createHash('sha256').update(accountId, 'utf8').digest('hex'),
614
652
  region,
615
653
  slice: '${name}',
616
- stage: input.stage as 'production' | 'staging',
654
+ stage,
617
655
  }),
618
656
  });
619
657
  }
@@ -724,19 +762,11 @@ function lambdaLogging(logGroupName: any, functionName?: any) {
724
762
  };
725
763
  }
726
764
 
727
- export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
728
- if (!$dev && !workloadRoles) {
729
- throw new Error(
730
- 'Protected workload-role preflight must complete before infrastructure construction.',
731
- );
732
- }
733
- const workloadRoleBindings = workloadRoles?.bindings;
765
+ export function product() {
734
766
  const asyncAdaptersConfigured = assertAsyncAdapterDeploymentReady();
735
- const secretLinks = createStandardSliceSecretLinks({
736
- protectedAccess: workloadRoles?.secretAccess,
737
- });
767
+ const secretLinks = createStandardSliceSecretLinks();
738
768
  const performanceHmacLogicalName =
739
- '${pascalName}PerformanceLoadHmacKeys';
769
+ 'GeneratedPerformanceLoadHmacKeys';
740
770
  const secretLinksFor = (
741
771
  resource: string,
742
772
  excludeLogicalNames: readonly string[] = [],
@@ -749,21 +779,6 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
749
779
  ];
750
780
  // Workload generators compose multi-role secret bindings through this seam.
751
781
  void secretLinksForWorkloads;
752
- const workloadRoleResourceNames = workloadRoles
753
- ? standardSliceResourceNames(workloadRoles.intentContext)
754
- : undefined;
755
- if (workloadRoleResourceNames) {
756
- $transform(aws.dynamodb.Table, (args: any, _opts: any, logicalName: string) => {
757
- if (logicalName === '${pascalName}WebRevalidationTable') {
758
- args.name = workloadRoleResourceNames.webRevalidationTable;
759
- }
760
- });
761
- $transform(aws.sqs.Queue, (args: any, _opts: any, logicalName: string) => {
762
- if (logicalName === '${pascalName}WebRevalidationEventsQueue') {
763
- args.name = workloadRoleResourceNames.webRevalidationQueue;
764
- }
765
- });
766
- }
767
782
  const devPortInput = $dev ? (process.env.EBK_DEV_PORT ?? '3000') : '3000';
768
783
  if (!/^\\d+$/.test(devPortInput)) {
769
784
  throw new Error('EBK_DEV_PORT must be an integer from 1024 through 65535.');
@@ -772,8 +787,9 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
772
787
  if (!Number.isSafeInteger(devPort) || devPort < 1024 || devPort > 65535) {
773
788
  throw new Error('EBK_DEV_PORT must be an integer from 1024 through 65535.');
774
789
  }
775
- const protectedStage =
776
- $app.stage === 'staging' || $app.stage === 'production';
790
+ const protectedStage = ${JSON.stringify(protectedRuntimeStages)}.includes(
791
+ $app.stage,
792
+ );
777
793
  const sourceCommit =
778
794
  process.env.EBK_SOURCE_COMMIT ?? (protectedStage ? '' : 'unresolved');
779
795
  const releaseSourceCommit =
@@ -850,6 +866,24 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
850
866
  })
851
867
  : undefined;
852
868
  const foundation = getFoundationInfrastructure();
869
+ const nativeAuthority = createStandardSliceNativeRuntimeAuthority({
870
+ clusterId: foundation.discovery.clusterId,
871
+ clusterResourceId: foundation.database.clusterResourceId,
872
+ eventBusArn: foundation.discovery.eventBusArn,
873
+ identityUserPoolArn: foundation.discovery.identityUserPoolArn,
874
+ masterSecretArn: foundation.database.masterSecretArn,
875
+ });
876
+ const runtimeResourceNames = nativeAuthority.resourceNames;
877
+ $transform(aws.dynamodb.Table, (args: any, _opts: any, logicalName: string) => {
878
+ if (logicalName === '${pascalName}WebRevalidationTable') {
879
+ args.name = runtimeResourceNames.webRevalidationTable;
880
+ }
881
+ });
882
+ $transform(aws.sqs.Queue, (args: any, _opts: any, logicalName: string) => {
883
+ if (logicalName === '${pascalName}WebRevalidationEventsQueue') {
884
+ args.name = runtimeResourceNames.webRevalidationQueue;
885
+ }
886
+ });
853
887
  const performanceCostControls = create${pascalName}PerformanceCostControls({
854
888
  accountCostPolicyDigest: foundation.discovery.accountCostPolicyDigest,
855
889
  accountMonthlyMaximumUsd:
@@ -882,16 +916,9 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
882
916
  const machineClientProvisioner = new sst.aws.Function(
883
917
  '${pascalName}MachineClientProvisioner',
884
918
  {
885
- ...(workloadRoleBindings?.authorization.provisioner ?? {}),
886
- ...(workloadRoles
887
- ? {}
888
- : {
889
- permissions:
890
- standardSliceMachineClientProvisionerPermissions({
891
- userPoolArn:
892
- foundation.discovery.identityUserPoolArn,
893
- }),
894
- }),
919
+ permissions: standardSliceMachineClientProvisionerPermissions({
920
+ userPoolArn: foundation.discovery.identityUserPoolArn,
921
+ }),
895
922
  environment: {
896
923
  EBK_SLICE: '${name}',
897
924
  EBK_STAGE: $app.stage,
@@ -915,9 +942,8 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
915
942
  userPoolId: foundation.userPool.id,
916
943
  });
917
944
  const dataExportStore = createStandardDataExportStore({
918
- bucketName: workloadRoleResourceNames?.dataExportBucket,
919
- keyAliasName: workloadRoleResourceNames?.dataExportKeyAlias,
920
- workloadRoleArn: workloadRoleBindings?.api.dataRights.role,
945
+ bucketName: runtimeResourceNames.dataExportBucket,
946
+ keyAliasName: runtimeResourceNames.dataExportKeyAlias,
921
947
  });
922
948
 
923
949
  const apiHealthLogs = managedLogGroup(
@@ -1097,7 +1123,7 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
1097
1123
  }
1098
1124
  : undefined;
1099
1125
  api.route(${identifierPrefix}Health.method + ' ' + ${identifierPrefix}Health.path, {
1100
- ...(workloadRoleBindings?.api.health ?? {}),
1126
+ permissions: nativeAuthority.permissions('api-health'),
1101
1127
  environment: {
1102
1128
  EBK_SOURCE_COMMIT: releaseSourceCommit,
1103
1129
  EBK_STAGE: $app.stage,
@@ -1111,7 +1137,7 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
1111
1137
  ' ' +
1112
1138
  ${identifierPrefix}MachineAuthorizationProof.path,
1113
1139
  {
1114
- ...(workloadRoleBindings?.api.machineAuthorizationProof ?? {}),
1140
+ permissions: nativeAuthority.permissions('api-machine-authorization-proof'),
1115
1141
  environment: {
1116
1142
  AUTH_CLIENT_ID: authClient.id,
1117
1143
  AUTH_MACHINE_ACCEPTED_CLIENT_IDS:
@@ -1143,7 +1169,7 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
1143
1169
  },
1144
1170
  ]) {
1145
1171
  routeInVpc(route.operation.method + ' ' + route.operation.path, {
1146
- ...(workloadRoleBindings?.api.delegations ?? {}),
1172
+ permissions: nativeAuthority.permissions('api-delegations'),
1147
1173
  environment: {
1148
1174
  AUTH_CLIENT_ID: authClient.id,
1149
1175
  AUTH_MACHINE_ACCEPTED_CLIENT_IDS:
@@ -1196,10 +1222,7 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
1196
1222
  },
1197
1223
  ]) {
1198
1224
  routeInVpc(route.operation.method + ' ' + route.operation.path, {
1199
- ...(workloadRoleBindings?.api.dataRights ?? {}),
1200
- ...(workloadRoles
1201
- ? {}
1202
- : { permissions: dataExportStore.dataRightsPermissions }),
1225
+ permissions: nativeAuthority.permissions('api-data-rights'),
1203
1226
  environment: {
1204
1227
  AUTH_CLIENT_ID: authClient.id,
1205
1228
  AUTH_MACHINE_ACCEPTED_CLIENT_IDS:
@@ -1231,7 +1254,7 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
1231
1254
  },
1232
1255
  ]) {
1233
1256
  routeInVpc(route.operation.method + ' ' + route.operation.path, {
1234
- ...(workloadRoleBindings?.api.databaseRecords ?? {}),
1257
+ permissions: nativeAuthority.permissions('api-database-records'),
1235
1258
  environment: {
1236
1259
  AUTH_CLIENT_ID: authClient.id,
1237
1260
  AUTH_MACHINE_ACCEPTED_CLIENT_IDS:
@@ -1250,7 +1273,7 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
1250
1273
  ' ' +
1251
1274
  ${identifierPrefix}ProtectedExample.path,
1252
1275
  {
1253
- ...(workloadRoleBindings?.api.protected ?? {}),
1276
+ permissions: nativeAuthority.permissions('api-protected'),
1254
1277
  environment: {
1255
1278
  AUTH_CLIENT_ID: authClient.id,
1256
1279
  AUTH_MACHINE_ACCEPTED_CLIENT_IDS:
@@ -1269,7 +1292,7 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
1269
1292
  ' ' +
1270
1293
  ${identifierPrefix}DatabaseHealth.path,
1271
1294
  {
1272
- ...(workloadRoleBindings?.api.databaseHealth ?? {}),
1295
+ permissions: nativeAuthority.permissions('api-database-health'),
1273
1296
  environment: {
1274
1297
  AUTH_CLIENT_ID: authClient.id,
1275
1298
  AUTH_MACHINE_ACCEPTED_CLIENT_IDS:
@@ -1298,7 +1321,7 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
1298
1321
  },
1299
1322
  ]) {
1300
1323
  routeInVpc(route.operation.method + ' ' + route.operation.path, {
1301
- ...(workloadRoleBindings?.api.databaseRecords ?? {}),
1324
+ permissions: nativeAuthority.permissions('api-database-records'),
1302
1325
  environment: {
1303
1326
  AUTH_CLIENT_ID: authClient.id,
1304
1327
  AUTH_MACHINE_ACCEPTED_CLIENT_IDS:
@@ -1328,7 +1351,7 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
1328
1351
  },
1329
1352
  ]) {
1330
1353
  routeInVpc(route.operation.method + ' ' + route.operation.path, {
1331
- ...(workloadRoleBindings?.api.databaseRecords ?? {}),
1354
+ permissions: nativeAuthority.permissions('api-database-records'),
1332
1355
  environment: {
1333
1356
  AUTH_CLIENT_ID: authClient.id,
1334
1357
  AUTH_MACHINE_ACCEPTED_CLIENT_IDS:
@@ -1347,7 +1370,7 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
1347
1370
  ' ' +
1348
1371
  ${identifierPrefix}PublishCreated.path,
1349
1372
  {
1350
- ...(workloadRoleBindings?.api.publishCreated ?? {}),
1373
+ permissions: nativeAuthority.permissions('api-publish-created'),
1351
1374
  environment: {
1352
1375
  AUTH_CLIENT_ID: authClient.id,
1353
1376
  AUTH_MACHINE_ACCEPTED_CLIENT_IDS:
@@ -1369,10 +1392,7 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
1369
1392
  const machineAuthorizationProof = new sst.aws.Function(
1370
1393
  '${pascalName}MachineAuthorizationProof',
1371
1394
  {
1372
- ...(workloadRoleBindings?.authorization.proof ?? {}),
1373
- ...(workloadRoles
1374
- ? {}
1375
- : { permissions: machineAuthorization.proof.permissions }),
1395
+ permissions: machineAuthorization.proof.permissions,
1376
1396
  environment: {
1377
1397
  ...machineAuthorization.proof.environment,
1378
1398
  AUTH_MACHINE_PROBE_URL:
@@ -1387,10 +1407,7 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
1387
1407
  const dataExportCleanup = new sst.aws.Function(
1388
1408
  '${pascalName}DataExportCleanup',
1389
1409
  {
1390
- ...(workloadRoleBindings?.dataExport.cleanup ?? {}),
1391
- ...(workloadRoles
1392
- ? {}
1393
- : { permissions: dataExportStore.cleanupPermissions }),
1410
+ permissions: dataExportStore.cleanupPermissions,
1394
1411
  environment: {
1395
1412
  DATA_EXPORT_BUCKET_NAME: dataExportStore.bucket.bucket,
1396
1413
  DATA_EXPORT_KMS_KEY_ARN: dataExportStore.encryptionKey.arn,
@@ -1410,9 +1427,7 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
1410
1427
  const dataExportCleanupRule = new aws.cloudwatch.EventRule(
1411
1428
  '${pascalName}DataExportCleanupSchedule',
1412
1429
  {
1413
- ...(workloadRoleResourceNames
1414
- ? { name: workloadRoleResourceNames.dataExportCleanupRule }
1415
- : {}),
1430
+ name: runtimeResourceNames.dataExportCleanupRule,
1416
1431
  description:
1417
1432
  'Hourly authoritative cleanup of expired confidential export versions.',
1418
1433
  scheduleExpression: 'rate(1 hour)',
@@ -1461,9 +1476,7 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
1461
1476
  const eventDlq = new sst.aws.Queue('${pascalName}EventDlq', {
1462
1477
  transform: {
1463
1478
  queue: {
1464
- ...(workloadRoleResourceNames
1465
- ? { name: workloadRoleResourceNames.eventDlq }
1466
- : {}),
1479
+ name: runtimeResourceNames.eventDlq,
1467
1480
  messageRetentionSeconds: 14 * 24 * 60 * 60,
1468
1481
  },
1469
1482
  },
@@ -1472,9 +1485,7 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
1472
1485
  dlq: { queue: eventDlq.arn, retry: 5 },
1473
1486
  transform: {
1474
1487
  queue: {
1475
- ...(workloadRoleResourceNames
1476
- ? { name: workloadRoleResourceNames.eventQueue }
1477
- : {}),
1488
+ name: runtimeResourceNames.eventQueue,
1478
1489
  messageRetentionSeconds: 4 * 24 * 60 * 60,
1479
1490
  visibilityTimeoutSeconds: 120,
1480
1491
  },
@@ -1486,9 +1497,7 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
1486
1497
  attributes: [{ name: 'report_digest', type: 'S' }],
1487
1498
  billingMode: 'PAY_PER_REQUEST',
1488
1499
  hashKey: 'report_digest',
1489
- ...(workloadRoleResourceNames
1490
- ? { name: workloadRoleResourceNames.asyncRecoveryLedger }
1491
- : {}),
1500
+ name: runtimeResourceNames.asyncRecoveryLedger,
1492
1501
  pointInTimeRecovery: { enabled: true },
1493
1502
  tags: {
1494
1503
  'ebk:async-recovery-ledger': 'true',
@@ -1508,14 +1517,12 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
1508
1517
  },
1509
1518
  handler: 'api/event-consumer.handler',
1510
1519
  link: [database, ...secretLinksFor('event-consumer')],
1520
+ permissions: nativeAuthority.permissions('event-consumer'),
1511
1521
  ...lambdaLogging(eventConsumerLogs.logGroup.name),
1512
1522
  timeout: '1 minute',
1513
1523
  vpc: foundation.vpc,
1514
1524
  }, {
1515
1525
  batch: { partialResponses: true },
1516
- transform: {
1517
- function: workloadRoleBindings?.queue.eventConsumer,
1518
- },
1519
1526
  });
1520
1527
  foundation.eventBus.subscribeQueue(
1521
1528
  '${pascalName}CreatedEventRule',
@@ -1573,9 +1580,7 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
1573
1580
  {
1574
1581
  transform: {
1575
1582
  queue: {
1576
- ...(workloadRoleResourceNames
1577
- ? { name: workloadRoleResourceNames.asyncTargetDlq }
1578
- : {}),
1583
+ name: runtimeResourceNames.asyncTargetDlq,
1579
1584
  messageRetentionSeconds: 14 * 24 * 60 * 60,
1580
1585
  tags: {
1581
1586
  'ebk:async-recovery-source': 'async-target-dlq',
@@ -1589,9 +1594,7 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
1589
1594
  const providerDlq = new sst.aws.Queue('${pascalName}ProviderDlq', {
1590
1595
  transform: {
1591
1596
  queue: {
1592
- ...(workloadRoleResourceNames
1593
- ? { name: workloadRoleResourceNames.providerDlq }
1594
- : {}),
1597
+ name: runtimeResourceNames.providerDlq,
1595
1598
  messageRetentionSeconds: 14 * 24 * 60 * 60,
1596
1599
  tags: {
1597
1600
  'ebk:async-recovery-source': 'provider-dlq',
@@ -1605,9 +1608,7 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
1605
1608
  dlq: { queue: providerDlq.arn, retry: 5 },
1606
1609
  transform: {
1607
1610
  queue: {
1608
- ...(workloadRoleResourceNames
1609
- ? { name: workloadRoleResourceNames.providerQueue }
1610
- : {}),
1611
+ name: runtimeResourceNames.providerQueue,
1611
1612
  messageRetentionSeconds: 4 * 24 * 60 * 60,
1612
1613
  tags: {
1613
1614
  'ebk:async-recovery-destination': 'provider-queue',
@@ -1672,6 +1673,9 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
1672
1673
  );
1673
1674
  const runtimeConfiguration = protectedStage && !$dev
1674
1675
  ? (() => {
1676
+ const monitorRole = nativeAuthority.createAppConfigMonitorRole(
1677
+ '${pascalName}ConfigurationMonitorRole',
1678
+ );
1675
1679
  const application = new aws.appconfig.Application(
1676
1680
  '${pascalName}ConfigurationApplication',
1677
1681
  {
@@ -1697,8 +1701,7 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
1697
1701
  reliability.providerDeadline,
1698
1702
  ].map((alarm) => ({
1699
1703
  alarmArn: alarm.arn,
1700
- alarmRoleArn:
1701
- workloadRoleBindings!.configuration.monitor.roleArn,
1704
+ alarmRoleArn: monitorRole.arn,
1702
1705
  })),
1703
1706
  name: $app.stage,
1704
1707
  tags: {
@@ -1850,22 +1853,20 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
1850
1853
  providerQueue,
1851
1854
  ...secretLinksFor('async-provider-worker'),
1852
1855
  ],
1856
+ permissions: nativeAuthority.permissions('async-provider-worker'),
1853
1857
  ...lambdaLogging(asyncProviderWorkerLogs.logGroup.name),
1854
1858
  timeout: '1 minute',
1855
1859
  vpc: foundation.vpc,
1856
1860
  },
1857
1861
  {
1858
1862
  batch: { partialResponses: true },
1859
- transform: {
1860
- function: workloadRoleBindings?.async.providerWorker,
1861
- },
1862
1863
  },
1863
1864
  configurationDeployment
1864
1865
  ? { dependsOn: [configurationDeployment] }
1865
1866
  : {},
1866
1867
  );
1867
1868
  api.route('POST /${name}/webhooks/provider', {
1868
- ...(workloadRoleBindings?.async.webhookIngress ?? {}),
1869
+ permissions: nativeAuthority.permissions('async-webhook-ingress'),
1869
1870
  environment: {
1870
1871
  EBK_ASYNC_LEDGER_TABLE: asyncRecoveryLedger.name,
1871
1872
  EBK_STAGE: $app.stage,
@@ -1884,7 +1885,7 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
1884
1885
  const asyncOutboxRelay = new sst.aws.Function(
1885
1886
  '${pascalName}AsyncOutboxRelay',
1886
1887
  {
1887
- ...(workloadRoleBindings?.async.outboxRelay ?? {}),
1888
+ permissions: nativeAuthority.permissions('async-outbox-relay'),
1888
1889
  environment: {
1889
1890
  EBK_STAGE: $app.stage,
1890
1891
  EBK_WORKLOAD_IDENTITY: '${name}:async-outbox-relay',
@@ -1905,7 +1906,7 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
1905
1906
  const asyncInboxCleanup = new sst.aws.Function(
1906
1907
  '${pascalName}AsyncInboxCleanup',
1907
1908
  {
1908
- ...(workloadRoleBindings?.async.inboxCleanup ?? {}),
1909
+ permissions: nativeAuthority.permissions('async-inbox-cleanup'),
1909
1910
  environment: {
1910
1911
  EBK_STAGE: $app.stage,
1911
1912
  EBK_WORKLOAD_IDENTITY: '${name}:async-inbox-cleanup',
@@ -1924,7 +1925,7 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
1924
1925
  const asyncScheduleTarget = new sst.aws.Function(
1925
1926
  '${pascalName}AsyncScheduleTarget',
1926
1927
  {
1927
- ...(workloadRoleBindings?.async.scheduleTarget ?? {}),
1928
+ permissions: nativeAuthority.permissions('async-schedule-target'),
1928
1929
  environment: {
1929
1930
  EBK_STAGE: $app.stage,
1930
1931
  EBK_WORKLOAD_IDENTITY: '${name}:async-schedule-target',
@@ -1939,7 +1940,7 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
1939
1940
  const asyncWorkflowTask = new sst.aws.Function(
1940
1941
  '${pascalName}AsyncWorkflowTask',
1941
1942
  {
1942
- ...(workloadRoleBindings?.async.workflowTask ?? {}),
1943
+ permissions: nativeAuthority.permissions('async-workflow-task'),
1943
1944
  environment: {
1944
1945
  EBK_ASYNC_LEDGER_TABLE: asyncRecoveryLedger.name,
1945
1946
  EBK_STAGE: $app.stage,
@@ -1950,7 +1951,7 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
1950
1951
  link: secretLinksFor('async-workflow-task'),
1951
1952
  ...lambdaLogging(
1952
1953
  asyncWorkflowTaskLogs.logGroup.name,
1953
- workloadRoleResourceNames?.workflowTaskFunction,
1954
+ runtimeResourceNames.workflowTaskFunction,
1954
1955
  ),
1955
1956
  timeout: '15 minutes',
1956
1957
  },
@@ -2097,6 +2098,10 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
2097
2098
  );
2098
2099
  let recordExportWorkflow: any;
2099
2100
  if (!$dev && asyncAdaptersConfigured) {
2101
+ const recordExportWorkflowRole = nativeAuthority.createStepFunctionsRole(
2102
+ '${pascalName}RecordExportWorkflowRole',
2103
+ 'async-workflow-orchestration',
2104
+ );
2100
2105
  recordExportWorkflow = new aws.sfn.StateMachine(
2101
2106
  '${pascalName}RecordExportWorkflow',
2102
2107
  {
@@ -2240,8 +2245,7 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
2240
2245
  'ebk-${recordExportWorkflowName}-' +
2241
2246
  $app.stage +
2242
2247
  '-record-export-v1',
2243
- roleArn:
2244
- workloadRoleBindings!.async.workflowOrchestration.roleArn,
2248
+ roleArn: recordExportWorkflowRole.arn,
2245
2249
  tags: {
2246
2250
  'ebk:slice': '${name}',
2247
2251
  'ebk:stage': $app.stage,
@@ -2291,17 +2295,15 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
2291
2295
  path: 'web',
2292
2296
  router: { instance: foundation.router, path: '/${name}' },
2293
2297
  transform: {
2294
- assets: workloadRoleResourceNames
2295
- ? {
2296
- transform: {
2297
- bucket: {
2298
- bucket: workloadRoleResourceNames.webAssetsBucket,
2299
- },
2300
- },
2301
- }
2302
- : undefined,
2298
+ assets: {
2299
+ transform: {
2300
+ bucket: {
2301
+ bucket: runtimeResourceNames.webAssetsBucket,
2302
+ },
2303
+ },
2304
+ },
2303
2305
  imageOptimizer: {
2304
- ...(workloadRoleBindings?.next.imageOptimizer ?? {}),
2306
+ permissions: nativeAuthority.permissions('web-image-optimizer'),
2305
2307
  hook: {
2306
2308
  async postbuild(directory: string) {
2307
2309
  removeFinderMetadataFromBuiltFunction(directory);
@@ -2311,17 +2313,17 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
2311
2313
  ...lambdaLogging(nextImageOptimizerLogs.logGroup.name),
2312
2314
  },
2313
2315
  revalidationEventsSubscriber: {
2314
- ...(workloadRoleBindings?.next.revalidationSubscriber ?? {}),
2316
+ permissions: nativeAuthority.permissions('web-revalidation-subscriber'),
2315
2317
  link: secretLinksFor('web-revalidation-subscriber'),
2316
2318
  ...lambdaLogging(nextRevalidationSubscriberLogs.logGroup.name),
2317
2319
  },
2318
2320
  revalidationSeeder: {
2319
- ...(workloadRoleBindings?.next.revalidationSeeder ?? {}),
2321
+ permissions: nativeAuthority.permissions('web-revalidation-seeder'),
2320
2322
  link: secretLinksFor('web-revalidation-seeder'),
2321
2323
  ...lambdaLogging(nextRevalidationSeederLogs.logGroup.name),
2322
2324
  },
2323
2325
  server: {
2324
- ...(workloadRoleBindings?.next.server ?? {}),
2326
+ permissions: nativeAuthority.permissions('web-server'),
2325
2327
  hook: {
2326
2328
  async postbuild(directory: string) {
2327
2329
  removeFinderMetadataFromBuiltFunction(directory);
@@ -2426,18 +2428,23 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
2426
2428
  logicalName: string,
2427
2429
  definition: unknown,
2428
2430
  logGroup: any,
2429
- roleArn: string,
2430
- ) =>
2431
- new aws.sfn.StateMachine(logicalName, {
2431
+ roleResource: string,
2432
+ ) => {
2433
+ const role = nativeAuthority.createStepFunctionsRole(
2434
+ logicalName + 'Role',
2435
+ roleResource,
2436
+ );
2437
+ return new aws.sfn.StateMachine(logicalName, {
2432
2438
  definition: $jsonStringify(definition),
2433
2439
  loggingConfiguration: {
2434
2440
  includeExecutionData: false,
2435
2441
  level: 'ERROR',
2436
2442
  logDestination: $interpolate\`\${logGroup.arn}:*\`,
2437
2443
  },
2438
- roleArn,
2444
+ roleArn: role.arn,
2439
2445
  type: 'STANDARD',
2440
2446
  });
2447
+ };
2441
2448
 
2442
2449
  if (!databaseProvision.readwriteSecretArn) {
2443
2450
  throw new Error(
@@ -2446,7 +2453,7 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
2446
2453
  }
2447
2454
  const retentionTaskLogs = managedLogContract('job-data-retention');
2448
2455
  const retentionTask = new sst.aws.Task('${pascalName}DataRetentionTask', {
2449
- ...workloadRoleBindings!.dataRetention.task,
2456
+ permissions: nativeAuthority.permissions('data-retention-job-task'),
2450
2457
  cluster: foundation.cluster,
2451
2458
  environment: {
2452
2459
  ...dataRetentionContainer.environment,
@@ -2475,7 +2482,7 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
2475
2482
  tags: retentionTaskLogs.tags,
2476
2483
  },
2477
2484
  taskDefinition: {
2478
- family: workloadRoleResourceNames!.dataRetentionTaskFamily,
2485
+ family: runtimeResourceNames.dataRetentionTaskFamily,
2479
2486
  },
2480
2487
  },
2481
2488
  });
@@ -2558,7 +2565,7 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
2558
2565
  },
2559
2566
  },
2560
2567
  retentionWorkflowLogs.logGroup,
2561
- workloadRoleBindings!.dataRetention.orchestration.roleArn,
2568
+ 'data-retention-job-orchestration',
2562
2569
  );
2563
2570
  const retentionFailureAlarm = new aws.cloudwatch.MetricAlarm(
2564
2571
  '${pascalName}DataRetentionFailure',
@@ -2617,7 +2624,9 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
2617
2624
  const retentionMaintenanceTask = new sst.aws.Task(
2618
2625
  '${pascalName}DataRetentionMaintenanceTask',
2619
2626
  {
2620
- ...workloadRoleBindings!.dataRetention.maintenance.task,
2627
+ permissions: nativeAuthority.permissions(
2628
+ 'data-retention-maintenance-job-task',
2629
+ ),
2621
2630
  cluster: foundation.cluster,
2622
2631
  environment: {
2623
2632
  ...dataRetentionContainer.environment,
@@ -2649,9 +2658,7 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
2649
2658
  tags: retentionMaintenanceTaskLogs.tags,
2650
2659
  },
2651
2660
  taskDefinition: {
2652
- family:
2653
- workloadRoleResourceNames!
2654
- .dataRetentionMaintenanceTaskFamily,
2661
+ family: runtimeResourceNames.dataRetentionMaintenanceTaskFamily,
2655
2662
  },
2656
2663
  },
2657
2664
  },
@@ -2683,7 +2690,9 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
2683
2690
  const retentionMaintenanceLauncher = new sst.aws.Function(
2684
2691
  '${pascalName}DataRetentionMaintenanceLauncher',
2685
2692
  {
2686
- ...workloadRoleBindings!.dataRetention.maintenance.launcher,
2693
+ permissions: nativeAuthority.permissions(
2694
+ 'data-retention-maintenance-launcher',
2695
+ ),
2687
2696
  environment: {
2688
2697
  EBK_MAINTENANCE_ASSIGN_PUBLIC_IP:
2689
2698
  retentionMaintenanceTask.assignPublicIp.apply(
@@ -2714,8 +2723,7 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
2714
2723
  const retentionMaintenanceRule = new aws.cloudwatch.EventRule(
2715
2724
  '${pascalName}DataRetentionMaintenanceSchedule',
2716
2725
  {
2717
- name:
2718
- workloadRoleResourceNames!.dataRetentionMaintenanceRule,
2726
+ name: runtimeResourceNames.dataRetentionMaintenanceRule,
2719
2727
  scheduleExpression: 'rate(1 day)',
2720
2728
  },
2721
2729
  );
@@ -2769,12 +2777,12 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
2769
2777
  'database-retirement',
2770
2778
  databaseIdentifier,
2771
2779
  );
2772
- const databaseRoleBindings =
2773
- workloadRoleBindings!.database(databaseIdentifier);
2774
2780
  const bootstrapTask = new sst.aws.Task(
2775
2781
  target.resourceName + 'BootstrapTask',
2776
2782
  {
2777
- ...databaseRoleBindings.bootstrap,
2783
+ permissions: nativeAuthority.permissions(
2784
+ 'database-' + databaseIdentifier + '-bootstrap-task',
2785
+ ),
2778
2786
  cluster: foundation.cluster,
2779
2787
  command: ['node', 'jobs/bootstrap-database.mjs'],
2780
2788
  environment: {
@@ -2831,7 +2839,9 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
2831
2839
  const migrationTask = new sst.aws.Task(
2832
2840
  target.resourceName + 'MigrationTask',
2833
2841
  {
2834
- ...databaseRoleBindings.migration,
2842
+ permissions: nativeAuthority.permissions(
2843
+ 'database-' + databaseIdentifier + '-migration-task',
2844
+ ),
2835
2845
  cluster: foundation.cluster,
2836
2846
  environment: {
2837
2847
  ...databaseMigrationContainer.environment,
@@ -2918,7 +2928,7 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
2918
2928
  },
2919
2929
  },
2920
2930
  migrationWorkflowLogs.logGroup,
2921
- databaseRoleBindings.migrationOrchestration.roleArn,
2931
+ 'database-' + databaseIdentifier + '-migration-orchestration',
2922
2932
  );
2923
2933
  const registration = registerProductMigration(
2924
2934
  target.resourceName + 'MigrationRegistration',
@@ -2927,10 +2937,11 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
2927
2937
  );
2928
2938
  const retirementTask =
2929
2939
  $app.stage === 'development' &&
2930
- databaseIdentifier === 'retirement_rehearsal' &&
2931
- databaseRoleBindings.retirement
2940
+ databaseIdentifier === 'retirement_rehearsal'
2932
2941
  ? new sst.aws.Task(target.resourceName + 'RetirementTask', {
2933
- ...databaseRoleBindings.retirement.task,
2942
+ permissions: nativeAuthority.permissions(
2943
+ 'database-' + databaseIdentifier + '-retirement-task',
2944
+ ),
2934
2945
  cluster: foundation.cluster,
2935
2946
  command: ['node', 'jobs/retire-database.mjs'],
2936
2947
  environment: {
@@ -3044,7 +3055,7 @@ export function product(workloadRoles?: StandardSliceWorkloadRolePreflight) {
3044
3055
  },
3045
3056
  },
3046
3057
  retirementWorkflowLogs.logGroup,
3047
- databaseRoleBindings.retirement!.orchestration.roleArn,
3058
+ 'database-' + databaseIdentifier + '-retirement-orchestration',
3048
3059
  );
3049
3060
  retirementControl = {
3050
3061
  retirementWorkflowLogs,