@jantstack/adonis-authz 1.1.0 → 2.4.0-alpha.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (236) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +837 -51
  3. package/build/commands/authz_catalog_diff.d.ts +28 -0
  4. package/build/commands/authz_catalog_diff.d.ts.map +1 -0
  5. package/build/commands/authz_catalog_diff.js +67 -0
  6. package/build/commands/authz_catalog_diff.js.map +1 -0
  7. package/build/commands/authz_catalog_prune_orphans.d.ts +78 -0
  8. package/build/commands/authz_catalog_prune_orphans.d.ts.map +1 -0
  9. package/build/commands/authz_catalog_prune_orphans.js +136 -0
  10. package/build/commands/authz_catalog_prune_orphans.js.map +1 -0
  11. package/build/commands/authz_catalog_sync.d.ts +37 -0
  12. package/build/commands/authz_catalog_sync.d.ts.map +1 -0
  13. package/build/commands/authz_catalog_sync.js +81 -0
  14. package/build/commands/authz_catalog_sync.js.map +1 -0
  15. package/build/commands/authz_freeze.d.ts +44 -0
  16. package/build/commands/authz_freeze.d.ts.map +1 -0
  17. package/build/commands/authz_freeze.js +95 -0
  18. package/build/commands/authz_freeze.js.map +1 -0
  19. package/build/commands/authz_reconcile.d.ts +102 -0
  20. package/build/commands/authz_reconcile.d.ts.map +1 -0
  21. package/build/commands/authz_reconcile.js +294 -0
  22. package/build/commands/authz_reconcile.js.map +1 -0
  23. package/build/commands/authz_relations_reconcile.d.ts +73 -0
  24. package/build/commands/authz_relations_reconcile.d.ts.map +1 -0
  25. package/build/commands/authz_relations_reconcile.js +225 -0
  26. package/build/commands/authz_relations_reconcile.js.map +1 -0
  27. package/build/commands/authz_scopes_relay.d.ts +47 -0
  28. package/build/commands/authz_scopes_relay.d.ts.map +1 -0
  29. package/build/commands/authz_scopes_relay.js +141 -0
  30. package/build/commands/authz_scopes_relay.js.map +1 -0
  31. package/build/commands/authz_unfreeze.d.ts +37 -0
  32. package/build/commands/authz_unfreeze.d.ts.map +1 -0
  33. package/build/commands/authz_unfreeze.js +92 -0
  34. package/build/commands/authz_unfreeze.js.map +1 -0
  35. package/build/commands/main.d.ts +8 -1
  36. package/build/commands/main.d.ts.map +1 -1
  37. package/build/commands/main.js +8 -1
  38. package/build/commands/main.js.map +1 -1
  39. package/build/commands/openfga_provision.d.ts +46 -4
  40. package/build/commands/openfga_provision.d.ts.map +1 -1
  41. package/build/commands/openfga_provision.js +91 -7
  42. package/build/commands/openfga_provision.js.map +1 -1
  43. package/build/configure.d.ts +11 -0
  44. package/build/configure.d.ts.map +1 -1
  45. package/build/configure.js +37 -1
  46. package/build/configure.js.map +1 -1
  47. package/build/index.d.ts +75 -7
  48. package/build/index.d.ts.map +1 -1
  49. package/build/index.js +67 -5
  50. package/build/index.js.map +1 -1
  51. package/build/providers/authz_provider.d.ts +26 -2
  52. package/build/providers/authz_provider.d.ts.map +1 -1
  53. package/build/providers/authz_provider.js +48 -2
  54. package/build/providers/authz_provider.js.map +1 -1
  55. package/build/services/relations.d.ts +14 -0
  56. package/build/services/relations.d.ts.map +1 -0
  57. package/build/services/relations.js +17 -0
  58. package/build/services/relations.js.map +1 -0
  59. package/build/src/catalog/catalog.d.ts +289 -0
  60. package/build/src/catalog/catalog.d.ts.map +1 -0
  61. package/build/src/catalog/catalog.js +859 -0
  62. package/build/src/catalog/catalog.js.map +1 -0
  63. package/build/src/catalog/catalog_cache.d.ts +324 -0
  64. package/build/src/catalog/catalog_cache.d.ts.map +1 -0
  65. package/build/src/catalog/catalog_cache.js +666 -0
  66. package/build/src/catalog/catalog_cache.js.map +1 -0
  67. package/build/src/clock.d.ts +24 -0
  68. package/build/src/clock.d.ts.map +1 -0
  69. package/build/src/clock.js +7 -0
  70. package/build/src/clock.js.map +1 -0
  71. package/build/src/define_config.d.ts +201 -7
  72. package/build/src/define_config.d.ts.map +1 -1
  73. package/build/src/define_config.js.map +1 -1
  74. package/build/src/drivers/database_driver.d.ts +324 -15
  75. package/build/src/drivers/database_driver.d.ts.map +1 -1
  76. package/build/src/drivers/database_driver.js +1107 -128
  77. package/build/src/drivers/database_driver.js.map +1 -1
  78. package/build/src/drivers/database_relations_driver.d.ts +75 -0
  79. package/build/src/drivers/database_relations_driver.d.ts.map +1 -0
  80. package/build/src/drivers/database_relations_driver.js +450 -0
  81. package/build/src/drivers/database_relations_driver.js.map +1 -0
  82. package/build/src/drivers/openfga_driver.d.ts +963 -55
  83. package/build/src/drivers/openfga_driver.d.ts.map +1 -1
  84. package/build/src/drivers/openfga_driver.js +2693 -372
  85. package/build/src/drivers/openfga_driver.js.map +1 -1
  86. package/build/src/drivers/openfga_facts.d.ts +369 -0
  87. package/build/src/drivers/openfga_facts.d.ts.map +1 -0
  88. package/build/src/drivers/openfga_facts.js +813 -0
  89. package/build/src/drivers/openfga_facts.js.map +1 -0
  90. package/build/src/drivers/openfga_relations_driver.d.ts +120 -0
  91. package/build/src/drivers/openfga_relations_driver.d.ts.map +1 -0
  92. package/build/src/drivers/openfga_relations_driver.js +466 -0
  93. package/build/src/drivers/openfga_relations_driver.js.map +1 -0
  94. package/build/src/errors.d.ts +586 -0
  95. package/build/src/errors.d.ts.map +1 -1
  96. package/build/src/errors.js +583 -0
  97. package/build/src/errors.js.map +1 -1
  98. package/build/src/expiry.d.ts +27 -0
  99. package/build/src/expiry.d.ts.map +1 -0
  100. package/build/src/expiry.js +50 -0
  101. package/build/src/expiry.js.map +1 -0
  102. package/build/src/freeze.d.ts +120 -0
  103. package/build/src/freeze.d.ts.map +1 -0
  104. package/build/src/freeze.js +172 -0
  105. package/build/src/freeze.js.map +1 -0
  106. package/build/src/hierarchical_resolver.d.ts +56 -0
  107. package/build/src/hierarchical_resolver.d.ts.map +1 -0
  108. package/build/src/hierarchical_resolver.js +87 -0
  109. package/build/src/hierarchical_resolver.js.map +1 -0
  110. package/build/src/{middleware → http}/app_access_middleware.d.ts +8 -6
  111. package/build/src/http/app_access_middleware.d.ts.map +1 -0
  112. package/build/src/{middleware → http}/app_access_middleware.js +10 -26
  113. package/build/src/http/app_access_middleware.js.map +1 -0
  114. package/build/src/http/resource_access_middleware.d.ts +105 -0
  115. package/build/src/http/resource_access_middleware.d.ts.map +1 -0
  116. package/build/src/http/resource_access_middleware.js +81 -0
  117. package/build/src/http/resource_access_middleware.js.map +1 -0
  118. package/build/src/identity.d.ts +228 -0
  119. package/build/src/identity.d.ts.map +1 -0
  120. package/build/src/identity.js +457 -0
  121. package/build/src/identity.js.map +1 -0
  122. package/build/src/manager.d.ts +536 -7
  123. package/build/src/manager.d.ts.map +1 -1
  124. package/build/src/manager.js +2676 -23
  125. package/build/src/manager.js.map +1 -1
  126. package/build/src/memoize_ancestors.d.ts +23 -0
  127. package/build/src/memoize_ancestors.d.ts.map +1 -0
  128. package/build/src/memoize_ancestors.js +42 -0
  129. package/build/src/memoize_ancestors.js.map +1 -0
  130. package/build/src/models/authz_assignment.d.ts +11 -11
  131. package/build/src/models/authz_assignment.d.ts.map +1 -1
  132. package/build/src/models/authz_deny.d.ts +11 -11
  133. package/build/src/models/authz_deny.d.ts.map +1 -1
  134. package/build/src/models/authz_permission.d.ts +17 -11
  135. package/build/src/models/authz_permission.d.ts.map +1 -1
  136. package/build/src/models/authz_permission.js +4 -0
  137. package/build/src/models/authz_permission.js.map +1 -1
  138. package/build/src/models/authz_role.d.ts +19 -12
  139. package/build/src/models/authz_role.d.ts.map +1 -1
  140. package/build/src/models/authz_role.js +6 -1
  141. package/build/src/models/authz_role.js.map +1 -1
  142. package/build/src/models/authz_role_permission.d.ts +11 -11
  143. package/build/src/models/authz_role_permission.d.ts.map +1 -1
  144. package/build/src/openfga.d.ts +29 -0
  145. package/build/src/openfga.d.ts.map +1 -0
  146. package/build/src/openfga.js +26 -0
  147. package/build/src/openfga.js.map +1 -0
  148. package/build/src/reconcile.d.ts +37 -0
  149. package/build/src/reconcile.d.ts.map +1 -0
  150. package/build/src/reconcile.js +69 -0
  151. package/build/src/reconcile.js.map +1 -0
  152. package/build/src/relation_partition_trigger.d.ts +8 -0
  153. package/build/src/relation_partition_trigger.d.ts.map +1 -0
  154. package/build/src/relation_partition_trigger.js +85 -0
  155. package/build/src/relation_partition_trigger.js.map +1 -0
  156. package/build/src/relations/define_relations_config.d.ts +58 -0
  157. package/build/src/relations/define_relations_config.d.ts.map +1 -0
  158. package/build/src/relations/define_relations_config.js +144 -0
  159. package/build/src/relations/define_relations_config.js.map +1 -0
  160. package/build/src/relations/manager.d.ts +38 -0
  161. package/build/src/relations/manager.d.ts.map +1 -0
  162. package/build/src/relations/manager.js +156 -0
  163. package/build/src/relations/manager.js.map +1 -0
  164. package/build/src/relations/reconcile.d.ts +62 -0
  165. package/build/src/relations/reconcile.d.ts.map +1 -0
  166. package/build/src/relations/reconcile.js +138 -0
  167. package/build/src/relations/reconcile.js.map +1 -0
  168. package/build/src/relations_config_store.d.ts +22 -0
  169. package/build/src/relations_config_store.d.ts.map +1 -0
  170. package/build/src/relations_config_store.js +74 -0
  171. package/build/src/relations_config_store.js.map +1 -0
  172. package/build/src/scope_outbox.d.ts +69 -0
  173. package/build/src/scope_outbox.d.ts.map +1 -0
  174. package/build/src/scope_outbox.js +291 -0
  175. package/build/src/scope_outbox.js.map +1 -0
  176. package/build/src/shared/backend_guard.d.ts +106 -0
  177. package/build/src/shared/backend_guard.d.ts.map +1 -0
  178. package/build/src/shared/backend_guard.js +246 -0
  179. package/build/src/shared/backend_guard.js.map +1 -0
  180. package/build/src/shared/sql_expiry.d.ts +53 -0
  181. package/build/src/shared/sql_expiry.d.ts.map +1 -0
  182. package/build/src/shared/sql_expiry.js +66 -0
  183. package/build/src/shared/sql_expiry.js.map +1 -0
  184. package/build/src/sql_descendants.d.ts +97 -0
  185. package/build/src/sql_descendants.d.ts.map +1 -0
  186. package/build/src/sql_descendants.js +203 -0
  187. package/build/src/sql_descendants.js.map +1 -0
  188. package/build/src/testing/contract.d.ts +212 -7
  189. package/build/src/testing/contract.d.ts.map +1 -1
  190. package/build/src/testing/contract.js +3449 -24
  191. package/build/src/testing/contract.js.map +1 -1
  192. package/build/src/testing/main.d.ts +10 -2
  193. package/build/src/testing/main.d.ts.map +1 -1
  194. package/build/src/testing/main.js +5 -1
  195. package/build/src/testing/main.js.map +1 -1
  196. package/build/src/testing/migration_contract.d.ts +284 -0
  197. package/build/src/testing/migration_contract.d.ts.map +1 -0
  198. package/build/src/testing/migration_contract.js +586 -0
  199. package/build/src/testing/migration_contract.js.map +1 -0
  200. package/build/src/testing/relations_contract.d.ts +51 -0
  201. package/build/src/testing/relations_contract.d.ts.map +1 -0
  202. package/build/src/testing/relations_contract.js +654 -0
  203. package/build/src/testing/relations_contract.js.map +1 -0
  204. package/build/src/testing/relations_reconcile_contract.d.ts +24 -0
  205. package/build/src/testing/relations_reconcile_contract.d.ts.map +1 -0
  206. package/build/src/testing/relations_reconcile_contract.js +172 -0
  207. package/build/src/testing/relations_reconcile_contract.js.map +1 -0
  208. package/build/src/testing/scope_tree.d.ts +65 -0
  209. package/build/src/testing/scope_tree.d.ts.map +1 -0
  210. package/build/src/testing/scope_tree.js +145 -0
  211. package/build/src/testing/scope_tree.js.map +1 -0
  212. package/build/src/traits/authz_scopes.d.ts +30 -6
  213. package/build/src/traits/authz_scopes.d.ts.map +1 -1
  214. package/build/src/traits/authz_scopes.js +30 -18
  215. package/build/src/traits/authz_scopes.js.map +1 -1
  216. package/build/src/traits/has_uuid.d.ts +12 -12
  217. package/build/src/traits/has_uuid.d.ts.map +1 -1
  218. package/build/src/types.d.ts +1313 -28
  219. package/build/src/types.d.ts.map +1 -1
  220. package/build/src/types.js +20 -4
  221. package/build/src/types.js.map +1 -1
  222. package/build/stubs/config/app_acl.stub +4 -2
  223. package/build/stubs/config/authorization.stub +168 -14
  224. package/build/stubs/migration.stub +183 -13
  225. package/build/stubs/scopes_outbox_migration.stub +57 -0
  226. package/package.json +14 -7
  227. package/build/commands/openfga_import.d.ts +0 -28
  228. package/build/commands/openfga_import.d.ts.map +0 -1
  229. package/build/commands/openfga_import.js +0 -74
  230. package/build/commands/openfga_import.js.map +0 -1
  231. package/build/src/catalog.d.ts +0 -3
  232. package/build/src/catalog.d.ts.map +0 -1
  233. package/build/src/catalog.js +0 -103
  234. package/build/src/catalog.js.map +0 -1
  235. package/build/src/middleware/app_access_middleware.d.ts.map +0 -1
  236. package/build/src/middleware/app_access_middleware.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAEH,2DAA2D;AAC3D,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAA;IACZ,IAAI,EAAE,MAAM,CAAA;CACb;AAED;;;;;;;;;GASG;AACH,MAAM,MAAM,SAAS,GAAG,MAAM,CAAA;AAE9B,uCAAuC;AACvC,eAAO,MAAM,cAAc,QAAQ,CAAA;AAEnC,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,SAAS,CAAA;IACf,yDAAyD;IACzD,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CACpB;AAED,sDAAsD;AACtD,eAAO,MAAM,SAAS,EAAE,QAAqD,CAAA;AAE7E,MAAM,WAAW,YAAY;IAC3B,oEAAoE;IACpE,SAAS,CAAC,EAAE,IAAI,GAAG,IAAI,CAAA;CACxB;AAED,MAAM,WAAW,mBAAmB;IAClC;;;;OAIG;IACH,SAAS,CAAC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IAErF;;;OAGG;IACH,KAAK,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAEhG,4EAA4E;IAC5E,MAAM,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAEzE;;;OAGG;IACH,OAAO,CAAC,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;IAE7E;;;OAGG;IACH,IAAI,CAAC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAE7E,gEAAgE;IAChE,UAAU,CAAC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAA;IAEnF,iFAAiF;IACjF,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,EAAE,CAAC,CAAA;IAElE,mFAAmF;IACnF,SAAS,CAAC,OAAO,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;IAElE;;;OAGG;IACH,cAAc,CAAC,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,SAAS,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAA;IAE9E;;;;OAIG;IACH,UAAU,CAAC,OAAO,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAA;CACzE;AAED,wDAAwD;AACxD,MAAM,MAAM,0BAA0B,GAAG,MAAM,mBAAmB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAAA;AAEjG;;;;;GAKG;AACH,MAAM,MAAM,sBAAsB,GAAG,CAAC,KAAK,EAAE,QAAQ,KAAK,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAA;AAE7E;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,QAAQ,GAAG,cAAc,CAAA;IACzD,OAAO,EAAE,UAAU,CAAA;IACnB,KAAK,EAAE,QAAQ,CAAA;IACf,mCAAmC;IACnC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,uCAAuC;IACvC,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,SAAS,CAAC,EAAE,IAAI,GAAG,IAAI,CAAA;CACxB;AAQD,MAAM,WAAW,eAAe;IAC9B,sFAAsF;IACtF,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,MAAM,CAAA;IACZ,0CAA0C;IAC1C,SAAS,EAAE,SAAS,CAAA;IACpB,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3B;;;;OAIG;IACH,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,+DAA+D;IAC/D,WAAW,EAAE,MAAM,EAAE,CAAA;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,kEAAkE;IAClE,WAAW,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,CAAA;IACjE,KAAK,EAAE,eAAe,EAAE,CAAA;CACzB"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
