rcf-lite 0.12.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (686) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +2 -0
  3. package/bin/rcf.js +3 -1
  4. package/bin/view-supervisor-child.mjs +0 -0
  5. package/blueprints/application-api-rest/README.md +40 -0
  6. package/blueprints/application-api-rest/assets/middleware/auth-classes.md +45 -0
  7. package/blueprints/application-api-rest/assets/openapi/openapi-skeleton.yaml +322 -0
  8. package/blueprints/application-api-rest/assets/sample-data/sample-resources.json +53 -0
  9. package/blueprints/application-api-rest/assets/samples/request-response-pairs.md +204 -0
  10. package/blueprints/application-api-rest/blueprint.json +265 -0
  11. package/blueprints/application-api-rest/contributions/adrs/adr-301-application-api-rest-error-envelope.json +25 -0
  12. package/blueprints/application-api-rest/contributions/adrs/adr-302-application-api-rest-auth-model.json +25 -0
  13. package/blueprints/application-api-rest/contributions/adrs/adr-303-application-api-rest-api-versioning.json +25 -0
  14. package/blueprints/application-api-rest/contributions/adrs/adr-304-application-api-rest-logging.json +25 -0
  15. package/blueprints/application-api-rest/contributions/adrs/adr-305-application-api-rest-pagination.json +25 -0
  16. package/blueprints/application-api-rest/contributions/adrs/adr-306-application-api-rest-idempotency.json +25 -0
  17. package/blueprints/application-api-rest/contributions/adrs/adr-307-application-api-rest-openapi-generation.json +25 -0
  18. package/blueprints/application-api-rest/contributions/adrs/adr-308-application-api-rest-rate-limiting.json +25 -0
  19. package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-001.json +18 -0
  20. package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-002.json +18 -0
  21. package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-003.json +18 -0
  22. package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-004.json +18 -0
  23. package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-005.json +18 -0
  24. package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-006.json +18 -0
  25. package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-007.json +18 -0
  26. package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-008.json +18 -0
  27. package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-009.json +18 -0
  28. package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-010.json +18 -0
  29. package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-011.json +18 -0
  30. package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-012.json +18 -0
  31. package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-013.json +18 -0
  32. package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-014.json +18 -0
  33. package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-015.json +18 -0
  34. package/blueprints/application-api-rest/contributions/requirements/application-api-rest-req-016.json +18 -0
  35. package/blueprints/application-api-rest/contributions/tacs/tac-301-application-api-rest-request-pipeline.json +48 -0
  36. package/blueprints/application-api-rest/contributions/tacs/tac-302-application-api-rest-auth-middleware.json +41 -0
  37. package/blueprints/application-api-rest/contributions/tacs/tac-303-application-api-rest-contract-surface.json +46 -0
  38. package/blueprints/application-api-rest/contributions/tacs/tac-304-application-api-rest-resource-layer.json +46 -0
  39. package/blueprints/application-api-rest/contributions/tacs/tac-305-application-api-rest-observability.json +40 -0
  40. package/blueprints/application-api-rest/contributions/tacs/tac-306-application-api-rest-operability.json +46 -0
  41. package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2101.json +72 -0
  42. package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2102.json +73 -0
  43. package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2103.json +63 -0
  44. package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2104.json +72 -0
  45. package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2105.json +63 -0
  46. package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2106.json +73 -0
  47. package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2107.json +90 -0
  48. package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2108.json +90 -0
  49. package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2109.json +72 -0
  50. package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2110.json +72 -0
  51. package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2111.json +72 -0
  52. package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2112.json +72 -0
  53. package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2113.json +73 -0
  54. package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2114.json +63 -0
  55. package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2115.json +63 -0
  56. package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2116.json +63 -0
  57. package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2117.json +64 -0
  58. package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2118.json +72 -0
  59. package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2119.json +63 -0
  60. package/blueprints/application-api-rest/contributions/user-stories/application-api-rest-us-2120.json +73 -0
  61. package/blueprints/application-api-rest/docs/topics.md +46 -0
  62. package/blueprints/application-api-rest/guide/application-api-rest.md +41 -0
  63. package/blueprints/application-spa/README.md +90 -0
  64. package/blueprints/application-spa/assets/component-specs/actions-and-text-inputs.md +36 -0
  65. package/blueprints/application-spa/assets/component-specs/data-display.md +19 -0
  66. package/blueprints/application-spa/assets/component-specs/feedback-and-status.md +27 -0
  67. package/blueprints/application-spa/assets/component-specs/overlays.md +23 -0
  68. package/blueprints/application-spa/assets/component-specs/selection-controls.md +23 -0
  69. package/blueprints/application-spa/assets/sample-data/sample-entities.json +41 -0
  70. package/blueprints/application-spa/assets/tokens/design-tokens.json +140 -0
  71. package/blueprints/application-spa/assets/tokens/theme.css +169 -0
  72. package/blueprints/application-spa/assets/viewports.md +18 -0
  73. package/blueprints/application-spa/assets/wireframes/dashboard.md +48 -0
  74. package/blueprints/application-spa/assets/wireframes/detail.md +40 -0
  75. package/blueprints/application-spa/assets/wireframes/empty.md +31 -0
  76. package/blueprints/application-spa/assets/wireframes/error.md +46 -0
  77. package/blueprints/application-spa/assets/wireframes/form.md +50 -0
  78. package/blueprints/application-spa/assets/wireframes/list.md +45 -0
  79. package/blueprints/application-spa/assets/wireframes/session-expired.md +35 -0
  80. package/blueprints/application-spa/assets/wireframes/sign-in.md +41 -0
  81. package/blueprints/application-spa/assets/wireframes/sign-out.md +32 -0
  82. package/blueprints/application-spa/blueprint.json +387 -0
  83. package/blueprints/application-spa/contributions/adrs/adr-201-application-spa-routing.json +25 -0
  84. package/blueprints/application-spa/contributions/adrs/adr-202-application-spa-theming.json +25 -0
  85. package/blueprints/application-spa/contributions/adrs/adr-203-application-spa-client-state.json +25 -0
  86. package/blueprints/application-spa/contributions/adrs/adr-204-application-spa-error-envelope.json +25 -0
  87. package/blueprints/application-spa/contributions/adrs/adr-205-application-spa-auth-model.json +25 -0
  88. package/blueprints/application-spa/contributions/adrs/adr-206-application-spa-iconography.json +13 -0
  89. package/blueprints/application-spa/contributions/adrs/adr-207-application-spa-motion.json +13 -0
  90. package/blueprints/application-spa/contributions/adrs/adr-208-application-spa-i18n.json +13 -0
  91. package/blueprints/application-spa/contributions/adrs/adr-209-application-spa-telemetry-naming.json +13 -0
  92. package/blueprints/application-spa/contributions/requirements/application-spa-req-001.json +18 -0
  93. package/blueprints/application-spa/contributions/requirements/application-spa-req-002.json +18 -0
  94. package/blueprints/application-spa/contributions/requirements/application-spa-req-003.json +18 -0
  95. package/blueprints/application-spa/contributions/requirements/application-spa-req-004.json +18 -0
  96. package/blueprints/application-spa/contributions/requirements/application-spa-req-005.json +18 -0
  97. package/blueprints/application-spa/contributions/requirements/application-spa-req-006.json +18 -0
  98. package/blueprints/application-spa/contributions/requirements/application-spa-req-007.json +18 -0
  99. package/blueprints/application-spa/contributions/requirements/application-spa-req-008.json +18 -0
  100. package/blueprints/application-spa/contributions/requirements/application-spa-req-009.json +18 -0
  101. package/blueprints/application-spa/contributions/requirements/application-spa-req-010.json +18 -0
  102. package/blueprints/application-spa/contributions/requirements/application-spa-req-011.json +18 -0
  103. package/blueprints/application-spa/contributions/requirements/application-spa-req-012.json +18 -0
  104. package/blueprints/application-spa/contributions/requirements/application-spa-req-013.json +18 -0
  105. package/blueprints/application-spa/contributions/requirements/application-spa-req-014.json +18 -0
  106. package/blueprints/application-spa/contributions/requirements/application-spa-req-015.json +18 -0
  107. package/blueprints/application-spa/contributions/requirements/application-spa-req-016.json +18 -0
  108. package/blueprints/application-spa/contributions/requirements/application-spa-req-017.json +18 -0
  109. package/blueprints/application-spa/contributions/requirements/application-spa-req-018.json +18 -0
  110. package/blueprints/application-spa/contributions/requirements/application-spa-req-019.json +18 -0
  111. package/blueprints/application-spa/contributions/requirements/application-spa-req-020.json +18 -0
  112. package/blueprints/application-spa/contributions/requirements/application-spa-req-021.json +18 -0
  113. package/blueprints/application-spa/contributions/tacs/tac-201-application-spa-app-shell.json +45 -0
  114. package/blueprints/application-spa/contributions/tacs/tac-202-application-spa-theme-system.json +32 -0
  115. package/blueprints/application-spa/contributions/tacs/tac-203-application-spa-component-library.json +32 -0
  116. package/blueprints/application-spa/contributions/tacs/tac-204-application-spa-client-data-layer.json +27 -0
  117. package/blueprints/application-spa/contributions/tacs/tac-205-application-spa-forms-engine.json +27 -0
  118. package/blueprints/application-spa/contributions/tacs/tac-206-application-spa-telemetry.json +19 -0
  119. package/blueprints/application-spa/contributions/tacs/tac-207-application-spa-token-adherence-probe.json +57 -0
  120. package/blueprints/application-spa/contributions/tacs/tac-208-application-spa-icon-adherence-probe.json +56 -0
  121. package/blueprints/application-spa/contributions/tacs/tac-209-application-spa-csp-styled-adherence-probe.json +61 -0
  122. package/blueprints/application-spa/contributions/tacs/tac-210-application-spa-external-dependency-provisioning-probe.json +70 -0
  123. package/blueprints/application-spa/contributions/tacs/tac-211-application-spa-core-flow-e2e-probe.json +70 -0
  124. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1101.json +72 -0
  125. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1102.json +63 -0
  126. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1103.json +72 -0
  127. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1104.json +63 -0
  128. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1105.json +69 -0
  129. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1106.json +63 -0
  130. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1107.json +63 -0
  131. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1108.json +90 -0
  132. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1109.json +90 -0
  133. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1110.json +100 -0
  134. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1111.json +90 -0
  135. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1112.json +81 -0
  136. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1113.json +82 -0
  137. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1114.json +60 -0
  138. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1115.json +73 -0
  139. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1116.json +72 -0
  140. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1117.json +73 -0
  141. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1118.json +54 -0
  142. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1119.json +63 -0
  143. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1120.json +72 -0
  144. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1121.json +73 -0
  145. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1122.json +69 -0
  146. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1123.json +63 -0
  147. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1124.json +60 -0
  148. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1125.json +69 -0
  149. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1126.json +78 -0
  150. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1127.json +63 -0
  151. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1128.json +51 -0
  152. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1129.json +54 -0
  153. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1130.json +54 -0
  154. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1131.json +72 -0
  155. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1132.json +72 -0
  156. package/blueprints/application-spa/contributions/user-stories/application-spa-us-1133.json +72 -0
  157. package/blueprints/application-spa/docs/topics.md +57 -0
  158. package/blueprints/application-spa/guide/application-spa.md +40 -0
  159. package/blueprints/delivery-ci-workflows/CHANGELOG.md +39 -0
  160. package/blueprints/delivery-ci-workflows/README.md +57 -0
  161. package/blueprints/delivery-ci-workflows/assets/ci-provider-examples/github-actions/default-branch-checks.yml +55 -0
  162. package/blueprints/delivery-ci-workflows/assets/ci-provider-examples/github-actions/pull-request-checks.yml +65 -0
  163. package/blueprints/delivery-ci-workflows/assets/ci-provider-examples/github-actions/release.yml +71 -0
  164. package/blueprints/delivery-ci-workflows/assets/ci-provider-examples/github-actions/scheduled-audit.yml +61 -0
  165. package/blueprints/delivery-ci-workflows/assets/ci-provider-examples/notes.md +61 -0
  166. package/blueprints/delivery-ci-workflows/assets/report-samples/per-gate.json +13 -0
  167. package/blueprints/delivery-ci-workflows/assets/report-samples/pipeline.json +28 -0
  168. package/blueprints/delivery-ci-workflows/blueprint.json +87 -0
  169. package/blueprints/delivery-ci-workflows/contributions/adrs/adr-701-delivery-ci-workflows-ci-gates.json +30 -0
  170. package/blueprints/delivery-ci-workflows/contributions/adrs/adr-702-delivery-ci-workflows-strict-coverage-gate.json +25 -0
  171. package/blueprints/delivery-ci-workflows/contributions/adrs/adr-703-delivery-ci-workflows-node-only-runner.json +25 -0
  172. package/blueprints/delivery-ci-workflows/contributions/adrs/adr-704-delivery-ci-workflows-report-shape.json +25 -0
  173. package/blueprints/delivery-ci-workflows/contributions/adrs/adr-705-delivery-ci-workflows-elicitation-surface.json +25 -0
  174. package/blueprints/delivery-ci-workflows/contributions/adrs/adr-706-delivery-ci-workflows-branch-model-defaults.json +25 -0
  175. package/blueprints/delivery-ci-workflows/contributions/adrs/adr-707-delivery-ci-workflows-release-workflow-shape.json +25 -0
  176. package/blueprints/delivery-ci-workflows/contributions/adrs/adr-708-delivery-ci-workflows-provider-hint-shape.json +25 -0
  177. package/blueprints/delivery-ci-workflows/contributions/adrs/adr-709-delivery-ci-workflows-release-artefacts.json +25 -0
  178. package/blueprints/delivery-ci-workflows/contributions/adrs/adr-710-delivery-ci-workflows-scheduled-audit.json +25 -0
  179. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-001.json +18 -0
  180. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-002.json +18 -0
  181. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-003.json +18 -0
  182. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-004.json +18 -0
  183. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-005.json +18 -0
  184. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-006.json +18 -0
  185. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-007.json +18 -0
  186. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-008.json +18 -0
  187. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-009.json +18 -0
  188. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-010.json +18 -0
  189. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-011.json +18 -0
  190. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-012.json +18 -0
  191. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-013.json +18 -0
  192. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-014.json +18 -0
  193. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-015.json +18 -0
  194. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-016.json +18 -0
  195. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-017.json +18 -0
  196. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-018.json +18 -0
  197. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-019.json +18 -0
  198. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-020.json +18 -0
  199. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-021.json +18 -0
  200. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-022.json +18 -0
  201. package/blueprints/delivery-ci-workflows/contributions/requirements/delivery-ci-workflows-req-023.json +18 -0
  202. package/blueprints/delivery-ci-workflows/contributions/tacs/tac-701-delivery-ci-workflows-gate-runner.json +59 -0
  203. package/blueprints/delivery-ci-workflows/contributions/tacs/tac-702-delivery-ci-workflows-gate-report.json +32 -0
  204. package/blueprints/delivery-ci-workflows/contributions/tacs/tac-703-delivery-ci-workflows-aggregate-report.json +41 -0
  205. package/blueprints/delivery-ci-workflows/contributions/tacs/tac-704-delivery-ci-workflows-workflow-materialiser.json +64 -0
  206. package/blueprints/delivery-ci-workflows/contributions/tacs/tac-705-delivery-ci-workflows-release-workflow.json +51 -0
  207. package/blueprints/delivery-ci-workflows/contributions/tacs/tac-706-delivery-ci-workflows-scheduled-audit.json +38 -0
  208. package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6101.json +37 -0
  209. package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6102.json +36 -0
  210. package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6103.json +37 -0
  211. package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6104.json +37 -0
  212. package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6105.json +36 -0
  213. package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6106.json +36 -0
  214. package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6107.json +37 -0
  215. package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6108.json +37 -0
  216. package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6109.json +36 -0
  217. package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6110.json +36 -0
  218. package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6111.json +36 -0
  219. package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6112.json +36 -0
  220. package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6113.json +36 -0
  221. package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6114.json +46 -0
  222. package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6115.json +37 -0
  223. package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6116.json +28 -0
  224. package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6117.json +28 -0
  225. package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6118.json +37 -0
  226. package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6119.json +28 -0
  227. package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6120.json +28 -0
  228. package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6121.json +46 -0
  229. package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6122.json +46 -0
  230. package/blueprints/delivery-ci-workflows/contributions/user-stories/delivery-ci-workflows-us-6123.json +37 -0
  231. package/blueprints/delivery-ci-workflows/docs/topics.md +61 -0
  232. package/blueprints/delivery-ci-workflows/guide/delivery-ci-workflows.md +136 -0
  233. package/blueprints/deploy-cloudflare-workers/README.md +63 -0
  234. package/blueprints/deploy-cloudflare-workers/assets/ci-workflows/build-and-upload.yml.md +109 -0
  235. package/blueprints/deploy-cloudflare-workers/assets/ci-workflows/promote.yml.md +120 -0
  236. package/blueprints/deploy-cloudflare-workers/assets/verification/served-surface-probes.md +90 -0
  237. package/blueprints/deploy-cloudflare-workers/assets/wrangler-samples/bootstrap-vs-steady-state.md +87 -0
  238. package/blueprints/deploy-cloudflare-workers/assets/wrangler-samples/preview-alias-shape.md +86 -0
  239. package/blueprints/deploy-cloudflare-workers/assets/wrangler-samples/wrangler-toml-shape.md +85 -0
  240. package/blueprints/deploy-cloudflare-workers/blueprint.json +48 -0
  241. package/blueprints/deploy-cloudflare-workers/contributions/adrs/adr-1301-deploy-cloudflare-workers-deployment-target.json +30 -0
  242. package/blueprints/deploy-cloudflare-workers/contributions/adrs/adr-1302-deploy-cloudflare-workers-default-vendor.json +35 -0
  243. package/blueprints/deploy-cloudflare-workers/contributions/adrs/adr-1303-deploy-cloudflare-workers-preview-vs-production.json +30 -0
  244. package/blueprints/deploy-cloudflare-workers/contributions/adrs/adr-1304-deploy-cloudflare-workers-rollback-is-promote.json +25 -0
  245. package/blueprints/deploy-cloudflare-workers/contributions/adrs/adr-1305-deploy-cloudflare-workers-dev-mode-drift.json +25 -0
  246. package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-001.json +18 -0
  247. package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-002.json +18 -0
  248. package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-003.json +18 -0
  249. package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-004.json +18 -0
  250. package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-005.json +18 -0
  251. package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-006.json +18 -0
  252. package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-007.json +18 -0
  253. package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-008.json +18 -0
  254. package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-009.json +18 -0
  255. package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-010.json +18 -0
  256. package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-011.json +18 -0
  257. package/blueprints/deploy-cloudflare-workers/contributions/requirements/deploy-cloudflare-workers-req-012.json +18 -0
  258. package/blueprints/deploy-cloudflare-workers/contributions/tacs/tac-1301-deploy-cloudflare-workers-deploy-adapter.json +54 -0
  259. package/blueprints/deploy-cloudflare-workers/contributions/tacs/tac-1302-deploy-cloudflare-workers-wrangler-manifest.json +45 -0
  260. package/blueprints/deploy-cloudflare-workers/contributions/tacs/tac-1303-deploy-cloudflare-workers-preview-url-resolver.json +46 -0
  261. package/blueprints/deploy-cloudflare-workers/contributions/tacs/tac-1304-deploy-cloudflare-workers-promote-gate.json +57 -0
  262. package/blueprints/deploy-cloudflare-workers/contributions/tacs/tac-1305-deploy-cloudflare-workers-served-surface-verifier.json +51 -0
  263. package/blueprints/deploy-cloudflare-workers/contributions/tacs/tac-1306-deploy-cloudflare-workers-deploy-ci-workflows.json +64 -0
  264. package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12101.json +54 -0
  265. package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12102.json +45 -0
  266. package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12103.json +46 -0
  267. package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12104.json +46 -0
  268. package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12105.json +46 -0
  269. package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12106.json +46 -0
  270. package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12107.json +46 -0
  271. package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12108.json +46 -0
  272. package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12109.json +47 -0
  273. package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12110.json +46 -0
  274. package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12111.json +45 -0
  275. package/blueprints/deploy-cloudflare-workers/contributions/user-stories/deploy-cloudflare-workers-us-12112.json +46 -0
  276. package/blueprints/deploy-cloudflare-workers/docs/topics.md +46 -0
  277. package/blueprints/deploy-cloudflare-workers/guide/deploy-cloudflare-workers.md +74 -0
  278. package/blueprints/email-smtp-resend/README.md +45 -0
  279. package/blueprints/email-smtp-resend/assets/from-address-rotation-pattern.md +44 -0
  280. package/blueprints/email-smtp-resend/assets/resend-verification-pointer.md +25 -0
  281. package/blueprints/email-smtp-resend/assets/stub-adapter.md +65 -0
  282. package/blueprints/email-smtp-resend/blueprint.json +23 -0
  283. package/blueprints/email-smtp-resend/contributions/adrs/adr-401-email-smtp-resend-transport-choice.json +30 -0
  284. package/blueprints/email-smtp-resend/contributions/adrs/adr-402-email-smtp-resend-retry-and-backoff-posture.json +30 -0
  285. package/blueprints/email-smtp-resend/contributions/requirements/email-smtp-resend-req-001.json +18 -0
  286. package/blueprints/email-smtp-resend/contributions/requirements/email-smtp-resend-req-002.json +18 -0
  287. package/blueprints/email-smtp-resend/contributions/requirements/email-smtp-resend-req-003.json +18 -0
  288. package/blueprints/email-smtp-resend/contributions/requirements/email-smtp-resend-req-004.json +18 -0
  289. package/blueprints/email-smtp-resend/contributions/requirements/email-smtp-resend-req-005.json +18 -0
  290. package/blueprints/email-smtp-resend/contributions/requirements/email-smtp-resend-req-006.json +18 -0
  291. package/blueprints/email-smtp-resend/contributions/tacs/tac-401-email-smtp-resend-send-adapter.json +53 -0
  292. package/blueprints/email-smtp-resend/contributions/tacs/tac-402-email-smtp-resend-webhook-verifier.json +56 -0
  293. package/blueprints/email-smtp-resend/contributions/user-stories/email-smtp-resend-us-4101.json +45 -0
  294. package/blueprints/email-smtp-resend/contributions/user-stories/email-smtp-resend-us-4102.json +36 -0
  295. package/blueprints/email-smtp-resend/contributions/user-stories/email-smtp-resend-us-4103.json +45 -0
  296. package/blueprints/email-smtp-resend/contributions/user-stories/email-smtp-resend-us-4104.json +45 -0
  297. package/blueprints/email-smtp-resend/contributions/user-stories/email-smtp-resend-us-4105.json +36 -0
  298. package/blueprints/email-smtp-resend/contributions/user-stories/email-smtp-resend-us-4106.json +37 -0
  299. package/blueprints/email-smtp-resend/docs/topics.md +44 -0
  300. package/blueprints/email-smtp-resend/guide/email-smtp-resend.md +71 -0
  301. package/blueprints/observability-essentials/README.md +53 -0
  302. package/blueprints/observability-essentials/assets/probe-samples/liveness-body.json +4 -0
  303. package/blueprints/observability-essentials/assets/probe-samples/readiness-body.json +18 -0
  304. package/blueprints/observability-essentials/assets/status-page-samples/status-page-clean.html +22 -0
  305. package/blueprints/observability-essentials/assets/status-page-samples/status-page-with-notice.html +25 -0
  306. package/blueprints/observability-essentials/blueprint.json +54 -0
  307. package/blueprints/observability-essentials/contributions/adrs/adr-801-observability-essentials-health-probes.json +30 -0
  308. package/blueprints/observability-essentials/contributions/adrs/adr-802-observability-essentials-readiness-semantics.json +30 -0
  309. package/blueprints/observability-essentials/contributions/adrs/adr-803-observability-essentials-status-page-contract.json +30 -0
  310. package/blueprints/observability-essentials/contributions/adrs/adr-804-observability-essentials-probe-secrecy.json +25 -0
  311. package/blueprints/observability-essentials/contributions/adrs/adr-805-observability-essentials-notification-outcome-model.json +25 -0
  312. package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-001.json +18 -0
  313. package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-002.json +18 -0
  314. package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-003.json +18 -0
  315. package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-004.json +18 -0
  316. package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-005.json +18 -0
  317. package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-006.json +18 -0
  318. package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-007.json +18 -0
  319. package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-008.json +18 -0
  320. package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-009.json +18 -0
  321. package/blueprints/observability-essentials/contributions/requirements/observability-essentials-req-010.json +18 -0
  322. package/blueprints/observability-essentials/contributions/tacs/tac-801-observability-essentials-liveness-probe.json +32 -0
  323. package/blueprints/observability-essentials/contributions/tacs/tac-802-observability-essentials-readiness-probe.json +43 -0
  324. package/blueprints/observability-essentials/contributions/tacs/tac-803-observability-essentials-status-page.json +37 -0
  325. package/blueprints/observability-essentials/contributions/tacs/tac-804-observability-essentials-notification-outcome.json +42 -0
  326. package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7101.json +45 -0
  327. package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7102.json +45 -0
  328. package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7103.json +45 -0
  329. package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7104.json +45 -0
  330. package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7105.json +45 -0
  331. package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7106.json +45 -0
  332. package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7107.json +46 -0
  333. package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7108.json +47 -0
  334. package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7109.json +45 -0
  335. package/blueprints/observability-essentials/contributions/user-stories/observability-essentials-us-7110.json +46 -0
  336. package/blueprints/observability-essentials/docs/topics.md +57 -0
  337. package/blueprints/observability-essentials/guide/observability-essentials.md +68 -0
  338. package/blueprints/observability-probe-endpoints/README.md +53 -0
  339. package/blueprints/observability-probe-endpoints/assets/docker/dockerfile-healthcheck.md +19 -0
  340. package/blueprints/observability-probe-endpoints/assets/kubernetes/podspec-probes-separate-port.md +54 -0
  341. package/blueprints/observability-probe-endpoints/assets/kubernetes/podspec-probes.md +36 -0
  342. package/blueprints/observability-probe-endpoints/assets/load-balancer/health-check-config.md +23 -0
  343. package/blueprints/observability-probe-endpoints/assets/systemd/notify-service.md +30 -0
  344. package/blueprints/observability-probe-endpoints/assets/uptime-monitor/monitor-config.md +22 -0
  345. package/blueprints/observability-probe-endpoints/blueprint.json +44 -0
  346. package/blueprints/observability-probe-endpoints/contributions/adrs/adr-1501-observability-probe-endpoints-health-probes.json +30 -0
  347. package/blueprints/observability-probe-endpoints/contributions/adrs/adr-1502-observability-probe-endpoints-readiness-semantics.json +30 -0
  348. package/blueprints/observability-probe-endpoints/contributions/adrs/adr-1503-observability-probe-endpoints-kubernetes-default.json +30 -0
  349. package/blueprints/observability-probe-endpoints/contributions/adrs/adr-1504-observability-probe-endpoints-separate-port-option.json +30 -0
  350. package/blueprints/observability-probe-endpoints/contributions/adrs/adr-1505-observability-probe-endpoints-external-response-secrecy.json +30 -0
  351. package/blueprints/observability-probe-endpoints/contributions/requirements/observability-probe-endpoints-req-001.json +18 -0
  352. package/blueprints/observability-probe-endpoints/contributions/requirements/observability-probe-endpoints-req-002.json +18 -0
  353. package/blueprints/observability-probe-endpoints/contributions/requirements/observability-probe-endpoints-req-003.json +18 -0
  354. package/blueprints/observability-probe-endpoints/contributions/requirements/observability-probe-endpoints-req-004.json +18 -0
  355. package/blueprints/observability-probe-endpoints/contributions/requirements/observability-probe-endpoints-req-005.json +18 -0
  356. package/blueprints/observability-probe-endpoints/contributions/requirements/observability-probe-endpoints-req-006.json +18 -0
  357. package/blueprints/observability-probe-endpoints/contributions/requirements/observability-probe-endpoints-req-007.json +18 -0
  358. package/blueprints/observability-probe-endpoints/contributions/requirements/observability-probe-endpoints-req-008.json +18 -0
  359. package/blueprints/observability-probe-endpoints/contributions/tacs/tac-1501-observability-probe-endpoints-profile-resolver.json +39 -0
  360. package/blueprints/observability-probe-endpoints/contributions/tacs/tac-1502-observability-probe-endpoints-handler-set.json +40 -0
  361. package/blueprints/observability-probe-endpoints/contributions/tacs/tac-1503-observability-probe-endpoints-listener-topology.json +51 -0
  362. package/blueprints/observability-probe-endpoints/contributions/tacs/tac-1504-observability-probe-endpoints-non-http-adapters.json +39 -0
  363. package/blueprints/observability-probe-endpoints/contributions/user-stories/observability-probe-endpoints-us-14101.json +46 -0
  364. package/blueprints/observability-probe-endpoints/contributions/user-stories/observability-probe-endpoints-us-14102.json +46 -0
  365. package/blueprints/observability-probe-endpoints/contributions/user-stories/observability-probe-endpoints-us-14103.json +46 -0
  366. package/blueprints/observability-probe-endpoints/contributions/user-stories/observability-probe-endpoints-us-14104.json +45 -0
  367. package/blueprints/observability-probe-endpoints/contributions/user-stories/observability-probe-endpoints-us-14105.json +46 -0
  368. package/blueprints/observability-probe-endpoints/contributions/user-stories/observability-probe-endpoints-us-14106.json +45 -0
  369. package/blueprints/observability-probe-endpoints/contributions/user-stories/observability-probe-endpoints-us-14107.json +45 -0
  370. package/blueprints/observability-probe-endpoints/contributions/user-stories/observability-probe-endpoints-us-14108.json +46 -0
  371. package/blueprints/observability-probe-endpoints/docs/topics.md +51 -0
  372. package/blueprints/observability-probe-endpoints/guide/observability-probe-endpoints.md +83 -0
  373. package/blueprints/persistence-data-d1/README.md +50 -0
  374. package/blueprints/persistence-data-d1/assets/batch-usage/batch-atomicity-example.md +72 -0
  375. package/blueprints/persistence-data-d1/assets/facade-shape/facade-module-shape.md +115 -0
  376. package/blueprints/persistence-data-d1/assets/migration-shape/migration-file-shape.md +119 -0
  377. package/blueprints/persistence-data-d1/assets/wrangler-config/d1-binding-shape.md +93 -0
  378. package/blueprints/persistence-data-d1/blueprint.json +42 -0
  379. package/blueprints/persistence-data-d1/contributions/adrs/adr-1401-persistence-data-d1-store-model.json +30 -0
  380. package/blueprints/persistence-data-d1/contributions/adrs/adr-1402-persistence-data-d1-migration-discipline.json +30 -0
  381. package/blueprints/persistence-data-d1/contributions/adrs/adr-1403-persistence-data-d1-event-secrecy.json +25 -0
  382. package/blueprints/persistence-data-d1/contributions/adrs/adr-1404-persistence-data-d1-store-boundary.json +25 -0
  383. package/blueprints/persistence-data-d1/contributions/adrs/adr-1405-persistence-data-d1-recovery-model.json +30 -0
  384. package/blueprints/persistence-data-d1/contributions/requirements/persistence-data-d1-req-001.json +18 -0
  385. package/blueprints/persistence-data-d1/contributions/requirements/persistence-data-d1-req-002.json +18 -0
  386. package/blueprints/persistence-data-d1/contributions/requirements/persistence-data-d1-req-003.json +18 -0
  387. package/blueprints/persistence-data-d1/contributions/requirements/persistence-data-d1-req-004.json +18 -0
  388. package/blueprints/persistence-data-d1/contributions/requirements/persistence-data-d1-req-005.json +18 -0
  389. package/blueprints/persistence-data-d1/contributions/requirements/persistence-data-d1-req-006.json +18 -0
  390. package/blueprints/persistence-data-d1/contributions/requirements/persistence-data-d1-req-007.json +18 -0
  391. package/blueprints/persistence-data-d1/contributions/tacs/tac-1401-persistence-data-d1-facade.json +51 -0
  392. package/blueprints/persistence-data-d1/contributions/tacs/tac-1402-persistence-data-d1-migration-catalog.json +31 -0
  393. package/blueprints/persistence-data-d1/contributions/tacs/tac-1403-persistence-data-d1-deploy-gate.json +38 -0
  394. package/blueprints/persistence-data-d1/contributions/tacs/tac-1404-persistence-data-d1-recovery-runner.json +39 -0
  395. package/blueprints/persistence-data-d1/contributions/user-stories/persistence-data-d1-us-13101.json +45 -0
  396. package/blueprints/persistence-data-d1/contributions/user-stories/persistence-data-d1-us-13102.json +45 -0
  397. package/blueprints/persistence-data-d1/contributions/user-stories/persistence-data-d1-us-13103.json +46 -0
  398. package/blueprints/persistence-data-d1/contributions/user-stories/persistence-data-d1-us-13104.json +45 -0
  399. package/blueprints/persistence-data-d1/contributions/user-stories/persistence-data-d1-us-13105.json +45 -0
  400. package/blueprints/persistence-data-d1/contributions/user-stories/persistence-data-d1-us-13106.json +46 -0
  401. package/blueprints/persistence-data-d1/contributions/user-stories/persistence-data-d1-us-13107.json +38 -0
  402. package/blueprints/persistence-data-d1/docs/topics.md +59 -0
  403. package/blueprints/persistence-data-d1/guide/persistence-data-d1.md +77 -0
  404. package/blueprints/persistence-data-sqlite/README.md +50 -0
  405. package/blueprints/persistence-data-sqlite/assets/backup-procedures/hot-checkpoint-note.md +22 -0
  406. package/blueprints/persistence-data-sqlite/assets/backup-procedures/sqlite-file-copy.md +70 -0
  407. package/blueprints/persistence-data-sqlite/assets/schema-samples/catalog-file-layout.md +73 -0
  408. package/blueprints/persistence-data-sqlite/assets/schema-samples/migration-shape.md +76 -0
  409. package/blueprints/persistence-data-sqlite/blueprint.json +50 -0
  410. package/blueprints/persistence-data-sqlite/contributions/adrs/adr-601-persistence-data-sqlite-store-model.json +30 -0
  411. package/blueprints/persistence-data-sqlite/contributions/adrs/adr-602-persistence-data-sqlite-migration-discipline.json +30 -0
  412. package/blueprints/persistence-data-sqlite/contributions/adrs/adr-603-persistence-data-sqlite-event-secrecy.json +25 -0
  413. package/blueprints/persistence-data-sqlite/contributions/adrs/adr-604-persistence-data-sqlite-store-boundary.json +25 -0
  414. package/blueprints/persistence-data-sqlite/contributions/adrs/adr-605-persistence-data-sqlite-backup-model.json +25 -0
  415. package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-001.json +18 -0
  416. package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-002.json +18 -0
  417. package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-003.json +18 -0
  418. package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-004.json +18 -0
  419. package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-005.json +18 -0
  420. package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-006.json +18 -0
  421. package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-007.json +18 -0
  422. package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-008.json +18 -0
  423. package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-009.json +18 -0
  424. package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-010.json +18 -0
  425. package/blueprints/persistence-data-sqlite/contributions/requirements/persistence-data-sqlite-req-011.json +18 -0
  426. package/blueprints/persistence-data-sqlite/contributions/tacs/tac-601-persistence-data-sqlite-store.json +57 -0
  427. package/blueprints/persistence-data-sqlite/contributions/tacs/tac-602-persistence-data-sqlite-migration-runner.json +34 -0
  428. package/blueprints/persistence-data-sqlite/contributions/tacs/tac-603-persistence-data-sqlite-migration-catalog.json +31 -0
  429. package/blueprints/persistence-data-sqlite/contributions/tacs/tac-604-persistence-data-sqlite-backup-runner.json +33 -0
  430. package/blueprints/persistence-data-sqlite/contributions/user-stories/persistence-data-sqlite-us-5101.json +46 -0
  431. package/blueprints/persistence-data-sqlite/contributions/user-stories/persistence-data-sqlite-us-5102.json +46 -0
  432. package/blueprints/persistence-data-sqlite/contributions/user-stories/persistence-data-sqlite-us-5103.json +37 -0
  433. package/blueprints/persistence-data-sqlite/contributions/user-stories/persistence-data-sqlite-us-5104.json +45 -0
  434. package/blueprints/persistence-data-sqlite/contributions/user-stories/persistence-data-sqlite-us-5105.json +45 -0
  435. package/blueprints/persistence-data-sqlite/contributions/user-stories/persistence-data-sqlite-us-5106.json +46 -0
  436. package/blueprints/persistence-data-sqlite/contributions/user-stories/persistence-data-sqlite-us-5107.json +45 -0
  437. package/blueprints/persistence-data-sqlite/contributions/user-stories/persistence-data-sqlite-us-5108.json +46 -0
  438. package/blueprints/persistence-data-sqlite/contributions/user-stories/persistence-data-sqlite-us-5109.json +46 -0
  439. package/blueprints/persistence-data-sqlite/contributions/user-stories/persistence-data-sqlite-us-5110.json +37 -0
  440. package/blueprints/persistence-data-sqlite/contributions/user-stories/persistence-data-sqlite-us-5111.json +37 -0
  441. package/blueprints/persistence-data-sqlite/docs/topics.md +49 -0
  442. package/blueprints/persistence-data-sqlite/guide/persistence-data-sqlite.md +69 -0
  443. package/blueprints/security-auth-clerk/README.md +52 -0
  444. package/blueprints/security-auth-clerk/assets/authorisation/role-claim-mapping-sample.md +99 -0
  445. package/blueprints/security-auth-clerk/assets/middleware/node-middleware-shape.md +86 -0
  446. package/blueprints/security-auth-clerk/assets/middleware/workers-fetch-shape.md +123 -0
  447. package/blueprints/security-auth-clerk/assets/wiring/clerk-provider-react.md +48 -0
  448. package/blueprints/security-auth-clerk/assets/wiring/clerk-provider-vue.md +41 -0
  449. package/blueprints/security-auth-clerk/assets/wiring/workers-wrangler-toml-shape.md +51 -0
  450. package/blueprints/security-auth-clerk/blueprint.json +42 -0
  451. package/blueprints/security-auth-clerk/contributions/adrs/adr-1001-security-auth-clerk-auth-model.json +30 -0
  452. package/blueprints/security-auth-clerk/contributions/adrs/adr-1002-security-auth-clerk-middleware-boundary.json +25 -0
  453. package/blueprints/security-auth-clerk/contributions/adrs/adr-1003-security-auth-clerk-authorisation-adapter-contract.json +25 -0
  454. package/blueprints/security-auth-clerk/contributions/adrs/adr-1004-security-auth-clerk-claims-mapping-discipline.json +25 -0
  455. package/blueprints/security-auth-clerk/contributions/adrs/adr-1005-security-auth-clerk-session-lifecycle.json +25 -0
  456. package/blueprints/security-auth-clerk/contributions/requirements/security-auth-clerk-req-001.json +18 -0
  457. package/blueprints/security-auth-clerk/contributions/requirements/security-auth-clerk-req-002.json +18 -0
  458. package/blueprints/security-auth-clerk/contributions/requirements/security-auth-clerk-req-003.json +18 -0
  459. package/blueprints/security-auth-clerk/contributions/requirements/security-auth-clerk-req-004.json +18 -0
  460. package/blueprints/security-auth-clerk/contributions/requirements/security-auth-clerk-req-005.json +18 -0
  461. package/blueprints/security-auth-clerk/contributions/requirements/security-auth-clerk-req-006.json +18 -0
  462. package/blueprints/security-auth-clerk/contributions/requirements/security-auth-clerk-req-007.json +18 -0
  463. package/blueprints/security-auth-clerk/contributions/requirements/security-auth-clerk-req-008.json +18 -0
  464. package/blueprints/security-auth-clerk/contributions/requirements/security-auth-clerk-req-009.json +18 -0
  465. package/blueprints/security-auth-clerk/contributions/tacs/tac-1001-security-auth-clerk-middleware.json +42 -0
  466. package/blueprints/security-auth-clerk/contributions/tacs/tac-1002-security-auth-clerk-authorisation-adapter.json +30 -0
  467. package/blueprints/security-auth-clerk/contributions/tacs/tac-1003-security-auth-clerk-session-verifier.json +38 -0
  468. package/blueprints/security-auth-clerk/contributions/tacs/tac-1004-security-auth-clerk-claims-mapper.json +22 -0
  469. package/blueprints/security-auth-clerk/contributions/user-stories/security-auth-clerk-us-9101.json +46 -0
  470. package/blueprints/security-auth-clerk/contributions/user-stories/security-auth-clerk-us-9102.json +38 -0
  471. package/blueprints/security-auth-clerk/contributions/user-stories/security-auth-clerk-us-9103.json +46 -0
  472. package/blueprints/security-auth-clerk/contributions/user-stories/security-auth-clerk-us-9104.json +46 -0
  473. package/blueprints/security-auth-clerk/contributions/user-stories/security-auth-clerk-us-9105.json +36 -0
  474. package/blueprints/security-auth-clerk/contributions/user-stories/security-auth-clerk-us-9106.json +36 -0
  475. package/blueprints/security-auth-clerk/contributions/user-stories/security-auth-clerk-us-9107.json +37 -0
  476. package/blueprints/security-auth-clerk/contributions/user-stories/security-auth-clerk-us-9108.json +36 -0
  477. package/blueprints/security-auth-clerk/contributions/user-stories/security-auth-clerk-us-9109.json +36 -0
  478. package/blueprints/security-auth-clerk/contributions/user-stories/security-auth-clerk-us-9110.json +37 -0
  479. package/blueprints/security-auth-clerk/contributions/user-stories/security-auth-clerk-us-9111.json +36 -0
  480. package/blueprints/security-auth-clerk/docs/topics.md +56 -0
  481. package/blueprints/security-auth-clerk/guide/security-auth-clerk.md +80 -0
  482. package/blueprints/security-auth-keycloak/README.md +56 -0
  483. package/blueprints/security-auth-keycloak/assets/local-container/keycloak-bootstrap.md +54 -0
  484. package/blueprints/security-auth-keycloak/assets/middleware/verifier-wiring.md +93 -0
  485. package/blueprints/security-auth-keycloak/assets/mock-introspection/mock-introspection-shape.md +62 -0
  486. package/blueprints/security-auth-keycloak/assets/provider-router/router-shape.md +71 -0
  487. package/blueprints/security-auth-keycloak/assets/realm-skeleton/realm-config-shape.md +55 -0
  488. package/blueprints/security-auth-keycloak/blueprint.json +49 -0
  489. package/blueprints/security-auth-keycloak/contributions/adrs/adr-1201-security-auth-keycloak-auth-model.json +35 -0
  490. package/blueprints/security-auth-keycloak/contributions/adrs/adr-1202-security-auth-keycloak-verification-mode-choice.json +30 -0
  491. package/blueprints/security-auth-keycloak/contributions/adrs/adr-1203-security-auth-keycloak-provider-routing-seam.json +30 -0
  492. package/blueprints/security-auth-keycloak/contributions/adrs/adr-1204-security-auth-keycloak-session-vs-token-contract.json +25 -0
  493. package/blueprints/security-auth-keycloak/contributions/adrs/adr-1205-security-auth-keycloak-jwks-rotation-cache-lifetime.json +30 -0
  494. package/blueprints/security-auth-keycloak/contributions/adrs/adr-1206-security-auth-keycloak-refresh-and-sign-out-posture.json +25 -0
  495. package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-001.json +18 -0
  496. package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-002.json +18 -0
  497. package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-003.json +18 -0
  498. package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-004.json +18 -0
  499. package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-005.json +18 -0
  500. package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-006.json +18 -0
  501. package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-007.json +18 -0
  502. package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-008.json +18 -0
  503. package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-009.json +18 -0
  504. package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-010.json +18 -0
  505. package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-011.json +18 -0
  506. package/blueprints/security-auth-keycloak/contributions/requirements/security-auth-keycloak-req-012.json +18 -0
  507. package/blueprints/security-auth-keycloak/contributions/tacs/tac-1201-security-auth-keycloak-discovery-client.json +51 -0
  508. package/blueprints/security-auth-keycloak/contributions/tacs/tac-1202-security-auth-keycloak-jwt-verifier.json +46 -0
  509. package/blueprints/security-auth-keycloak/contributions/tacs/tac-1203-security-auth-keycloak-introspection-client.json +45 -0
  510. package/blueprints/security-auth-keycloak/contributions/tacs/tac-1204-security-auth-keycloak-provider-router.json +37 -0
  511. package/blueprints/security-auth-keycloak/contributions/tacs/tac-1205-security-auth-keycloak-role-adapter.json +32 -0
  512. package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11101.json +47 -0
  513. package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11102.json +45 -0
  514. package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11103.json +36 -0
  515. package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11104.json +36 -0
  516. package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11105.json +45 -0
  517. package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11106.json +46 -0
  518. package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11107.json +45 -0
  519. package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11108.json +45 -0
  520. package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11109.json +37 -0
  521. package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11110.json +45 -0
  522. package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11111.json +45 -0
  523. package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11112.json +37 -0
  524. package/blueprints/security-auth-keycloak/contributions/user-stories/security-auth-keycloak-us-11113.json +36 -0
  525. package/blueprints/security-auth-keycloak/docs/topics.md +74 -0
  526. package/blueprints/security-auth-keycloak/guide/security-auth-keycloak.md +81 -0
  527. package/blueprints/security-auth-magic-link/README.md +46 -0
  528. package/blueprints/security-auth-magic-link/assets/email-templates/magic-link-email.md +44 -0
  529. package/blueprints/security-auth-magic-link/assets/email-templates/stub-adapter.md +55 -0
  530. package/blueprints/security-auth-magic-link/assets/principal-registry-samples/allow-list-file.md +46 -0
  531. package/blueprints/security-auth-magic-link/assets/principal-registry-samples/single-address.md +35 -0
  532. package/blueprints/security-auth-magic-link/blueprint.json +45 -0
  533. package/blueprints/security-auth-magic-link/contributions/adrs/adr-501-security-auth-magic-link-model.json +30 -0
  534. package/blueprints/security-auth-magic-link/contributions/adrs/adr-502-security-auth-magic-link-token-secrecy.json +25 -0
  535. package/blueprints/security-auth-magic-link/contributions/adrs/adr-503-security-auth-magic-link-anti-enumeration-budget.json +25 -0
  536. package/blueprints/security-auth-magic-link/contributions/adrs/adr-504-security-auth-magic-link-session-lifecycle.json +30 -0
  537. package/blueprints/security-auth-magic-link/contributions/adrs/adr-505-security-auth-magic-link-rate-limiting.json +25 -0
  538. package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-001.json +18 -0
  539. package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-002.json +18 -0
  540. package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-003.json +18 -0
  541. package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-004.json +18 -0
  542. package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-005.json +18 -0
  543. package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-006.json +18 -0
  544. package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-007.json +18 -0
  545. package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-008.json +18 -0
  546. package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-009.json +18 -0
  547. package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-010.json +18 -0
  548. package/blueprints/security-auth-magic-link/contributions/requirements/security-auth-magic-link-req-011.json +18 -0
  549. package/blueprints/security-auth-magic-link/contributions/tacs/tac-501-security-auth-magic-link-manager.json +45 -0
  550. package/blueprints/security-auth-magic-link/contributions/tacs/tac-502-security-auth-magic-link-session-manager.json +46 -0
  551. package/blueprints/security-auth-magic-link/contributions/tacs/tac-503-security-auth-magic-link-login-routes.json +76 -0
  552. package/blueprints/security-auth-magic-link/contributions/tacs/tac-504-security-auth-magic-link-email-delivery-adapter.json +26 -0
  553. package/blueprints/security-auth-magic-link/contributions/tacs/tac-505-security-auth-magic-link-principal-registry.json +26 -0
  554. package/blueprints/security-auth-magic-link/contributions/user-stories/security-auth-magic-link-us-3101.json +64 -0
  555. package/blueprints/security-auth-magic-link/contributions/user-stories/security-auth-magic-link-us-3102.json +54 -0
  556. package/blueprints/security-auth-magic-link/contributions/user-stories/security-auth-magic-link-us-3103.json +45 -0
  557. package/blueprints/security-auth-magic-link/contributions/user-stories/security-auth-magic-link-us-3104.json +55 -0
  558. package/blueprints/security-auth-magic-link/contributions/user-stories/security-auth-magic-link-us-3105.json +46 -0
  559. package/blueprints/security-auth-magic-link/contributions/user-stories/security-auth-magic-link-us-3106.json +46 -0
  560. package/blueprints/security-auth-magic-link/contributions/user-stories/security-auth-magic-link-us-3107.json +54 -0
  561. package/blueprints/security-auth-magic-link/contributions/user-stories/security-auth-magic-link-us-3108.json +46 -0
  562. package/blueprints/security-auth-magic-link/contributions/user-stories/security-auth-magic-link-us-3109.json +48 -0
  563. package/blueprints/security-auth-magic-link/contributions/user-stories/security-auth-magic-link-us-3110.json +45 -0
  564. package/blueprints/security-auth-magic-link/contributions/user-stories/security-auth-magic-link-us-3111.json +45 -0
  565. package/blueprints/security-auth-magic-link/docs/topics.md +45 -0
  566. package/blueprints/security-auth-magic-link/guide/security-auth-magic-link.md +65 -0
  567. package/blueprints/security-auth-oauth2/README.md +50 -0
  568. package/blueprints/security-auth-oauth2/assets/mock-provider/mock-oidc-shape.md +55 -0
  569. package/blueprints/security-auth-oauth2/assets/provider-selector/list-shape.md +27 -0
  570. package/blueprints/security-auth-oauth2/assets/providers/generic-oidc-discovery.md +31 -0
  571. package/blueprints/security-auth-oauth2/assets/providers/github-oauth2-only.md +31 -0
  572. package/blueprints/security-auth-oauth2/assets/providers/google-oidc.md +31 -0
  573. package/blueprints/security-auth-oauth2/assets/session-bridge/opaque-handle-shape.md +59 -0
  574. package/blueprints/security-auth-oauth2/blueprint.json +44 -0
  575. package/blueprints/security-auth-oauth2/contributions/adrs/adr-1101-security-auth-oauth2-auth-model.json +35 -0
  576. package/blueprints/security-auth-oauth2/contributions/adrs/adr-1102-security-auth-oauth2-provider-abstraction-contract.json +25 -0
  577. package/blueprints/security-auth-oauth2/contributions/adrs/adr-1103-security-auth-oauth2-pkce-discipline.json +25 -0
  578. package/blueprints/security-auth-oauth2/contributions/adrs/adr-1104-security-auth-oauth2-session-bridge-shape.json +25 -0
  579. package/blueprints/security-auth-oauth2/contributions/adrs/adr-1105-security-auth-oauth2-refresh-token-posture.json +25 -0
  580. package/blueprints/security-auth-oauth2/contributions/adrs/adr-1106-security-auth-oauth2-multi-provider-routing.json +25 -0
  581. package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-001.json +18 -0
  582. package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-002.json +18 -0
  583. package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-003.json +18 -0
  584. package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-004.json +18 -0
  585. package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-005.json +18 -0
  586. package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-006.json +18 -0
  587. package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-007.json +18 -0
  588. package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-008.json +18 -0
  589. package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-009.json +18 -0
  590. package/blueprints/security-auth-oauth2/contributions/requirements/security-auth-oauth2-req-010.json +18 -0
  591. package/blueprints/security-auth-oauth2/contributions/tacs/tac-1101-security-auth-oauth2-flow-controller.json +61 -0
  592. package/blueprints/security-auth-oauth2/contributions/tacs/tac-1102-security-auth-oauth2-provider-adapter.json +33 -0
  593. package/blueprints/security-auth-oauth2/contributions/tacs/tac-1103-security-auth-oauth2-session-bridge.json +51 -0
  594. package/blueprints/security-auth-oauth2/contributions/tacs/tac-1104-security-auth-oauth2-provider-selector.json +29 -0
  595. package/blueprints/security-auth-oauth2/contributions/user-stories/security-auth-oauth2-us-10101.json +47 -0
  596. package/blueprints/security-auth-oauth2/contributions/user-stories/security-auth-oauth2-us-10102.json +45 -0
  597. package/blueprints/security-auth-oauth2/contributions/user-stories/security-auth-oauth2-us-10103.json +36 -0
  598. package/blueprints/security-auth-oauth2/contributions/user-stories/security-auth-oauth2-us-10104.json +36 -0
  599. package/blueprints/security-auth-oauth2/contributions/user-stories/security-auth-oauth2-us-10105.json +55 -0
  600. package/blueprints/security-auth-oauth2/contributions/user-stories/security-auth-oauth2-us-10106.json +45 -0
  601. package/blueprints/security-auth-oauth2/contributions/user-stories/security-auth-oauth2-us-10107.json +46 -0
  602. package/blueprints/security-auth-oauth2/contributions/user-stories/security-auth-oauth2-us-10108.json +46 -0
  603. package/blueprints/security-auth-oauth2/contributions/user-stories/security-auth-oauth2-us-10109.json +37 -0
  604. package/blueprints/security-auth-oauth2/contributions/user-stories/security-auth-oauth2-us-10110.json +37 -0
  605. package/blueprints/security-auth-oauth2/contributions/user-stories/security-auth-oauth2-us-10111.json +28 -0
  606. package/blueprints/security-auth-oauth2/docs/topics.md +58 -0
  607. package/blueprints/security-auth-oauth2/guide/security-auth-oauth2.md +65 -0
  608. package/blueprints/security-secrets-management/README.md +48 -0
  609. package/blueprints/security-secrets-management/assets/cli-usage/agent-access-pattern.md +69 -0
  610. package/blueprints/security-secrets-management/assets/manifest-samples/environment-aware-example.md +33 -0
  611. package/blueprints/security-secrets-management/assets/manifest-samples/secrets-yaml-shape.md +74 -0
  612. package/blueprints/security-secrets-management/assets/ui-integration/three-way-choice.md +44 -0
  613. package/blueprints/security-secrets-management/blueprint.json +43 -0
  614. package/blueprints/security-secrets-management/contributions/adrs/adr-901-security-secrets-management-secrets-source.json +30 -0
  615. package/blueprints/security-secrets-management/contributions/adrs/adr-902-security-secrets-management-default-vendor.json +35 -0
  616. package/blueprints/security-secrets-management/contributions/adrs/adr-903-security-secrets-management-agent-access-discipline.json +25 -0
  617. package/blueprints/security-secrets-management/contributions/adrs/adr-904-security-secrets-management-dotenv-reflection.json +25 -0
  618. package/blueprints/security-secrets-management/contributions/adrs/adr-905-security-secrets-management-rotation-and-audit.json +30 -0
  619. package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-001.json +18 -0
  620. package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-002.json +18 -0
  621. package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-003.json +18 -0
  622. package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-004.json +18 -0
  623. package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-005.json +18 -0
  624. package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-006.json +18 -0
  625. package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-007.json +18 -0
  626. package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-008.json +18 -0
  627. package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-009.json +18 -0
  628. package/blueprints/security-secrets-management/contributions/requirements/security-secrets-management-req-010.json +18 -0
  629. package/blueprints/security-secrets-management/contributions/tacs/tac-901-security-secrets-management-manager-client.json +52 -0
  630. package/blueprints/security-secrets-management/contributions/tacs/tac-902-security-secrets-management-manifest.json +34 -0
  631. package/blueprints/security-secrets-management/contributions/tacs/tac-903-security-secrets-management-env-reflector.json +46 -0
  632. package/blueprints/security-secrets-management/contributions/tacs/tac-904-security-secrets-management-rotation-gate.json +57 -0
  633. package/blueprints/security-secrets-management/contributions/tacs/tac-905-security-secrets-management-agent-cli.json +59 -0
  634. package/blueprints/security-secrets-management/contributions/user-stories/security-secrets-management-us-8101.json +46 -0
  635. package/blueprints/security-secrets-management/contributions/user-stories/security-secrets-management-us-8102.json +45 -0
  636. package/blueprints/security-secrets-management/contributions/user-stories/security-secrets-management-us-8103.json +37 -0
  637. package/blueprints/security-secrets-management/contributions/user-stories/security-secrets-management-us-8104.json +45 -0
  638. package/blueprints/security-secrets-management/contributions/user-stories/security-secrets-management-us-8105.json +55 -0
  639. package/blueprints/security-secrets-management/contributions/user-stories/security-secrets-management-us-8106.json +46 -0
  640. package/blueprints/security-secrets-management/contributions/user-stories/security-secrets-management-us-8107.json +46 -0
  641. package/blueprints/security-secrets-management/contributions/user-stories/security-secrets-management-us-8108.json +45 -0
  642. package/blueprints/security-secrets-management/contributions/user-stories/security-secrets-management-us-8109.json +46 -0
  643. package/blueprints/security-secrets-management/contributions/user-stories/security-secrets-management-us-8110.json +45 -0
  644. package/blueprints/security-secrets-management/docs/topics.md +46 -0
  645. package/blueprints/security-secrets-management/guide/security-secrets-management.md +68 -0
  646. package/fixtures/canary-manifest.json +1 -101
  647. package/guidance/build-cycle-playbook.md +2 -2
  648. package/guidance/document-model.md +1 -1
  649. package/guidance/harness-template.md +13 -0
  650. package/guidance/managed/agent-instructions-block.hash +1 -1
  651. package/guidance/managed/agent-instructions-block.md +13 -0
  652. package/package.json +18 -9
  653. package/rcf/adrs/adr-001.json +1 -1
  654. package/rcf/adrs/adr-009.json +1 -1
  655. package/rcf/build-sequence.json +1 -1
  656. package/rcf/manifest.json +2 -2
  657. package/rcf/prd.json +2 -2
  658. package/releases/releases.yaml +116 -0
  659. package/scripts/preinstall-node-check.mjs +61 -0
  660. package/src/blueprint/apply.js +62 -18
  661. package/src/blueprint/conflicts.js +8 -8
  662. package/src/blueprint/index.js +14 -1
  663. package/src/blueprint/library-loader.js +271 -0
  664. package/src/blueprint/library-registry.js +341 -0
  665. package/src/blueprint/list.js +94 -0
  666. package/src/blueprint/loader.js +26 -1
  667. package/src/blueprint/namespace.js +20 -16
  668. package/src/blueprint/shelf-resolver.js +286 -0
  669. package/src/blueprint/supersede.js +3 -2
  670. package/src/browser-verify/invariants.js +40 -0
  671. package/src/browser-verify/runner.js +2 -0
  672. package/src/cli/blueprint-library.js +419 -0
  673. package/src/cli/blueprint.js +91 -10
  674. package/src/cli/guidance.js +1 -1
  675. package/src/cli/help.js +27 -1
  676. package/src/cli/init.js +2 -0
  677. package/src/cli/version.js +673 -0
  678. package/src/cli/view.js +282 -1
  679. package/src/core/store/writer.js +64 -2
  680. package/src/server/index.js +3 -0
  681. package/src/server/routes.js +15 -1
  682. package/src/server/scope-endpoint.js +105 -0
  683. package/src/setup/agent-setup.js +28 -10
  684. package/src/view/live-client.js +253 -6
  685. package/src/view/scope.js +231 -0
  686. package/src/view/style.css +42 -0