@@ -12,10 +12,12 @@
12
12
  * suite corre contra cada driver — es el juez del contrato):
13
13
  *
14
14
  * 1. **Scopes jerárquicos, herencia SOLO hacia abajo.** La cadena de un scope
15
- * es `[scope, ...ancestros]` (`app` es la raíz: su cadena es él mismo).
15
+ * es `[scope canónico, ...ancestros]` (`app` es la raíz: su cadena es él
16
+ * mismo); la identidad de un scope es la que devuelve el resolutor, nunca
17
+ * la forma con la que lo escribió el llamante (2.5-B · K1).
16
18
  * Un grant en un scope autoriza en ese scope y en TODOS sus descendientes;
17
19
  * nunca en hermanos ni ancestros. En T1 solo opera `app` (los ancestros de
18
- * `organization`/`unit` se completan en T2/T3 vía `resolveAncestors`).
20
+ * `organization`/`unit` se completan en T2/T3 vía `resolveChain`).
19
21
  * 2. **Deny explícito gana.** Un deny de un permiso en cualquier scope de la
20
22
  * cadena bloquea `authorize`, aunque un rol lo conceda (el deny también
21
23
  * hereda hacia abajo). Quitar el deny restaura el permiso.
@@ -28,11 +30,25 @@
28
30
  * holder sin asignación vigente → `false`, nunca throw en `authorize`.
29
31
  * En cambio `grant`/`deny` con rol/permiso fuera del catálogo → throw
30
32
  * (error de programación, no de autorización).
31
- * 6. **Idempotencia de escritura.** Re-`grant` no duplica (actualiza
32
- * `expiresAt`); re-`revoke`/re-`deny`/re-`removeDeny` son no-ops seguros.
33
+ * 6. **Idempotencia de escritura.** Re-`grant` no duplica (`expiresAt` en
34
+ * tres estados: omitido preserva, `null` quita, `Date` fija);
35
+ * re-`revoke`/re-`deny`/re-`removeDeny` son no-ops seguros.
36
+ * 7. **El árbol es un hecho del contrato.** Un scope que el resolutor no
37
+ * conoce (`null`) deniega, no lista y no admite escrituras; `purgeScope`
38
+ * borra los hechos del scope exacto (los del catálogo) y demuestra cero.
33
39
  */
34
40
  /** Nombre reservado del scope raíz. */
35
41
  export const APP_SCOPE_TYPE = 'app';
36
42
  /** El scope raíz de aplicación (nivel plataforma). */
37
43
  export const APP_SCOPE = Object.freeze({ type: 'app', uuid: null });
44
+ /**
45
+ * Cuántas tuplas/filas del destino caben en una pasada de `authz:reconcile`
46
+ * (3b-3b · B5). No es una garantía de memoria: es la cota DECLARADA por
47
+ * encima de la cual la pasada se niega en vez de intentarlo.
48
+ */
49
+ export const DEFAULT_RECONCILE_MAX_TUPLES = 1_000_000;
50
+ /** Discriminador: ¿este sujeto es un userset (`group:g#member`) y no un holder? */
51
+ export function isRelUserset(subject) {
52
+ return typeof subject.object === 'object' && subject.object !== null;
53
+ }
38
54
  //# sourceMappingURL=types.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAoBH,uCAAuC;AACvC,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,CAAA;AAQnC,sDAAsD;AACtD,MAAM,CAAC,MAAM,SAAS,GAAa,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsCG;AAoBH,uCAAuC;AACvC,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,CAAA;AAQnC,sDAAsD;AACtD,MAAM,CAAC,MAAM,SAAS,GAAa,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;AAymB7E;;;;GAIG;AACH,MAAM,CAAC,MAAM,4BAA4B,GAAG,SAAS,CAAA;AAkrBrD,mFAAmF;AACnF,MAAM,UAAU,YAAY,CAAC,OAAmB;IAC9C,OAAO,OAAQ,OAAsB,CAAC,MAAM,KAAK,QAAQ,IAAK,OAAsB,CAAC,MAAM,KAAK,IAAI,CAAA;AACtG,CAAC"}