@@ -0,0 +1,56 @@
1
+ # Security auth Keycloak blueprint (v1.0.0)
2
+
3
+ The twelfth content blueprint on the rcf-build-lite blueprint mechanism, category `security`. A Keycloak-committed sibling to `security-auth-magic-link`, `security-auth-clerk`, and `security-auth-oauth2` on the `authModel` global topic. Identity is delegated to a Keycloak realm the operator runs; the project owns the discovery client, the token verifier (JWKS or introspection per realm), the role adapter, the provider-routing seam, and the optional application session on top. Targeted at rcf-lite projects that have committed to a self-hosted Keycloak realm (or are running one already) and want the Keycloak-shaped decisions the vendor-neutral `security-auth-oauth2` sibling deliberately does not fix.
4
+
5
+ ## Apply
6
+
7
+ ```
8
+ rcf define blueprint add <path-to>/blueprints/security-auth-keycloak
9
+ ```
10
+
11
+ Phase 1 resolves local path sources only; registry and git-ref resolution is a mechanism follow-up. Apply is idempotent; `rcf define blueprint list` shows the applied entry grouped under the `security` category; `rcf define blueprint remove security-auth-keycloak` cleanly removes an unreferenced application.
12
+
13
+ Composing with `security-auth-magic-link`, `security-auth-clerk`, `security-auth-oauth2`, or any other blueprint contributing `scope: global` on `authModel` (which includes `application-spa` and `application-api-rest`) raises a `globalAdrTopic` conflict at add time. The four documented resolutions apply (adopt the incoming, keep the existing, project-level supersede ADR, or `--resolve authModel=project:<ADR-id>` on the add). See `docs/topics.md` for the deliberate-conflict statement.
14
+
15
+ ## Anatomy
16
+
17
+ | Piece | Where | What |
18
+ |---|---|---|
19
+ | Metadata | `blueprint.json` | Slug, version, category `security`, and the 36 contributions with scope/topic on the one global ADR |
20
+ | Doc set | `contributions/` | 12 REQs, 13 USs (34 ACs), 5 TACs, 6 ADRs, all schema-valid and namespaced (`security-auth-keycloak-REQ-001` prefix family; `ADR-1201-security-auth-keycloak-auth-model` suffix family) |
21
+ | Local-container bootstrap | `assets/local-container/keycloak-bootstrap.md` | Shape a project harness follows to stand up the vendor's official image; no compose file lifted from any real deployment |
22
+ | Realm-config record | `assets/realm-skeleton/realm-config-shape.md` | The plain data-record shape a project maintains per realm; placeholder secrets only |
23
+ | Verifier middleware wiring | `assets/middleware/verifier-wiring.md` | HTTP-framework-agnostic Node middleware chain wiring the mechanism's five factories |
24
+ | Provider-router seam | `assets/provider-router/router-shape.md` | The pure-function contract a project's routing decision satisfies; generic OAuth2/OIDC vocabulary; no named second issuer |
25
+ | Mock introspection responder | `assets/mock-introspection/mock-introspection-shape.md` | RFC 7662 shape the harness stands up for the introspection-mode verify path |
26
+ | Guide | `guide/security-auth-keycloak.md` | Operator-facing: when to use it, when not, promotion signals, cost honesty |
27
+ | Coordination vocabulary | `docs/topics.md` | The global topic string and the shared id-band registry |
28
+
29
+ The doc set is contributions (copied into the project tree by `rcf define blueprint add`); the guide, assets, and docs are package-resident references. Guide rendering into `rcf/knowledge/docs/blueprint-guides/` and asset ingestion are mechanism follow-ups; until they land, the working agent reads them from the applied blueprint's source path recorded in `manifest.blueprints[].source`.
30
+
31
+ ## What it contributes, and what it deliberately does not
32
+
33
+ Contributed kinds: REQ, US (with inline ACs), TAC, ADR. Adherence is expressed as ACs; the blueprint ships no test files (ratified decision 5) and no code.
34
+
35
+ No FBS contributions, as a matter of principle (ratified policy 2026-08-19): FBSs are the work of the implementing agent, not the blueprint; project constraints have to be applied at the time of creation. The blueprint contributes the WHAT (the Keycloak realm as identity source, the OIDC discovery contract, the JWKS-with-rotation-cache verification path, the RFC 7662 introspection path, the provider-routing seam, the Keycloak client-roles / realm-roles claim shape, the refresh-and-sign-out posture inherited from the realm, the session-vs-token separation, the local-first stand-up shape, the fail-safe boot postures, the runtime-verify posture with accountBound cloud smokes); the implementing agent derives the HOW-tasks (FBS) in the host project.
36
+
37
+ Deliberately not contributed: the OAuth2 authorisation-code flow controller itself (a project either draws it from the sibling `security-auth-oauth2` blueprint or authors one above this blueprint's five TACs; the Keycloak-committed decisions here bind the flow controller's provider adapter to a Keycloak realm and no more); a specific HTTP framework adapter (the middleware wiring is framework-agnostic; framework adapters are a project responsibility); a specific session-record store (opaque-handle mode injects it; in-memory is the reference default; a persistence-composed project points at a table); MFA specifics (Keycloak owns MFA at the realm surface); real realm data (a placeholder `example` realm name is the shape; no lifted config); any specific second identity provider (the provider-routing seam is generic; the blueprint does not name a second issuer, per the ratified reshape ruling).
38
+
39
+ ## The one global decision
40
+
41
+ ADR-1201-security-auth-keycloak-auth-model ships `scope: global` on topic `authModel`. This is the project's single decision on how identity is proven, where credentials live, and what the wire credential looks like. Composing with `security-auth-magic-link`, `security-auth-clerk`, `security-auth-oauth2`, `application-spa`, `application-api-rest`, or any future `security-auth-*` blueprint conflicts here by design and expects a project-level ADR resolution. The composition-precedent (SPA + REST on `errorEnvelope` and `authModel`) is the same pattern the auth-family blueprints follow.
42
+
43
+ See `docs/topics.md` for the exact strings, the expected resolutions, and the AC id band allocation (security-auth-keycloak owns US 11101-11899 with US 11101-11113 in use, ADR/TAC suffix block 1201-1299; the third blueprint to sit in the four-digit ADR/TAC suffix space after security-auth-clerk (1001-1099) and security-auth-oauth2 (1101-1199)).
44
+
45
+ ## Quality bar
46
+
47
+ Authorisation-code + PKCE (S256) as the sole flow; JWT verification via realm JWKS with a rotation cache defended by TTL and by kid-miss single-refresh; RFC 7662 introspection as the alternate verification mode selected per realm record; provider-routing seam expressed as a project-authored pure function; role extraction from Keycloak's `client-roles` or `realm-roles` claim path per record declaration; refresh rotation honours the realm's declared model (revoke-on-reuse tightened by the realm; soft rotation permitted where the operator has declared it); sign-out invalidates the project session with realm-side end-session opt-in per record; session-vs-token separation with opaque-handle sessions (default) or stateless bearer verification (opt-in) per realm; fail-safe boot posture declared per realm (strict / deferred / standby); runtime-verify against a local Keycloak container with cloud-tenant smokes marked accountBound and skipped with a stable-coded reason when credentials are unavailable. Every bar is carried by ACs in the doc set, not by this README.
48
+
49
+ ## Known mechanism-reach gaps
50
+
51
+ Three named gaps at v1.0.0. First, AC-11112-2 (the live cloud-realm smoke against a project-owned Keycloak deployment or a managed Keycloak service) is `accountBound` and depends on operator-provided cloud-realm credentials plus a redirect URI registration at the deployment's admin console; those steps sit outside the blueprint's mechanism reach. The project's ship gate reads the honest coverage: the AC is covered by a project-authored TC whose latest outcome is `skipped` with reason `KEYCLOAK_LIVE_REALM_UNREACHABLE` when credentials are absent, and `pass` when the operator has driven the smoke. The `accountBound` skip does not fail CI and does not count as coverage passed for a project auditing its cloud-realm readiness; the ship-gate operator reads the AC and drives the smoke themselves before promoting a build past staging. The local Keycloak container path (REQ-009, US-11101 through US-11104, US-11107, US-11108, US-11110, US-11111) is NOT accountBound: the vendor's official container image runs standalone under a project's harness and the mechanism verifies against it end-to-end at every runtime-verify pass. Second, every AC on every story is bound to at least one TAC that the host project must realise, and every AC's `then` clause is runtime-observable in the deployed application (redirect-inspection for the authorise URL shape, token-exchange-request inspection for the PKCE verifier presentation, response-cookie inspection for the session-cookie contract, `request.auth` shape inspection for the Principal reduction, mock-introspection response substitution for the opaque-token classes, JWKS mutation for the JWT refusal classes, session-record store inspection for refresh-token rotation, cookie-clear inspection for sign-out, `Location`-header inspection for realm-side sign-out redirect). A project that applies this blueprint and does not realise a TAC leaves an unresolved `tacIds` reference on the story that `rcf define validate` and `rcf audit coverage` refuse. Third, the flow controller itself (the state machine that mints the pending-flow record, builds the authorisation redirect, and drives the callback) is NOT contributed by this blueprint at v1.0.0: a project either composes the vendor-neutral sibling `security-auth-oauth2` (which contributes TAC-1101-security-auth-oauth2-flow-controller) and points its provider-adapter at a Keycloak realm through this blueprint's discovery client and verifier, or the project authors a project-side flow controller above this blueprint's five TACs. The two composition paths are equally valid; the blueprint documents both in the guide.
52
+
53
+ ## Composition intent (deliberate)
54
+
55
+ - Applying this blueprint on top of `security-auth-magic-link`, `security-auth-clerk`, `security-auth-oauth2`, `application-spa`, or `application-api-rest` raises a `globalAdrTopic` conflict on `authModel`. That is intended: one project has one authentication model, and the surfacing is the mechanism's promise. Resolution paths are documented on `docs/topics.md`.
56
+ - Sibling PRs open or recently merged at this pass: `blueprint/security-auth-oauth2` (band 10101-10899 US, 1101-1199 ADR/TAC). Zero id-band overlap.
@@ -0,0 +1,54 @@
1
+ # Keycloak local-container bootstrap: shape (not a compose file lift)
2
+
3
+ Shape a project stands up to satisfy REQ-009's local-first posture. The container is real Keycloak on the wire; the discovery client, the JWT verifier, and the introspection client cannot tell it apart from a cloud-hosted realm for the purpose of the state machine and the verification paths.
4
+
5
+ The blueprint does NOT ship a `docker-compose.yaml` file, a `Dockerfile`, or a container-orchestration recipe from any real deployment. The notes below name the shape a project's harness follows; the harness itself lives on the project.
6
+
7
+ ## Image
8
+
9
+ The vendor's official image is `quay.io/keycloak/keycloak`. The operator pins the currently-supported stable tag at the moment they set the harness up (the vendor's release cadence moves; the pin belongs on the project's tooling, not on this blueprint). A harness that reads the pin from a project environment file is the recommended pattern.
10
+
11
+ ## Startup command shape
12
+
13
+ Development-mode startup is what the harness invokes; the vendor documents it as `kc.sh start-dev`. The harness passes:
14
+
15
+ - `KC_HOSTNAME=127.0.0.1` (or a hostname the project's test suite reaches over)
16
+ - `KC_HTTP_ENABLED=true` (development-mode is fine over plain HTTP; production is the operator's own concern and not this asset's shape)
17
+ - `KC_BOOTSTRAP_ADMIN_USERNAME` and `KC_BOOTSTRAP_ADMIN_PASSWORD` read from a project environment file the harness controls (placeholders only; never committed)
18
+ - A published port the harness records for the `issuerBaseUrl` on the realm-config record
19
+
20
+ The container is standalone; no external database is required in development mode (Keycloak's default embedded H2 covers a scratch service).
21
+
22
+ ## Realm seed (placeholder-only)
23
+
24
+ The harness applies a realm-configuration seed either through the vendor's `kc.sh import` path (mounting a realm-export file) or through the admin REST API after startup. The seed carries:
25
+
26
+ - Realm name: `example` (a generic placeholder; the operator picks a stable name for their project)
27
+ - One client: `example-client`
28
+ - `Access Type: confidential`
29
+ - `Client authentication: on`
30
+ - `Standard flow (authorisation code): on`
31
+ - `Direct access grants: off`
32
+ - `Redirect URIs: <project-callback-url>` (the project's callback route on the test process)
33
+ - `PKCE Code Challenge Method: S256`
34
+ - `Access Token Signature Algorithm: RS256` (JWKS mode) or issued opaque (introspection mode)
35
+ - One role assignment shape:
36
+ - Client roles when `roleClaimShape: 'client-roles'` (recommended default)
37
+ - Realm roles when `roleClaimShape: 'realm-roles'`
38
+ - One or two test users (placeholder usernames and passwords; never committed)
39
+
40
+ Nothing in this seed shape names a real deployment; the operator either accepts the `example` names or renames them for their own project.
41
+
42
+ ## Wiring notes for the project
43
+
44
+ - The harness records `<issuerBaseUrl>` (the container's public URL) and passes it as the `issuerBaseUrl` field on the realm-config record.
45
+ - The realm name (`realmName` field on the record) matches the seed's realm name.
46
+ - The `clientId` and `clientSecret` on the record match the seeded client's fields; the secret comes from the admin surface after client creation and lives in an operator-controlled environment file, never in a committed record.
47
+ - A harness that tears down the container between test suites is fine and preferred; Keycloak's development-mode startup is fast enough to run per-suite when the project's suite structure warrants it.
48
+ - A harness that keeps a shared team-level container running is also fine; each project's harness applies its own seed on start.
49
+
50
+ ## Alternate stand-up paths
51
+
52
+ - A persistent scratch service the operator runs once (a system-installed Keycloak, a team-shared container, a devcontainer) is fine; the harness records the discovered endpoints and the mechanism does not care whether the realm is per-suite or persistent.
53
+ - A Kubernetes namespace with Keycloak deployed via the vendor's operator (or via a chart the operator maintains) is fine; the mechanism sees a discovery endpoint and populates the record.
54
+ - The blueprint does not commit to any of these paths; the shape above is the contract, not the tooling.
@@ -0,0 +1,93 @@
1
+ # Verifier middleware wiring: HTTP-framework-agnostic shape
2
+
3
+ A record-only shape for the middleware chain a project wires above the mechanism. Not production code; a project's own HTTP framework is what turns this into concrete request handlers.
4
+
5
+ The mechanism's public surface is three factory functions and one router:
6
+
7
+ ```
8
+ const discoveryClient = createDiscoveryClient({
9
+ realmConfig,
10
+ httpFetch,
11
+ clock,
12
+ auditSink,
13
+ retryScheduler
14
+ });
15
+
16
+ const jwtVerifier = createJwtVerifier({
17
+ discoveryClient,
18
+ httpFetch,
19
+ clock,
20
+ auditSink
21
+ });
22
+
23
+ const introspectionClient = createIntrospectionClient({
24
+ discoveryClient,
25
+ httpFetch,
26
+ clock,
27
+ auditSink
28
+ });
29
+
30
+ const providerRouter = createProviderRouter({
31
+ routeFn,
32
+ realmConfig,
33
+ auditSink
34
+ });
35
+
36
+ const roleAdapter = createRoleAdapter({
37
+ realmConfig,
38
+ auditSink
39
+ });
40
+ ```
41
+
42
+ ## Request-time chain
43
+
44
+ ```
45
+ async function verifyRequest(request) {
46
+ const decision = providerRouter.route(request);
47
+ if (decision === 'notThisIssuer') {
48
+ return { status: 'notThisIssuer' };
49
+ }
50
+ const record = realmConfig.get(decision.realmSlug);
51
+ if (record === undefined) {
52
+ return { status: 'refused', code: 'KEYCLOAK_REALM_UNKNOWN' };
53
+ }
54
+ const health = discoveryClient.health(decision.realmSlug);
55
+ if (health !== 'healthy') {
56
+ return { status: 'refused', code: 'KEYCLOAK_REALM_UNAVAILABLE' };
57
+ }
58
+ const token = extractToken(request, record);
59
+ if (token === null) {
60
+ return { status: 'refused', code: 'KEYCLOAK_TOKEN_MISSING' };
61
+ }
62
+ const verified =
63
+ decision.verificationMode === 'jwks'
64
+ ? await jwtVerifier.verify(decision.realmSlug, token)
65
+ : await introspectionClient.verify(decision.realmSlug, token);
66
+ if (verified.ok === false) {
67
+ return { status: 'refused', code: verified.code };
68
+ }
69
+ const principal = roleAdapter.principalFrom(decision.realmSlug, verified.claims);
70
+ if (principal.ok === false) {
71
+ return { status: 'refused', code: principal.code };
72
+ }
73
+ request.auth = principal.reduced;
74
+ return { status: 'verified' };
75
+ }
76
+ ```
77
+
78
+ `extractToken(request, record)` reads the bearer source per `sessionMode`: opaque-handle mode reads the session cookie and swaps it for the stored access token from the session record; stateless mode reads directly from the `bearerSource` field.
79
+
80
+ ## Wiring a specific framework
81
+
82
+ The mechanism does not ship framework adapters at v1; a project on Express, Fastify, Hono, or the vendor's Workers runtime writes a one-file adapter that calls `verifyRequest` and produces the framework's response shape for the refusal classes above. Every framework adapter is a thin wrapper; the state machine is what this file names.
83
+
84
+ ## Sign-in and sign-out routes
85
+
86
+ The sign-in initiation and callback routes are the flow controller's territory (a project either authors them above this blueprint's five TACs, or draws them from the sibling `security-auth-oauth2` blueprint's flow controller and adapts the state machine to the Keycloak record). The sign-out route is one line: invalidate the session handle if opaque-handle mode; clear the cookie; consult the realm record's `providerLogout` field to decide whether to return a 302 to `end_session_endpoint`.
87
+
88
+ ## What this file does NOT commit
89
+
90
+ - No specific HTTP framework
91
+ - No specific session-record store implementation
92
+ - No specific httpFetch (the platform's `fetch` is the reference default; a project's harness substitutes in tests)
93
+ - No specific audit sink; a project points at its own event pipeline
@@ -0,0 +1,62 @@
1
+ # Mock introspection responder: shape
2
+
3
+ A local stub responder a project stands up to satisfy US-11105's runtime-verify posture for `verificationMode: 'introspection'` without running a second Keycloak realm configured for opaque tokens.
4
+
5
+ The mock is real RFC 7662 on the wire: same request shape, same response shape, same content-type. The introspection client cannot tell it apart from a real Keycloak introspection endpoint for the purpose of the state machine and the response handling.
6
+
7
+ A project may implement the mock in-process (a small Node HTTP server the test harness starts and tears down), against an existing library, or as a persistent scratch service. The shape below is what the harness expects, not what a specific library commits to.
8
+
9
+ ## Introspection endpoint (`POST /introspect`)
10
+
11
+ Accepts:
12
+
13
+ ```
14
+ Content-Type: application/x-www-form-urlencoded
15
+ Authorization: Basic <base64(clientId:clientSecret)>
16
+
17
+ token=<opaque-token>
18
+ ```
19
+
20
+ Returns (per RFC 7662):
21
+
22
+ ```
23
+ Content-Type: application/json
24
+
25
+ {
26
+ "active": true,
27
+ "sub": "<opaque-subject-id>",
28
+ "aud": "<clientId>",
29
+ "iss": "<issuer>",
30
+ "exp": <epoch-seconds>,
31
+ "scope": "openid profile email",
32
+ "resource_access": {
33
+ "<clientId>": {
34
+ "roles": ["admin", "editor"]
35
+ }
36
+ },
37
+ "realm_access": {
38
+ "roles": []
39
+ }
40
+ }
41
+ ```
42
+
43
+ ## Test-controllable knobs (per-token)
44
+
45
+ - Return `active: false` on demand (for AC-11105-2)
46
+ - Return HTTP 503 on demand (for AC-11105-3)
47
+ - Return HTTP 400 on demand (for endpoint-error edge cases)
48
+ - Return an `active: true` response with a claim record shaped for either `client-roles` or `realm-roles` (for US-11107)
49
+ - Return an `active: true` response with a malformed `roles` field (for AC-11107-3)
50
+
51
+ ## Wiring notes
52
+
53
+ - The mock listens on `127.0.0.1:<random-port>` and the harness passes the port to the realm-config record's `introspection_endpoint` (either directly or through a discovery-response substitution).
54
+ - The mock's `clientSecret` is a placeholder the harness controls; the real realm's secret never appears here.
55
+ - A per-test-suite instance is fine and preferred; state does not have to persist.
56
+ - A project may substitute a second local Keycloak realm configured for opaque tokens if it prefers a real Keycloak surface; the mechanism cannot tell the difference and does not care.
57
+
58
+ ## What this asset does NOT commit
59
+
60
+ - No library or package version. The shape is the contract; the implementation is a project responsibility.
61
+ - No specific `sub` value, no specific role vocabulary, no specific issuer string. The examples above are placeholders.
62
+ - No real `clientId` or `clientSecret`. The mock trusts whatever basic-auth pair the harness gives it, or refuses per the harness's test-driven behaviour.
@@ -0,0 +1,71 @@
1
+ # Provider router: seam shape
2
+
3
+ Generic-vocabulary shape a project's own middleware invokes to answer one question: for THIS request, which realm record is authoritative (or does the routing hand off entirely)?
4
+
5
+ The blueprint stays Keycloak-committed. This asset describes the SHAPE of the routing function; it does NOT name any specific second issuer, any specific request feature, or any specific deployment topology.
6
+
7
+ ## The pure function
8
+
9
+ ```
10
+ type RouteDecision =
11
+ | { realmSlug: string, verificationMode: 'jwks' | 'introspection' }
12
+ | 'notThisIssuer';
13
+
14
+ type RouteFn = (request: RequestLike) => RouteDecision;
15
+ ```
16
+
17
+ `RequestLike` is what the project's HTTP framework exposes at the middleware boundary. The blueprint does not commit to a specific shape (Express's `req`, Fastify's `request`, Hono's `c.req`, Workers' `Request`); the routeFn adapts to whatever the project's framework provides.
18
+
19
+ ## Single-realm deployment
20
+
21
+ ```
22
+ const routeFn = () => ({ realmSlug: 'r1', verificationMode: 'jwks' });
23
+ ```
24
+
25
+ The reference wiring includes this constant-realmSlug default for the common single-realm case. The overhead is one function call per request and one config-record lookup; the payoff is that the same seam exists in every deployment shape, so upgrading from single-realm to multi-realm is a routeFn swap, not a code rewrite.
26
+
27
+ ## Multi-realm deployment (two Keycloak realms)
28
+
29
+ ```
30
+ const routeFn = (request) => {
31
+ const marker = readMarker(request); // project-specific: header, path prefix, claim, or other
32
+ if (marker === undefined) {
33
+ return { realmSlug: 'r1', verificationMode: 'jwks' }; // project's declared default
34
+ }
35
+ return { realmSlug: marker, verificationMode: 'jwks' };
36
+ };
37
+ ```
38
+
39
+ The MARKER is the project's own concern. The blueprint refuses to name it: a project might use a header, a request-path prefix, a preflight claim, a tenant slug from a subdomain, or something else entirely. The routeFn inspects the request and picks; the mechanism honours the pick.
40
+
41
+ ## Deployment where routing hands off
42
+
43
+ ```
44
+ const routeFn = (request) => {
45
+ if (isThisMechanismsResponsibility(request)) {
46
+ return { realmSlug: 'r1', verificationMode: 'jwks' };
47
+ }
48
+ return 'notThisIssuer';
49
+ };
50
+ ```
51
+
52
+ A project whose middleware chain also verifies tokens from another OAuth2/OIDC issuer above this blueprint's mechanism reach returns the sentinel `notThisIssuer` when the request is not for this mechanism to verify. The caller (the project's own middleware) is responsible for what happens next; the mechanism does not know and does not care.
53
+
54
+ The blueprint does NOT contribute an ADR that fixes what a project puts in `isThisMechanismsResponsibility`. That is the project-level decision the ratified reshape ruling reserves for the project. The seam is the mechanism's contribution; the routing policy is the project's.
55
+
56
+ ## Why the sentinel exists
57
+
58
+ Without it, the mechanism would have to guess: either refuse the request (which would break a deployment where a token from another issuer is expected on that path) or trust it (which would break the security posture). The sentinel makes the hand-off explicit and paper-trailed; the routeFn is where a reviewer looks to see which requests this mechanism owns.
59
+
60
+ ## What the routeFn must NOT do
61
+
62
+ - Perform any HTTP request. The routeFn is pure; network I/O belongs on the verifiers, not the router.
63
+ - Read or mutate the session-record store. That is the session-bridge's territory.
64
+ - Name a specific second issuer inside the shipped mechanism. A project that has one names it on a project-level ADR whose scope is the project, not the blueprint.
65
+
66
+ ## What the routeFn MAY do
67
+
68
+ - Read request fields (headers, path, method, cookies, query parameters).
69
+ - Consult a project-authored in-process lookup (a tenant registry the project maintains, a rules table the operator loaded at boot).
70
+ - Return a stable realmSlug per request feature that maps to a realm record.
71
+ - Return the sentinel when the project's middleware chain owns the decision above this mechanism.
@@ -0,0 +1,55 @@
1
+ # Realm-config record: shape
2
+
3
+ The plain data record a project maintains per configured realm. TAC-1201 validates the shape at boot; TAC-1202, TAC-1203, and TAC-1205 read from it on the hot path.
4
+
5
+ All fields below are declared with placeholder or example values; a project populates them from a realm the operator runs. The `clientSecret` is server-only and NEVER committed - the record reads it from `security-secrets-management` (when composed) or from the process environment at boot.
6
+
7
+ ```
8
+ {
9
+ realmSlug: 'r1',
10
+ issuerBaseUrl: 'http://127.0.0.1:8080',
11
+ realmName: 'example',
12
+ clientId: 'example-client',
13
+ clientSecret: '<PLACEHOLDER_CLIENT_SECRET>',
14
+ verificationMode: 'jwks',
15
+ roleClaimShape: 'client-roles',
16
+ scopes: ['openid', 'profile', 'email'],
17
+ redirectUri: '<PLACEHOLDER_PROJECT_CALLBACK_URL>',
18
+ providerLogout: 'none',
19
+ sessionMode: 'opaque-handle',
20
+ bearerSource: null,
21
+ jwksCacheTtlSeconds: 900,
22
+ introspectionCacheTtlSeconds: 0,
23
+ bootPosture: 'strict',
24
+ deferredRetryCapSeconds: 300,
25
+ discoveryRefreshSeconds: 3600,
26
+ enabled: true
27
+ }
28
+ ```
29
+
30
+ ## Field notes
31
+
32
+ - `realmSlug` is a project-local stable slug; it appears in `principalId` derivations and in every audit event. Short and lowercase; do not use the operator's realm name here (that is `realmName`).
33
+ - `issuerBaseUrl` is the URL prefix Keycloak reports as the realm's issuer, up to but not including `/realms/<realm>`. The discovery client appends `/realms/<realmName>/.well-known/openid-configuration`.
34
+ - `verificationMode` is `'jwks'` (default) or `'introspection'`. See ADR-1202.
35
+ - `roleClaimShape` is `'client-roles'` (reads `resource_access.<clientId>.roles`) or `'realm-roles'` (reads `realm_access.roles`). See REQ-006 and TAC-1205.
36
+ - `providerLogout` is `'none'` (default; sign-out clears the project session only) or `'redirect'` (sign-out returns a 302 to the realm's `end_session_endpoint`). A record with `'redirect'` on a realm whose discovery lacks `end_session_endpoint` refuses boot. See REQ-010 and ADR-1206.
37
+ - `sessionMode` is `'opaque-handle'` (the default; server-side session record + opaque cookie) or `'stateless'` (per-request bearer verification, no session record). See ADR-1204.
38
+ - `bearerSource` is required when `sessionMode='stateless'`: `'authorization-header'` or `'cookie:<name>'`.
39
+ - `jwksCacheTtlSeconds` is 900 by default; the record may raise (up to 86400) or lower (down to 60). See ADR-1205.
40
+ - `introspectionCacheTtlSeconds` is 0 by default (no cache); the record may raise for high-issuance realms. See TAC-1203.
41
+ - `bootPosture` is `'strict'` (default), `'deferred'`, or `'standby'`. See REQ-011 and TAC-1201.
42
+ - `discoveryRefreshSeconds` is the background refresh cadence (default 3600); a failure at refresh logs a warning and does not flip a healthy realm to unhealthy.
43
+ - `enabled: false` marks the record as configured but not routed to; the provider-router skips disabled records.
44
+
45
+ ## Multiple realms
46
+
47
+ A project may declare N realm records. Each carries its own `realmSlug` and its own set of the fields above. The provider-router (TAC-1204) uses a project-authored `routeFn` to decide which realmSlug a request routes to. A project with only one realm passes a constant `routeFn`; the reference wiring ships that constant.
48
+
49
+ ## Rejection classes at boot
50
+
51
+ - Missing required field: `KEYCLOAK_RECORD_INCOMPLETE` naming the field.
52
+ - `verificationMode='introspection'` on a discovery without `introspection_endpoint`: `KEYCLOAK_DISCOVERY_MISSING_ENDPOINT`.
53
+ - `providerLogout='redirect'` on a discovery without `end_session_endpoint`: `KEYCLOAK_LOGOUT_NOT_DECLARED`.
54
+ - `sessionMode='stateless'` without `bearerSource`: `KEYCLOAK_BEARER_SOURCE_MISSING`.
55
+ - `jwksCacheTtlSeconds` outside `[60, 86400]`: `KEYCLOAK_JWKS_TTL_OUT_OF_RANGE`.
@@ -0,0 +1,49 @@
1
+ {
2
+ "slug": "security-auth-keycloak",
3
+ "version": "1.0.0",
4
+ "category": "security",
5
+ "contributions": [
6
+ { "id": "security-auth-keycloak-REQ-001", "kind": "req", "path": "requirements/security-auth-keycloak-req-001.json" },
7
+ { "id": "security-auth-keycloak-REQ-002", "kind": "req", "path": "requirements/security-auth-keycloak-req-002.json" },
8
+ { "id": "security-auth-keycloak-REQ-003", "kind": "req", "path": "requirements/security-auth-keycloak-req-003.json" },
9
+ { "id": "security-auth-keycloak-REQ-004", "kind": "req", "path": "requirements/security-auth-keycloak-req-004.json" },
10
+ { "id": "security-auth-keycloak-REQ-005", "kind": "req", "path": "requirements/security-auth-keycloak-req-005.json" },
11
+ { "id": "security-auth-keycloak-REQ-006", "kind": "req", "path": "requirements/security-auth-keycloak-req-006.json" },
12
+ { "id": "security-auth-keycloak-REQ-007", "kind": "req", "path": "requirements/security-auth-keycloak-req-007.json" },
13
+ { "id": "security-auth-keycloak-REQ-008", "kind": "req", "path": "requirements/security-auth-keycloak-req-008.json" },
14
+ { "id": "security-auth-keycloak-REQ-009", "kind": "req", "path": "requirements/security-auth-keycloak-req-009.json" },
15
+ { "id": "security-auth-keycloak-REQ-010", "kind": "req", "path": "requirements/security-auth-keycloak-req-010.json" },
16
+ { "id": "security-auth-keycloak-REQ-011", "kind": "req", "path": "requirements/security-auth-keycloak-req-011.json" },
17
+ { "id": "security-auth-keycloak-REQ-012", "kind": "req", "path": "requirements/security-auth-keycloak-req-012.json" },
18
+ { "id": "security-auth-keycloak-US-11101", "kind": "us", "path": "user-stories/security-auth-keycloak-us-11101.json" },
19
+ { "id": "security-auth-keycloak-US-11102", "kind": "us", "path": "user-stories/security-auth-keycloak-us-11102.json" },
20
+ { "id": "security-auth-keycloak-US-11103", "kind": "us", "path": "user-stories/security-auth-keycloak-us-11103.json" },
21
+ { "id": "security-auth-keycloak-US-11104", "kind": "us", "path": "user-stories/security-auth-keycloak-us-11104.json" },
22
+ { "id": "security-auth-keycloak-US-11105", "kind": "us", "path": "user-stories/security-auth-keycloak-us-11105.json" },
23
+ { "id": "security-auth-keycloak-US-11106", "kind": "us", "path": "user-stories/security-auth-keycloak-us-11106.json" },
24
+ { "id": "security-auth-keycloak-US-11107", "kind": "us", "path": "user-stories/security-auth-keycloak-us-11107.json" },
25
+ { "id": "security-auth-keycloak-US-11108", "kind": "us", "path": "user-stories/security-auth-keycloak-us-11108.json" },
26
+ { "id": "security-auth-keycloak-US-11109", "kind": "us", "path": "user-stories/security-auth-keycloak-us-11109.json" },
27
+ { "id": "security-auth-keycloak-US-11110", "kind": "us", "path": "user-stories/security-auth-keycloak-us-11110.json" },
28
+ { "id": "security-auth-keycloak-US-11111", "kind": "us", "path": "user-stories/security-auth-keycloak-us-11111.json" },
29
+ { "id": "security-auth-keycloak-US-11112", "kind": "us", "path": "user-stories/security-auth-keycloak-us-11112.json" },
30
+ { "id": "security-auth-keycloak-US-11113", "kind": "us", "path": "user-stories/security-auth-keycloak-us-11113.json" },
31
+ { "id": "TAC-1201-security-auth-keycloak-discovery-client", "kind": "tac", "path": "tacs/tac-1201-security-auth-keycloak-discovery-client.json" },
32
+ { "id": "TAC-1202-security-auth-keycloak-jwt-verifier", "kind": "tac", "path": "tacs/tac-1202-security-auth-keycloak-jwt-verifier.json" },
33
+ { "id": "TAC-1203-security-auth-keycloak-introspection-client", "kind": "tac", "path": "tacs/tac-1203-security-auth-keycloak-introspection-client.json" },
34
+ { "id": "TAC-1204-security-auth-keycloak-provider-router", "kind": "tac", "path": "tacs/tac-1204-security-auth-keycloak-provider-router.json" },
35
+ { "id": "TAC-1205-security-auth-keycloak-role-adapter", "kind": "tac", "path": "tacs/tac-1205-security-auth-keycloak-role-adapter.json" },
36
+ {
37
+ "id": "ADR-1201-security-auth-keycloak-auth-model",
38
+ "kind": "adr",
39
+ "path": "adrs/adr-1201-security-auth-keycloak-auth-model.json",
40
+ "scope": "global",
41
+ "topic": "authModel"
42
+ },
43
+ { "id": "ADR-1202-security-auth-keycloak-verification-mode-choice", "kind": "adr", "path": "adrs/adr-1202-security-auth-keycloak-verification-mode-choice.json" },
44
+ { "id": "ADR-1203-security-auth-keycloak-provider-routing-seam", "kind": "adr", "path": "adrs/adr-1203-security-auth-keycloak-provider-routing-seam.json" },
45
+ { "id": "ADR-1204-security-auth-keycloak-session-vs-token-contract", "kind": "adr", "path": "adrs/adr-1204-security-auth-keycloak-session-vs-token-contract.json" },
46
+ { "id": "ADR-1205-security-auth-keycloak-jwks-rotation-cache-lifetime", "kind": "adr", "path": "adrs/adr-1205-security-auth-keycloak-jwks-rotation-cache-lifetime.json" },
47
+ { "id": "ADR-1206-security-auth-keycloak-refresh-and-sign-out-posture", "kind": "adr", "path": "adrs/adr-1206-security-auth-keycloak-refresh-and-sign-out-posture.json" }
48
+ ]
49
+ }
@@ -0,0 +1,35 @@
1
+ {
2
+ "adrId": "ADR-1201-security-auth-keycloak-auth-model",
3
+ "prdId": "PRD-001",
4
+ "tadId": "TAD-001",
5
+ "version": "1.0.0",
6
+ "status": "accepted",
7
+ "title": "A Keycloak realm is the project's identity source; federation is OIDC authorisation-code + PKCE with per-realm verification mode",
8
+ "context": "A project has one authentication model; the client tier, the server tier, and every operator surface must reason against it. The security-auth-keycloak blueprint contributes a vendor-committed shape of that model: identity, sign-in surface, credential storage, MFA, and account recovery live at a Keycloak realm the operator runs; the project owns the discovery client, the token verifier (JWKS or introspection depending on the realm's client configuration), the role adapter, the provider-router seam, and the optional application session on top. Every other auth-family blueprint (security-auth-magic-link, security-auth-clerk, security-auth-oauth2) contributes its own decision on this topic; blueprint composition surfaces the pairing at add time for the operator to reconcile into one project-level model. That surfacing is intended.",
9
+ "decision": "The project's authentication model is delegated identity to a Keycloak realm the operator runs, federated through OAuth2 authorisation-code with PKCE (RFC 7636, S256), with the realm's OIDC endpoints resolved through discovery (REQ-002). Every access token the project receives from the realm is verified either through JWKS (default, REQ-003) or through the RFC 7662 introspection endpoint (opt-in per realm, REQ-004); the verification mode is a per-realm-record field. Roles are read from Keycloak's client-roles or realm-roles claim path per the realm's configuration (REQ-006); the project's own handlers see only the reduced Principal. The application session posture on top of the verified token stream is either an opaque-handle session cookie (the default, mirroring the sibling blueprints' opaque-handle contract) or stateless bearer verification per request; the operator picks one per realm record (REQ-008). Refresh follows the realm's rotation model (REQ-007). Sign-out invalidates the project session; realm-side sign-out is a project option (REQ-010). Fail-safe boot follows a declared posture (REQ-011). Runtime-verify binds against a local Keycloak container; live cloud-tenant smokes are accountBound (REQ-012). The blueprint contributes a provider-routing seam (REQ-005) that a project's own middleware may use to route requests to one of several issuers; the seam is described in generic OAuth2/OIDC vocabulary and does not itself commit the blueprint to any specific second issuer.",
10
+ "consequences": "The project owns the discovery client, the token verifier, the role adapter, the session-bridge (opaque-handle mode) or the bearer verifier (stateless mode), the provider-router seam, and the optional local-container harness for runtime-verify; the realm owns the sign-in surface, the credential storage, MFA, account recovery, refresh-token issuance policy, role assignments, and the whole admin console. A realm swap is a discovery-record refresh plus (if the client configuration changed) a re-choice of `verificationMode`; the project's code path does not change. Composing with another auth-family blueprint conflicts on this topic by design; the expected resolution is one project-level ADR that fixes the identity surface and the credential shape for the whole project. The local-container runtime-verify posture makes CI honest without demanding cloud-realm credentials; a project that has a cloud realm wires it on top and the accountBound smokes light up. Every path that produces or consumes a session record (opaque-handle mode) or that reads a bearer token (stateless mode) flows through one narrow set of modules the ship gate compels.",
11
+ "alternativesConsidered": [
12
+ {
13
+ "name": "Vendor-neutral OAuth2 authorisation-code + PKCE (security-auth-oauth2)",
14
+ "summary": "The sibling blueprint's model: keep the flow (authorisation-code + PKCE) but do not commit to a vendor; let the project drop in any conforming IdP through a fixed provider-abstraction record.",
15
+ "reasonNotChosen": "Right choice for projects that are not committed to a single vendor. This blueprint is for projects that have committed to Keycloak: they want the Keycloak-shaped decisions (JWKS vs introspection, client-roles vs realm-roles, local-container stand-up, RP-initiated logout through the realm's end_session_endpoint) fixed at the mechanism layer so the project code path can name a Keycloak realm rather than an abstract provider record."
16
+ },
17
+ {
18
+ "name": "Hosted identity vendor with vendor-committed shape (security-auth-clerk)",
19
+ "summary": "The Clerk sibling: Clerk hosts the sign-in surface, the credential storage, MFA, account recovery; the project runs a middleware boundary against Clerk's session-verification API.",
20
+ "reasonNotChosen": "Valid for projects that want a hosted-identity fast lane. This blueprint targets the operator who wants self-hosted control over the realm and the admin surface, or who has an existing Keycloak deployment they cannot displace. The Clerk lane trades vendor commitment for less operator work; the Keycloak lane trades operator work for full self-hosted control."
21
+ },
22
+ {
23
+ "name": "Passwordless magic-link with server-issued opaque cookie sessions (security-auth-magic-link)",
24
+ "summary": "The magic-link sibling's model: mint a single-use token on POST /login, deliver by email, verify on GET /login/verify, issue an opaque-handle session cookie.",
25
+ "reasonNotChosen": "Valid for projects with no third-party identity dependency and the willingness to own the whole authentication surface in-house. This blueprint delegates that surface entirely to the realm; the trade against magic-link is running a Keycloak realm rather than an in-process principal registry."
26
+ },
27
+ {
28
+ "name": "Hand-wire the Keycloak flow inside the project without a mechanism-level record",
29
+ "summary": "Keep the Keycloak URLs, client id, secret, and JWKS knowledge inline in project code; no discovery, no per-realm record, no injected verifier.",
30
+ "reasonNotChosen": "Cheap on day one and expensive on day thirty: the realm URL layout changes, the client configuration changes to opaque tokens, the operator introduces a second realm, or the deployment moves to a different hostname. Every one of those is a code edit rather than a record refresh; the injected verifier + discovery record shape pays back the abstraction cost by the second such change."
31
+ }
32
+ ],
33
+ "createdAt": "2026-08-31T00:00:00Z",
34
+ "updatedAt": "2026-08-31T00:00:00Z"
35
+ }
@@ -0,0 +1,30 @@
1
+ {
2
+ "adrId": "ADR-1202-security-auth-keycloak-verification-mode-choice",
3
+ "prdId": "PRD-001",
4
+ "tadId": "TAD-001",
5
+ "version": "1.0.0",
6
+ "status": "accepted",
7
+ "title": "Verification mode is a per-realm-record choice between JWKS (default) and RFC 7662 introspection",
8
+ "context": "Keycloak clients issue either JWT access tokens (verifiable off-line against the realm's JWKS) or opaque access tokens (verifiable only through the RFC 7662 introspection endpoint). The choice is made at the Keycloak client configuration layer (Access Token Signature vs Bearer-only clients using opaque handles) and each has legitimate operational reasons. A blueprint that fixes one mode fights half the deployments. A blueprint that lets a project mix modes at random inside one realm record blurs the mechanism.",
9
+ "decision": "The realm record carries a `verificationMode` field with two legal values: `jwks` (the default) and `introspection`. The verifier reads the field once per verification and dispatches to the JWT verifier (TAC-1202) or the introspection client (TAC-1203) accordingly. A single realm record carries a single mode; a project whose realm has both kinds of clients declares one realm record per client and routes through the provider-router seam (REQ-005). The default is JWKS because JWKS is cheap on the hot path and matches the more common Keycloak client configuration; introspection is opt-in per record.",
10
+ "consequences": "The verifier stays single-branched inside one realm record. The role adapter (TAC-1205) reads roles from the verified claims in both modes (the introspection response body is claim-shaped identically to the id_token payload for role-carrying paths). The operator's mode choice is legible on the record and does not require a code path change to swap; a realm reconfigured from JWT to opaque tokens is a `verificationMode` field flip on the record plus a discovery re-fetch (introspection_endpoint appears on discovery in both modes but its use only matters in introspection mode). Runtime-verify covers both modes; the JWKS path binds against a real local Keycloak container and the introspection path binds against a local stub responder (or a second local realm configured for opaque tokens, per project preference).",
11
+ "alternativesConsidered": [
12
+ {
13
+ "name": "JWKS only (fix the mode at the mechanism layer)",
14
+ "summary": "Refuse to support introspection at all; every client must be configured to issue JWTs.",
15
+ "reasonNotChosen": "Excludes deployments that legitimately prefer opaque tokens (some regulated environments require server-side revocation reflection with no JWT-in-flight window). Fixing a mode at the mechanism boundary is exactly the vendor-lock this blueprint is designed to accept for Keycloak specifically, not for token shape."
16
+ },
17
+ {
18
+ "name": "Introspection only (fix the mode at the mechanism layer)",
19
+ "summary": "Every access token is verified through the introspection endpoint on every request.",
20
+ "reasonNotChosen": "Trades a documented performance property for one policy uniformity. Introspection is one HTTP round-trip per verification against the realm; the hot-path cost is unacceptable on any deployment where the JWKS-cached path would satisfy the operator's revocation posture."
21
+ },
22
+ {
23
+ "name": "Auto-detect the mode from the token shape at first receipt",
24
+ "summary": "Peek at the token; if it parses as a JWT with valid header, run JWKS; otherwise run introspection.",
25
+ "reasonNotChosen": "The mode is not the token's decision to make; it is the realm operator's. Auto-detect makes the mechanism reason about the operator's realm configuration in code rather than on the record, and a realm reconfigured mid-deployment would flip modes without a paper trail. Naming the choice on the record makes it observable and reviewable."
26
+ }
27
+ ],
28
+ "createdAt": "2026-08-31T00:00:00Z",
29
+ "updatedAt": "2026-08-31T00:00:00Z"
30
+ }
@@ -0,0 +1,30 @@
1
+ {
2
+ "adrId": "ADR-1203-security-auth-keycloak-provider-routing-seam",
3
+ "prdId": "PRD-001",
4
+ "tadId": "TAD-001",
5
+ "version": "1.0.0",
6
+ "status": "accepted",
7
+ "title": "A provider-routing seam is contributed at one named point in the request chain; the seam is described in generic OAuth2/OIDC vocabulary and does not commit to any second issuer",
8
+ "context": "A project may sit in a deployment where a receiving system's request stream carries tokens issued by more than one server. Two Keycloak realms is one shape; a Keycloak realm alongside a project-authored second-issuer path (a corporate OIDC provider the operator declares separately, a second Keycloak realm on a different hostname, an internal service-to-service issuer) is another. The blueprint stays vendor-committed to Keycloak; it does not know, and refuses to encode, what the second issuer is. What the blueprint does know is that a deployment with more than one issuer needs the routing decision made in exactly one legible place, not scattered across handlers where the ship gate cannot see it.",
9
+ "decision": "The blueprint contributes TAC-1204, the provider-router, as the seam a project's own middleware invokes on every authenticated request. The seam's contract is a pure function: `route(request) -> { realmSlug, verificationMode } | notThisIssuer`. A project with only Keycloak configured wires the seam to a constant realmSlug and the mechanism is single-branched. A project with two Keycloak realms wires the seam to inspect a request feature (a header the project's middleware layer already reads, a request-path prefix the project owns, a preflight claim the project extracts elsewhere) and picks the realmSlug. A project with Keycloak plus a non-Keycloak issuer wires the seam to return `notThisIssuer` when the routing decision hands off to a middleware layer above this blueprint's mechanism reach; the middleware layer above is the project's own concern, not the blueprint's. The blueprint refuses to name the header, the path, the claim, or the second issuer; the ratified reshape ruling forbids naming a specific dual-provider deployment shape, and the seam contract respects that.",
10
+ "consequences": "A project that has one Keycloak realm pays zero cost for the seam: the wiring is a constant. A project that has two Keycloak realms wires the routing once and every request passes through it observably. A project that has Keycloak alongside another issuer has one named point where the choice is made, which is a paper-trailed decision the ship gate can see. The trade against a hard-coded assumption (only Keycloak, only one realm, always JWKS mode) is one function call on the request path; that cost is trivial and the observability payoff scales with deployment complexity. The blueprint never names a second issuer; a project that has one owns that decision on a project-level ADR whose `related-reqs` cites this ADR.",
11
+ "alternativesConsidered": [
12
+ {
13
+ "name": "Refuse to contribute any routing seam; assume Keycloak is the only issuer forever",
14
+ "summary": "The mechanism reads every access token against the single configured realm; a request carrying a token from a different issuer refuses uniformly.",
15
+ "reasonNotChosen": "Bakes an assumption into the mechanism that the ratified reshape ruling names as the exact deployment shape the blueprint must be aware of. A project with a second issuer would either hand-wire the choice above the mechanism (invisible) or push it into every handler (unmaintainable). The seam is cheap and makes the decision legible."
16
+ },
17
+ {
18
+ "name": "Name a specific second-issuer integration in the mechanism (e.g., `providerLayer: 'keycloak' | 'other'`)",
19
+ "summary": "Ship an ADR (and the router TAC) that names the second issuer's shape.",
20
+ "reasonNotChosen": "Fights the ratified reshape ruling. The candidate that minted this blueprint originally proposed naming a specific dual-provider deployment, and the ruling stripped that; the seam stays in vendor-neutral OAuth2/OIDC vocabulary. A project that has a second issuer names it on its own ADR, not on the blueprint's."
21
+ },
22
+ {
23
+ "name": "Publish the seam as a per-issuer array and let the project fill it with N records",
24
+ "summary": "The blueprint declares a `configuredIssuers: []` array; each record is a full realm-record (or a similar shape); the router iterates.",
25
+ "reasonNotChosen": "Turns the seam from a decision point into a data structure; the mechanism ends up owning the routing algorithm as well as the data, which is exactly the responsibility the ADR is trying to keep on the project side. The pure-function contract keeps the algorithm the project's concern."
26
+ }
27
+ ],
28
+ "createdAt": "2026-08-31T00:00:00Z",
29
+ "updatedAt": "2026-08-31T00:00:00Z"
30
+ }
@@ -0,0 +1,25 @@
1
+ {
2
+ "adrId": "ADR-1204-security-auth-keycloak-session-vs-token-contract",
3
+ "prdId": "PRD-001",
4
+ "tadId": "TAD-001",
5
+ "version": "1.0.0",
6
+ "status": "accepted",
7
+ "title": "Keycloak owns tokens; the project chooses opaque-handle session or stateless bearer per realm record",
8
+ "context": "Keycloak's ownership of the token stream is not negotiable within this blueprint's vendor commitment; the realm mints access, id, and refresh tokens and the project verifies them. What the project can choose is the shape of any application session it layers on top. The vendor-neutral sibling committed to opaque-handle sessions uniformly because it could not rely on the underlying provider for revocation; a Keycloak-committed blueprint has the realm's revocation clock available and can honestly support a stateless posture where the operator prefers it.",
9
+ "decision": "The realm record carries a `sessionMode` field with two legal values: `opaque-handle` (the default) and `stateless`. Under `opaque-handle`, the session-bridge issues an opaque-handle cookie (`Secure`, `HttpOnly`, `SameSite=Lax`); the server-side session record stores the Keycloak-minted access token, id_token, and (if issued) refresh token keyed by the handle; the browser never holds a provider-minted token; the reduced Principal is what handlers read from `request.auth`. Under `stateless`, no server-side session record is kept; every request re-verifies the access token from a bearer source the operator declares on the record (`bearerSource: 'authorization-header' | 'cookie:<name>'`); the reduced Principal is derived per request from the verified token and no session cookie is issued by the mechanism (a project may still issue its own out-of-band session for unrelated reasons, but the auth mechanism does not). Provider tokens are never exposed on `request.auth` in either mode; only the reduced Principal (`principalId`, `provider`, `email?`, `roles[]`, `organisationIds[]`) crosses outward.",
10
+ "consequences": "The reference wiring is opaque-handle: it works out of the box on any Node HTTP framework, matches the sibling blueprints' pattern, and gives the project cheap sign-out (one delete on the session record). The stateless posture matches deployments where the operator has committed to bearer-per-request verification (a service tier, a public API surface behind an API gateway that itself terminates the browser session, a strict-no-cookie environment). Naming the mode on the record makes the trade a paper-trailed decision. The two modes are not composable per realm record; a project that needs both patterns on different routes declares two realm records (potentially against the same realm) with distinct `sessionMode` values and routes through the provider-router seam.",
11
+ "alternativesConsidered": [
12
+ {
13
+ "name": "Opaque-handle only (mirror the sibling blueprints uniformly)",
14
+ "summary": "Every session is server-side; no stateless posture.",
15
+ "reasonNotChosen": "Fights the operational reason a project might choose Keycloak in the first place. A deployment on a stateless service tier that wants Keycloak-issued JWTs verified per request and no cookie shape is a legitimate posture; refusing it in the mechanism would drive that project to hand-wire the verification outside the blueprint and lose the ship-gate observability."
16
+ },
17
+ {
18
+ "name": "Stateless only (JWT in cookie, browser holds the JWT)",
19
+ "summary": "Every request carries the Keycloak-minted JWT in a cookie; no server-side session record.",
20
+ "reasonNotChosen": "Leaks the provider token surface into every browser side-channel; a compromised cookie is a lifted Keycloak token whose only revocation clock is the realm's expiry timer. Opaque-handle is the safer default for the common small-project deployment shape."
21
+ }
22
+ ],
23
+ "createdAt": "2026-08-31T00:00:00Z",
24
+ "updatedAt": "2026-08-31T00:00:00Z"
25
+ }