@@ -17,9 +17,11 @@ import type { CatalogSpec } from '@jantstack/adonis-authz'
17
17
  * Para el ACL POR TENANT ver `config/organization_acl.ts` (migra al motor
18
18
  * en la tanda 2).
19
19
  *
20
- * Workflow para añadir un permiso:
20
+ * Workflow para añadir o quitar un permiso:
21
21
  * 1. Editar este archivo.
22
- * 2. `node ace db:seed:one app_acl_seeder`
22
+ * 2. `node ace authz:catalog:sync` (quitar un permiso de un rol lo retira
23
+ * de verdad: el sync poda los vínculos que ya no listas).
24
+ * 3. En CI, `node ace authz:catalog:diff` falla si la base no coincide.
23
25
  */
24
26
  const appAclConfig = {
25
27
  /**
@@ -2,31 +2,89 @@
2
2
  exports({ to: app.configPath('authorization.ts') })
3
3
  }}}
4
4
  import env from '#start/env'
5
- import { defineConfig, DatabaseAuthorizationDriver } from '@jantstack/adonis-authz'
5
+ import {
6
+ defineConfig,
7
+ DatabaseAuthorizationDriver,
8
+ DatabaseRelationsDriver,
9
+ defineRelationsConfig,
10
+ APP_SCOPE,
11
+ } from '@jantstack/adonis-authz'
6
12
  import type { AuthzWriteEvent, ScopeRef } from '@jantstack/adonis-authz'
13
+ import { appAclCatalog } from '#config/app_acl'
7
14
 
8
15
  /**
9
16
  * Holders de tu aplicación: morph name (`@MorphMap` del modelo) → tipo del
10
17
  * modelo FGA. Solo lo usa el driver `openfga` y sus comandos.
11
18
  *
12
19
  * ⚠️ Cambiar este mapa cambia el authorization model: hay que re-provisionar
13
- * el store (`node ace openfga:provision`) y reimportar los hechos.
20
+ * el store (`node ace openfga:provision`) y volver a proyectar el catálogo.
14
21
  */
15
22
  export const holderTypes = {
16
23
  users: 'user',
17
24
  }
18
25
 
19
26
  /**
20
- * Jerarquía de scopes de tu dominio. El motor solo conoce la raíz (`app`);
21
- * si tienes niveles propios (organizaciones, proyectos, sedes…), devuelve
22
- * aquí sus ancestros del más cercano a la raíz.
27
+ * ReBAC genérico (relaciones a nivel de objeto: `document#viewer`,
28
+ * `group#member`…), OPT-IN. Declara aquí tus tipos de objeto y sus relaciones.
29
+ * Con la sección `relations` de abajo, el paquete cablea el `RelationsManager`
30
+ * como servicio (`import relations from '@jantstack/adonis-authz/services/relations'`)
31
+ * y —con AUTHZ_DRIVER=openfga— `node ace openfga:provision` mete estos tipos en
32
+ * el modelo `facts`, así que un store recién aprovisionado ya acepta tuplas de
33
+ * relación sin un `authz:catalog:sync` previo.
23
34
  *
24
- * organization [APP_SCOPE]
25
- * unit → [padres…, su organization, APP_SCOPE]
35
+ * `document` es solo un EJEMPLO: cámbialo por tus tipos (o borra este bloque y
36
+ * la sección `relations` si no usas ReBAC). `defineRelationsConfig` exige al
37
+ * menos un tipo, así que un array vacío lanza.
26
38
  */
27
- async function resolveScopeAncestors(scope: ScopeRef): Promise<ScopeRef[]> {
28
- if (scope.type === 'app') return []
29
- return [{ type: 'app', uuid: null }]
39
+ export const relationsConfig = defineRelationsConfig({
40
+ objectTypes: [
41
+ {
42
+ type: 'document',
43
+ relations: [
44
+ { name: 'owner' },
45
+ { name: 'editor', includes: ['owner'] },
46
+ { name: 'viewer', includes: ['editor'] },
47
+ ],
48
+ },
49
+ ],
50
+ holderTypes: Object.values(holderTypes),
51
+ })
52
+
53
+ /**
54
+ * Jerarquía de scopes de tu dominio: la ÚNICA costura entre tu dominio y el
55
+ * motor. El motor solo conoce la raíz (`app`); si tienes niveles propios
56
+ * (organizaciones, proyectos, sedes…), devuelve aquí la CADENA CANÓNICA del
57
+ * scope: él mismo TAL COMO ESTÁ EN TU TABLA (la fila leída, no lo que llegó
58
+ * en la pregunta) y después sus ancestros del más cercano a la raíz, con
59
+ * `APP_SCOPE` al final; y `null` si el scope NO existe (el motor deniega y
60
+ * rechaza escribir sobre él). Nunca devuelvas `[scope, APP_SCOPE]` para lo
61
+ * que no conoces: convertiría cualquier scope inventado en descendiente de la
62
+ * raíz. Devolver la fila (y no el argumento) es lo que impide que un alias del
63
+ * uuid —mayúsculas, guiones quitados, que el tipo `uuid` de PostgreSQL o una
64
+ * collation `*_ci` funden con la fila real— evada un deny escrito con la
65
+ * forma canónica. `hierarchicalScopeResolver({ nodeOf })` lo hace por ti a
66
+ * partir de un `nodeOf` que lea la fila.
67
+ *
68
+ * organization → [la organization (fila), APP_SCOPE] (si existe; si no, null)
69
+ * unit → [la unit (fila), su organization (fila), APP_SCOPE] (idem)
70
+ *
71
+ * Esta MISMA función va a tres sitios, y tiene que ser la misma:
72
+ * - `scopes.resolveChain` (abajo): el manager valida con ella
73
+ * `scopes.attached/moved` (padre existente, sin ciclos) antes de tocar
74
+ * el driver;
75
+ * - `resolveChain` de cada driver: con ella responde `authorize`,
76
+ * `hasRole` y los `list*`, y valida `grant`/`deny`.
77
+ * Un driver sin ella solo conoce `app` (422 al preguntar por otro nivel).
78
+ *
79
+ * Cuando tu árbol cambie, avisa al motor en todos los drivers:
80
+ * authorization.scopes.attached(child, parent) / moved(child, newParent) /
81
+ * detached(child) ← purga los hechos del scope antes de que borres la fila.
82
+ */
83
+ async function resolveScopeChain(scope: ScopeRef): Promise<ScopeRef[] | null> {
84
+ if (scope.type === 'app') return [APP_SCOPE]
85
+ // TODO: consulta tu tabla; devuelve null si `scope.uuid` no existe, y si
86
+ // existe, [{ type, uuid: fila.uuid }, ...ancestros, APP_SCOPE].
87
+ return null
30
88
  }
31
89
 
32
90
  /**
@@ -46,15 +104,60 @@ export default defineConfig({
46
104
  modelId: env.get('OPENFGA_MODEL_ID'),
47
105
  },
48
106
 
107
+ // La costura del árbol (ver arriba): la misma función que reciben los drivers.
108
+ // 2.1: añade `descendantsOf: sqlDescendantsOf({ table, uuidColumn, parentColumn, typeColumn })`
109
+ // (2.2: con `descendantsOf`, `scopes.detached` purga también los roles
110
+ // locales del SUBÁRBOL —sin él, solo los del scope exacto— y el nivel de
111
+ // un rol local se comprueba contra el árbol de hoy; delegar hacia abajo
112
+ // —`lead@unit` con owner una org— funciona con o sin él)
113
+ // (o tu propia función) para `authorizedScopes`; y `requireWithin: true` / `requireActor: true`
114
+ // en cuanto todos los call-sites pasen `within` / `actor` (hasta entonces el manager avisa).
115
+ // 2.3: `enumerateEdges: sqlScopeEdges({ table, uuidColumn, parentColumn, typeColumn })` es
116
+ // el árbol ENTERO paginado, y lo necesita `node ace authz:reconcile` (migrar entre drivers
117
+ // y verificar con --dry-run). Sin él el comando se niega en vez de suponer un árbol plano.
118
+ // La migración va en las DOS direcciones: `--to=openfga` reconstruye el store desde `authz_*`
119
+ // + este árbol, y `--to=database` reconstruye `authz_*` desde los hechos del store (ahí el
120
+ // árbol NO se migra: el driver `database` lo lee de TUS tablas en cada pregunta).
121
+ scopes: {
122
+ resolveChain: resolveScopeChain,
123
+ // Con AUTHZ_DRIVER=openfga el árbol vive en DOS sitios (tus tablas y el
124
+ // store) y quien ENCOLA los cambios es el MANAGER, que lee ESTA sección
125
+ // —no las opciones del driver—: sin una de las dos mitigaciones aquí,
126
+ // cada request es 500 E_AUTHZ_SCOPE_DRIFT_UNGUARDED. Igual que en la
127
+ // factory de abajo: cámbialo por `outbox: scopeOutbox` (la MISMA
128
+ // instancia en los dos sitios) en cuanto el árbol lo muevan peticiones
129
+ // de tenant; hasta entonces, esta es la firma explícita del riesgo.
130
+ // Con AUTHZ_DRIVER=database no aplica (el árbol tiene una sola copia).
131
+ acceptScopeDriftRisk: true,
132
+ },
133
+
49
134
  drivers: {
50
- database: () => new DatabaseAuthorizationDriver({ resolveAncestors: resolveScopeAncestors }),
135
+ database: () => new DatabaseAuthorizationDriver({ resolveChain: resolveScopeChain }),
51
136
 
52
137
  /**
53
138
  * Backend externo opcional. Levanta el servidor y provisiona con
54
- * `node ace openfga:provision`; migra los hechos con `openfga:import`.
139
+ * `node ace openfga:provision` (escribe el modelo con TUS permisos: el
140
+ * modelo cambia cada vez que añades o quitas uno, y `authz:catalog:sync`
141
+ * proyecta el catálogo en el store).
142
+ * El driver vive en el subpath `/openfga` (lo único que importa el peer
143
+ * opcional `@openfga/sdk`) y se carga DENTRO de la factory: sin
144
+ * AUTHZ_DRIVER=openfga el SDK ni se instala ni se importa.
145
+ *
146
+ * **El árbol de scopes vive en el store** (el driver es el PDP y
147
+ * `authorize` es un solo `Check`), así que hay DOS copias del árbol —la
148
+ * tuya y la suya— y un `rollback` de tu transacción dejaría la del store
149
+ * adelantada. Por eso el driver NO se construye sin una de las dos
150
+ * mitigaciones (500 `E_AUTHZ_SCOPE_DRIFT_UNGUARDED`):
151
+ *
152
+ * - `scopes.outbox`: la MISMA instancia que pones en `scopes` arriba —
153
+ * el manager encola los cambios del árbol dentro de tu transacción y
154
+ * `node ace authz:scopes:relay` los aplica. Es la recomendada;
155
+ * publica la tabla con la migración `scopes_outbox_migration.stub`.
156
+ * - `acceptScopeDriftRisk: true`: la firma explícita de quien mueve el
157
+ * árbol solo desde la plataforma y lo asume.
55
158
  */
56
159
  openfga: async () => {
57
- const { OpenFgaAuthorizationDriver } = await import('@jantstack/adonis-authz')
160
+ const { OpenFgaAuthorizationDriver } = await import('@jantstack/adonis-authz/openfga')
58
161
  const apiUrl = env.get('OPENFGA_URL')
59
162
  const storeId = env.get('OPENFGA_STORE_ID')
60
163
  if (!apiUrl || !storeId) {
@@ -64,11 +167,62 @@ export default defineConfig({
64
167
  apiUrl,
65
168
  storeId,
66
169
  modelId: env.get('OPENFGA_MODEL_ID'),
67
- resolveAncestors: resolveScopeAncestors,
170
+ resolveChain: resolveScopeChain,
68
171
  holderTypes,
172
+ // Cámbialo por `outbox: scopeOutbox` (la misma que pases en `scopes`)
173
+ // en cuanto el árbol lo muevan peticiones de tenant.
174
+ acceptScopeDriftRisk: true,
69
175
  })
70
176
  },
71
177
  },
72
178
 
179
+ /**
180
+ * Catálogos de roles/permisos (uno por módulo). `node ace authz:catalog:sync`
181
+ * los sincroniza en orden (podando los vínculos que el config ya no lista);
182
+ * `node ace authz:catalog:diff` falla en CI si la base no coincide.
183
+ */
184
+ catalogs: [async () => appAclCatalog()],
185
+
186
+ /**
187
+ * Roles locales a un scope (2.2): `defineScopedRole(actor, ownerScope, spec)`
188
+ * solo puede meter en un rol local permisos de esta lista blanca (y que el
189
+ * actor tenga efectivos en el owner). Vacía = nadie delega nada. Los
190
+ * permisos de plataforma (`admin:*`, ajustes de organización) no deberían
191
+ * estar aquí.
192
+ */
193
+ delegablePermissions: [],
194
+
195
+ /**
196
+ * ReBAC genérico (OPT-IN). `config` es la MISMA instancia que capturan las
197
+ * factories de `drivers` (F-05 del manager y del driver es la misma frontera);
198
+ * `default` es el driver de relaciones activo que resuelve el servicio
199
+ * `@jantstack/adonis-authz/services/relations` (default: el `default` de
200
+ * roles). Los `drivers` los usa además `node ace authz:relations:reconcile`.
201
+ * El driver `openfga` de relaciones entra por el subpath `/openfga` DENTRO de
202
+ * la factory (peer opcional). Si no usas ReBAC, borra esta sección y el
203
+ * `relationsConfig` de arriba.
204
+ */
205
+ relations: {
206
+ config: relationsConfig,
207
+ default: env.get('AUTHZ_DRIVER', 'database'),
208
+ drivers: {
209
+ database: () => new DatabaseRelationsDriver(relationsConfig),
210
+ openfga: async () => {
211
+ const { OpenFgaRelationsDriver } = await import('@jantstack/adonis-authz/openfga')
212
+ const apiUrl = env.get('OPENFGA_URL')
213
+ const storeId = env.get('OPENFGA_STORE_ID')
214
+ if (!apiUrl || !storeId) {
215
+ throw new Error('AUTHZ_DRIVER=openfga requiere OPENFGA_URL y OPENFGA_STORE_ID')
216
+ }
217
+ return new OpenFgaRelationsDriver(relationsConfig, {
218
+ apiUrl,
219
+ storeId,
220
+ modelId: env.get('OPENFGA_MODEL_ID'),
221
+ holderTypes,
222
+ })
223
+ },
224
+ },
225
+ },
226
+
73
227
  hooks: { onWrite: onAuthzWrite },
74
228
  })
@@ -14,31 +14,57 @@ import { BaseSchema } from '@adonisjs/lucid/schema'
14
14
  * El catálogo (roles/permissions/role_permissions) es metadata compartida
15
15
  * entre drivers; los HECHOS (assignments/denies) son lo único que otro
16
16
  * driver (p.ej. openfga) materializaría fuera.
17
+ *
18
+ * Decisiones observadas en PostgreSQL y MySQL (2.5 · J3, la suite corre en
19
+ * los tres motores):
20
+ * - `holder_uuid`/`scope_uuid` son `varchar(64)`, NO `uuid`: la identidad
21
+ * es una cadena validada por la gramática del paquete (`[A-Za-z0-9._-]`,
22
+ * ≤ 36) y el uuid es del consumidor; el tipo `uuid` de PostgreSQL
23
+ * rechazaba cualquier id que no fuera un UUID.
24
+ * - Las columnas de identidad y los slugs llevan `collate 'utf8mb4_bin'`
25
+ * (solo MySQL lo compila; en PG y SQLite la comparación ya es binaria):
26
+ * con la collation por defecto (`*_ci`) `abc` y `ABC` eran la misma fila
27
+ * y un grant a uno autorizaba al otro.
28
+ * - `expires_at` es `DATETIME(3)` (`datetime` con precisión 3): el
29
+ * `timestamp` de MySQL redondea al segundo (una caducidad de +600 ms
30
+ * concedía hasta +1 s) y no admite fechas más allá de 2038.
17
31
  */
18
32
  export default class extends BaseSchema {
19
33
  public async up() {
20
34
  this.schema.createTable('authz_roles', (table) => {
21
35
  table.uuid('uuid').primary().notNullable()
22
- table.string('slug', 100).notNullable()
36
+ table.string('slug', 100).notNullable().collate('utf8mb4_bin')
23
37
  table.string('name', 100).notNullable()
24
38
  table.string('description', 500).nullable()
25
39
  // Nivel al que el rol es asignable: 'app' | 'organization' | 'unit'.
26
- table.string('scope_type', 20).notNullable()
40
+ // Identidad: byte a byte, como el resto (2.5-B, auditor ⚪4).
41
+ table.string('scope_type', 20).notNullable().collate('utf8mb4_bin')
27
42
  // Rango de privilegio (mayor = más poder). Lo consume la policy de
28
43
  // asignación (role_assignment_policy): nadie otorga/quita por encima
29
44
  // de su propio rango.
30
45
  table.integer('rank').notNullable().defaultTo(0)
46
+ // Quién define el rol (3B · B1): `global` (el catálogo del config,
47
+ // `syncAuthzCatalog`) o la clave del scope que lo define
48
+ // (`<tipo>|<uuid>`, `defineScopedRole`). Un rol local solo existe
49
+ // dentro de su owner; dos tenants pueden definir `lead@unit` cada uno.
50
+ // Es identidad: byte a byte. `app` nunca es owner (sería global).
51
+ table.string('owner_scope_key', 80).notNullable().defaultTo('global').collate('utf8mb4_bin')
31
52
  table.timestamp('created_at').notNullable()
32
53
  table.timestamp('updated_at').notNullable()
33
54
 
34
- table.unique(['slug', 'scope_type'], 'authz_roles_slug_scope_uq')
55
+ table.unique(['slug', 'scope_type', 'owner_scope_key'], 'authz_roles_slug_scope_owner_uq')
56
+ table.index(['owner_scope_key'], 'authz_roles_owner_idx')
35
57
  })
36
58
 
37
59
  this.schema.createTable('authz_permissions', (table) => {
38
60
  table.uuid('uuid').primary().notNullable()
39
61
  // Formato `recurso:accion` (la misma gramática que las abilities M3).
40
- table.string('slug', 100).notNullable().unique()
62
+ table.string('slug', 100).notNullable().unique().collate('utf8mb4_bin')
41
63
  table.string('description', 500).nullable()
64
+ // Niveles (scope types) cuyos roles PUEDEN llevar este permiso (3B ·
65
+ // B5): JSON `["app","organization"]`, o NULL = cualquiera. Control de
66
+ // COMPOSICIÓN (sync, defineScopedRole, grant); jamás de evaluación.
67
+ table.string('assignable_at', 500).nullable()
42
68
  table.timestamp('created_at').notNullable()
43
69
  table.timestamp('updated_at').notNullable()
44
70
  })
@@ -65,22 +91,23 @@ export default class extends BaseSchema {
65
91
  this.schema.createTable('authz_assignments', (table) => {
66
92
  table.uuid('uuid').primary().notNullable()
67
93
  // Holder polimórfico: morph name (users/admins/integrations/...).
68
- table.string('holder_type', 50).notNullable()
69
- table.uuid('holder_uuid').notNullable()
94
+ table.string('holder_type', 50).notNullable().collate('utf8mb4_bin')
95
+ table.string('holder_uuid', 64).notNullable().collate('utf8mb4_bin')
70
96
  table
71
97
  .uuid('role_uuid')
72
98
  .notNullable()
73
99
  .references('uuid')
74
100
  .inTable('authz_roles')
75
101
  .onDelete('RESTRICT')
76
- table.string('scope_type', 20).notNullable()
102
+ table.string('scope_type', 20).notNullable().collate('utf8mb4_bin')
77
103
  // Sin FK: el scope es polimórfico. El nivel 'app' usa el uuid CENTINELA
78
104
  // 00000000-... (no NULL): los motores SQL tratan cada NULL como
79
105
  // distinto y el unique no aplicaría — con centinela la idempotencia
80
106
  // del grant la respalda la constraint en TODOS los niveles (sin
81
107
  // features específicas de un motor, regla M6).
82
- table.uuid('scope_uuid').notNullable()
83
- table.timestamp('expires_at').nullable()
108
+ table.string('scope_uuid', 64).notNullable().collate('utf8mb4_bin')
109
+ // Milisegundos y sin tope de 2038 (ver cabecera): DATETIME(3).
110
+ table.datetime('expires_at', { precision: 3 }).nullable()
84
111
  table.timestamp('created_at').notNullable()
85
112
 
86
113
  table.unique(
@@ -93,17 +120,17 @@ export default class extends BaseSchema {
93
120
 
94
121
  this.schema.createTable('authz_denies', (table) => {
95
122
  table.uuid('uuid').primary().notNullable()
96
- table.string('holder_type', 50).notNullable()
97
- table.uuid('holder_uuid').notNullable()
123
+ table.string('holder_type', 50).notNullable().collate('utf8mb4_bin')
124
+ table.string('holder_uuid', 64).notNullable().collate('utf8mb4_bin')
98
125
  table
99
126
  .uuid('permission_uuid')
100
127
  .notNullable()
101
128
  .references('uuid')
102
129
  .inTable('authz_permissions')
103
130
  .onDelete('CASCADE')
104
- table.string('scope_type', 20).notNullable()
131
+ table.string('scope_type', 20).notNullable().collate('utf8mb4_bin')
105
132
  // Centinela 00000000-... para 'app' (ver nota en authz_assignments).
106
- table.uuid('scope_uuid').notNullable()
133
+ table.string('scope_uuid', 64).notNullable().collate('utf8mb4_bin')
107
134
  table.timestamp('created_at').notNullable()
108
135
 
109
136
  table.unique(
@@ -112,9 +139,109 @@ export default class extends BaseSchema {
112
139
  )
113
140
  table.index(['holder_type', 'holder_uuid'], 'authz_deny_holder_idx')
114
141
  })
142
+
143
+ // Versión COMPARTIDA del catálogo (2.1): una fila (`id = 1`) cuyo entero
144
+ // sube `syncAuthzCatalog` dentro de su transacción. Los memos del
145
+ // catálogo de todos los procesos la contrastan antes de servir: un sync
146
+ // en un worker se ve en los demás sin reiniciar ni pub/sub. Quien
147
+ // escriba `authz_*` a mano lo hace con `withAuthzCatalogWrite(async (trx)
148
+ // => …)`: misma transacción, versión subida como última sentencia. Sin
149
+ // esta fila (id = 1) toda pregunta es 503: por eso se siembra aquí.
150
+ //
151
+ // La fila `id = 2` es el **freeze DURABLE** (2.3): motivo, dueño
152
+ // (`<kind>:<pid>:<hex>`), lease (`freeze_until_ms`, null = sin caducidad)
153
+ // y `freeze_fence` (número de generación: `unfreeze` solo levanta el
154
+ // freeze cuyo fence+holder coinciden). Toda ESCRITURA del manager la lee
155
+ // antes de validar nada; sin esta fila toda escritura es 503 «migración
156
+ // 2.0 no aplicada» — tratarla como «no congelado» sería fail-open.
157
+ this.schema.createTable('authz_catalog_version', (table) => {
158
+ table.integer('id').primary().notNullable()
159
+ table.bigInteger('version').notNullable().defaultTo(0)
160
+ table.timestamp('updated_at').notNullable()
161
+ table.string('freeze_reason', 255).nullable()
162
+ table.string('freeze_holder', 120).nullable()
163
+ table.bigInteger('freeze_until_ms').nullable()
164
+ table.bigInteger('freeze_fence').notNullable().defaultTo(0)
165
+ })
166
+ this.defer(async (db) => {
167
+ await db.table('authz_catalog_version').insert({ id: 1, version: 0, updated_at: new Date() })
168
+ await db.table('authz_catalog_version').insert({ id: 2, version: 0, updated_at: new Date() })
169
+ })
170
+
171
+ // La config de relaciones PERSISTIDA (Fase 4-5, 🟡3): vive donde el gate de
172
+ // versión la ve (invariante 14), como el catálogo, para que CUALQUIER
173
+ // proceso que republique el modelo fusionado lea los tipos de relación de
174
+ // la BASE y NO los deje caer —el «modelo de uno, tuplas de otro» del
175
+ // auditor—. `spec` es el JSON de `defineRelationsConfig`; `model_id` es el
176
+ // último modelId del modelo fusionado publicado (el pin de la carrera
177
+ // `defineRelationsConfig`↔`syncAuthzCatalog`). Fila ausente = sin
178
+ // relaciones declaradas (opt-in), nunca un error.
179
+ this.schema.createTable('authz_relations_config', (table) => {
180
+ table.integer('id').primary().notNullable()
181
+ table.text('spec').notNullable()
182
+ table.string('model_id', 64).nullable()
183
+ table.timestamp('updated_at').notNullable()
184
+ })
185
+
186
+ // Tuplas de ReBAC (Fase 4): una fila por relación, INSERT/DELETE-ONLY (sin
187
+ // `expires_at`: la caducidad de relaciones quedó fuera de la 2.4). Sin FK:
188
+ // las relaciones NO cuelgan del catálogo (viven en su propio espacio de
189
+ // ids, disjunto de `authz_*` por construcción). Identidad byte a byte
190
+ // (`utf8mb4_bin`) como el resto (2.5 · J3). La partición (tenant) es la
191
+ // clave del scope; `subject_relation` con valor = userset (`group:g#member`),
192
+ // `subject_partition` = la partición del userset.
193
+ this.schema.createTable('authz_relations', (table) => {
194
+ table.uuid('uuid').primary().notNullable()
195
+ table.string('partition_key', 64).notNullable().collate('utf8mb4_bin')
196
+ table.string('object_type', 50).notNullable().collate('utf8mb4_bin')
197
+ table.string('object_uuid', 64).notNullable().collate('utf8mb4_bin')
198
+ table.string('relation', 50).notNullable().collate('utf8mb4_bin')
199
+ table.string('subject_type', 50).notNullable().collate('utf8mb4_bin')
200
+ table.string('subject_uuid', 64).notNullable().collate('utf8mb4_bin')
201
+ table.string('subject_relation', 50).nullable().collate('utf8mb4_bin')
202
+ table.string('subject_partition', 64).nullable().collate('utf8mb4_bin')
203
+ table.timestamp('created_at').notNullable()
204
+
205
+ table.unique(
206
+ ['partition_key', 'object_type', 'object_uuid', 'relation', 'subject_type', 'subject_uuid', 'subject_relation'],
207
+ 'authz_rel_tuple_uq'
208
+ )
209
+ table.index(['partition_key', 'object_type', 'object_uuid', 'relation'], 'authz_rel_object_idx')
210
+ table.index(['partition_key', 'subject_type', 'subject_uuid'], 'authz_rel_subject_idx')
211
+ })
212
+
213
+ // El TRIGGER de partición, por dialecto. Defiende al escritor «a mano»: una
214
+ // fila con userset (`subject_relation` con valor) de OTRA partición que la
215
+ // de la tupla se rechaza en el motor. La DDL es radicalmente distinta en
216
+ // cada uno (SQLite `RAISE(ABORT)`, PostgreSQL función plpgsql + trigger,
217
+ // MySQL `SIGNAL SQLSTATE`), y el cuerpo `BEGIN…END` lleva `;` dentro: cada
218
+ // sentencia se ejecuta ENTERA con `rawQuery`, nunca por un runner que
219
+ // trocea por `;`.
220
+ this.defer(async (db) => {
221
+ const dialect = db.dialect.name
222
+ for (const statement of relationPartitionTriggerStatements(dialect)) {
223
+ await db.rawQuery(statement)
224
+ }
225
+ })
115
226
  }
116
227
 
117
228
  public async down() {
229
+ this.defer(async (db) => {
230
+ const drops =
231
+ db.dialect.name === 'postgres'
232
+ ? [
233
+ 'DROP TRIGGER IF EXISTS authz_relations_partition_biu ON authz_relations',
234
+ 'DROP FUNCTION IF EXISTS authz_relations_partition_guard()',
235
+ ]
236
+ : [
237
+ 'DROP TRIGGER IF EXISTS authz_relations_partition_bi',
238
+ 'DROP TRIGGER IF EXISTS authz_relations_partition_bu',
239
+ ]
240
+ for (const statement of drops) await db.rawQuery(statement)
241
+ })
242
+ this.schema.dropTable('authz_relations')
243
+ this.schema.dropTable('authz_relations_config')
244
+ this.schema.dropTable('authz_catalog_version')
118
245
  this.schema.dropTable('authz_denies')
119
246
  this.schema.dropTable('authz_assignments')
120
247
  this.schema.dropTable('authz_role_permissions')
@@ -122,3 +249,46 @@ export default class extends BaseSchema {
122
249
  this.schema.dropTable('authz_roles')
123
250
  }
124
251
  }
252
+
253
+ /**
254
+ * La DDL del trigger de partición de `authz_relations` por dialecto. Es la
255
+ * MISMA que `relationPartitionTrigger` del paquete
256
+ * (`@jantstack/adonis-authz` → `src/drivers/database_relations_driver.ts`);
257
+ * se inlinea aquí porque una migración es una foto congelada y no importa
258
+ * código del paquete. Dialecto no medido ⇒ lanza (nunca una tabla sin defensa).
259
+ */
260
+ function relationPartitionTriggerStatements(dialect) {
261
+ const msg = 'authz_relations: un userset no puede pertenecer a otra partición que su tupla'
262
+ if (dialect === 'sqlite3' || dialect === 'better-sqlite3') {
263
+ const body = (event) =>
264
+ `CREATE TRIGGER authz_relations_partition_b${event === 'INSERT' ? 'i' : 'u'} ` +
265
+ `BEFORE ${event} ON authz_relations FOR EACH ROW ` +
266
+ `WHEN NEW.subject_relation IS NOT NULL AND NEW.subject_partition IS NOT NEW.partition_key ` +
267
+ `BEGIN SELECT RAISE(ABORT, '${msg}'); END`
268
+ return [body('INSERT'), body('UPDATE')]
269
+ }
270
+ if (dialect === 'postgres') {
271
+ return [
272
+ `CREATE OR REPLACE FUNCTION authz_relations_partition_guard() RETURNS trigger LANGUAGE plpgsql AS $authz$ ` +
273
+ `BEGIN ` +
274
+ `IF NEW.subject_relation IS NOT NULL AND NEW.subject_partition IS DISTINCT FROM NEW.partition_key THEN ` +
275
+ `RAISE EXCEPTION '${msg} (subject_partition=%, partition_key=%)', NEW.subject_partition, NEW.partition_key; ` +
276
+ `END IF; RETURN NEW; END; $authz$`,
277
+ `CREATE TRIGGER authz_relations_partition_biu BEFORE INSERT OR UPDATE ON authz_relations ` +
278
+ `FOR EACH ROW EXECUTE FUNCTION authz_relations_partition_guard()`,
279
+ ]
280
+ }
281
+ if (dialect === 'mysql' || dialect === 'mysql2') {
282
+ const body = (event) =>
283
+ `CREATE TRIGGER authz_relations_partition_b${event === 'INSERT' ? 'i' : 'u'} ` +
284
+ `BEFORE ${event} ON authz_relations FOR EACH ROW ` +
285
+ `BEGIN ` +
286
+ `IF NEW.subject_relation IS NOT NULL AND NOT (NEW.subject_partition <=> NEW.partition_key) THEN ` +
287
+ `SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '${msg}'; ` +
288
+ `END IF; END`
289
+ return [body('INSERT'), body('UPDATE')]
290
+ }
291
+ throw new Error(
292
+ `authz_relations: dialecto '${dialect}' sin trigger de partición medido (hoy: PostgreSQL, MySQL 8 y SQLite).`
293
+ )
294
+ }