@stigmer/server 3.27.1 → 3.28.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 (245) hide show
  1. package/README.md +2 -0
  2. package/dist/authorization/authorizer.d.ts +7 -5
  3. package/dist/authorization/authorizer.d.ts.map +1 -1
  4. package/dist/authorization/authorizer.js +7 -5
  5. package/dist/authorization/authorizer.js.map +1 -1
  6. package/dist/authorization/derived-tuples.d.ts +3 -1
  7. package/dist/authorization/derived-tuples.d.ts.map +1 -1
  8. package/dist/authorization/derived-tuples.js +52 -2
  9. package/dist/authorization/derived-tuples.js.map +1 -1
  10. package/dist/authorization/evaluator.d.ts +9 -10
  11. package/dist/authorization/evaluator.d.ts.map +1 -1
  12. package/dist/authorization/evaluator.js.map +1 -1
  13. package/dist/authorization/list-read-scope.d.ts.map +1 -1
  14. package/dist/authorization/list-read-scope.js +29 -18
  15. package/dist/authorization/list-read-scope.js.map +1 -1
  16. package/dist/authorization/model/bindings.d.ts +41 -0
  17. package/dist/authorization/model/bindings.d.ts.map +1 -0
  18. package/dist/authorization/model/bindings.js +89 -0
  19. package/dist/authorization/model/bindings.js.map +1 -0
  20. package/dist/authorization/model/data/authorization-model.json +3114 -0
  21. package/dist/authorization/model/default-of.d.ts +2 -2
  22. package/dist/authorization/model/execution-viewer.d.ts +3 -0
  23. package/dist/authorization/model/execution-viewer.d.ts.map +1 -0
  24. package/dist/authorization/model/execution-viewer.js +50 -0
  25. package/dist/authorization/model/execution-viewer.js.map +1 -0
  26. package/dist/authorization/model/index.d.ts +33 -21
  27. package/dist/authorization/model/index.d.ts.map +1 -1
  28. package/dist/authorization/model/index.js +74 -52
  29. package/dist/authorization/model/index.js.map +1 -1
  30. package/dist/authorization/model/openfga-json.d.ts +18 -0
  31. package/dist/authorization/model/openfga-json.d.ts.map +1 -0
  32. package/dist/authorization/model/openfga-json.js +266 -0
  33. package/dist/authorization/model/openfga-json.js.map +1 -0
  34. package/dist/authorization/model/rewrite.d.ts +39 -67
  35. package/dist/authorization/model/rewrite.d.ts.map +1 -1
  36. package/dist/authorization/model/rewrite.js +1 -117
  37. package/dist/authorization/model/rewrite.js.map +1 -1
  38. package/dist/authorization/strict-json.d.ts +20 -0
  39. package/dist/authorization/strict-json.d.ts.map +1 -0
  40. package/dist/authorization/strict-json.js +45 -0
  41. package/dist/authorization/strict-json.js.map +1 -0
  42. package/dist/boot/compose.d.ts.map +1 -1
  43. package/dist/boot/compose.js +9 -7
  44. package/dist/boot/compose.js.map +1 -1
  45. package/dist/boot/list-indexes.d.ts.map +1 -1
  46. package/dist/boot/list-indexes.js +6 -0
  47. package/dist/boot/list-indexes.js.map +1 -1
  48. package/dist/domain/iampolicy/list-index.d.ts +2 -0
  49. package/dist/domain/iampolicy/list-index.d.ts.map +1 -0
  50. package/dist/domain/iampolicy/list-index.js +32 -0
  51. package/dist/domain/iampolicy/list-index.js.map +1 -0
  52. package/dist/domain/iampolicy/resource-store.d.ts.map +1 -1
  53. package/dist/domain/iampolicy/resource-store.js +24 -11
  54. package/dist/domain/iampolicy/resource-store.js.map +1 -1
  55. package/dist/domain/workflowexecution/list-index.d.ts +1 -1
  56. package/dist/extensions/list-read-scope.d.ts +20 -3
  57. package/dist/extensions/list-read-scope.d.ts.map +1 -1
  58. package/dist/extensions/list-read-scope.js +22 -2
  59. package/dist/extensions/list-read-scope.js.map +1 -1
  60. package/dist/index.d.ts +8 -8
  61. package/dist/index.d.ts.map +1 -1
  62. package/dist/index.js +20 -5
  63. package/dist/index.js.map +1 -1
  64. package/package.json +7 -6
  65. package/src/authorization/README.md +48 -39
  66. package/src/authorization/__tests__/authorizer.test.ts +5 -14
  67. package/src/authorization/__tests__/derived-tuples.test.ts +192 -17
  68. package/src/authorization/__tests__/evaluator.test.ts +53 -160
  69. package/src/authorization/__tests__/facts.test.ts +5 -11
  70. package/src/authorization/__tests__/list-read-scope.measure.test.ts +424 -62
  71. package/src/authorization/__tests__/list-read-scope.test.ts +15 -14
  72. package/src/authorization/__tests__/organization-directory.test.ts +2 -2
  73. package/src/authorization/__tests__/store-test-kit.ts +246 -0
  74. package/src/authorization/__tests__/store-tests.test.ts +91 -223
  75. package/src/authorization/__tests__/support.ts +30 -2
  76. package/src/authorization/__tests__/throwaway-model.ts +75 -0
  77. package/src/authorization/__tests__/wire-permissions.test.ts +141 -107
  78. package/src/authorization/authorizer.ts +7 -5
  79. package/src/authorization/derived-tuples.ts +105 -16
  80. package/src/authorization/evaluator.ts +8 -10
  81. package/src/authorization/list-read-scope.ts +37 -22
  82. package/src/authorization/model/__tests__/openfga-json.test.ts +353 -0
  83. package/src/authorization/model/__tests__/registry.test.ts +102 -276
  84. package/src/authorization/model/bindings.ts +131 -0
  85. package/src/authorization/model/data/authorization-model.json +3114 -0
  86. package/src/authorization/model/default-of.ts +2 -2
  87. package/src/authorization/model/execution-viewer.ts +56 -0
  88. package/src/authorization/model/index.ts +81 -72
  89. package/src/authorization/model/openfga-json.ts +310 -0
  90. package/src/authorization/model/rewrite.ts +39 -188
  91. package/src/authorization/strict-json.ts +52 -0
  92. package/src/boot/__tests__/list-indexes.test.ts +4 -0
  93. package/src/boot/compose.ts +9 -7
  94. package/src/boot/list-indexes.ts +6 -0
  95. package/src/domain/iampolicy/__tests__/resource-store.test.ts +65 -5
  96. package/src/domain/iampolicy/list-index.ts +33 -0
  97. package/src/domain/iampolicy/resource-store.ts +24 -11
  98. package/src/extensions/__tests__/built-in-authorization-composed.test.ts +3 -6
  99. package/src/extensions/list-read-scope.ts +32 -4
  100. package/src/index.ts +20 -44
  101. package/dist/authorization/model/agent.d.ts +0 -2
  102. package/dist/authorization/model/agent.d.ts.map +0 -1
  103. package/dist/authorization/model/agent.js +0 -43
  104. package/dist/authorization/model/agent.js.map +0 -1
  105. package/dist/authorization/model/agent_channel.d.ts +0 -2
  106. package/dist/authorization/model/agent_channel.d.ts.map +0 -1
  107. package/dist/authorization/model/agent_channel.js +0 -39
  108. package/dist/authorization/model/agent_channel.js.map +0 -1
  109. package/dist/authorization/model/agent_execution.d.ts +0 -2
  110. package/dist/authorization/model/agent_execution.d.ts.map +0 -1
  111. package/dist/authorization/model/agent_execution.js +0 -25
  112. package/dist/authorization/model/agent_execution.js.map +0 -1
  113. package/dist/authorization/model/agent_instance.d.ts +0 -2
  114. package/dist/authorization/model/agent_instance.d.ts.map +0 -1
  115. package/dist/authorization/model/agent_instance.js +0 -48
  116. package/dist/authorization/model/agent_instance.js.map +0 -1
  117. package/dist/authorization/model/agent_share.d.ts +0 -2
  118. package/dist/authorization/model/agent_share.d.ts.map +0 -1
  119. package/dist/authorization/model/agent_share.js +0 -29
  120. package/dist/authorization/model/agent_share.js.map +0 -1
  121. package/dist/authorization/model/api_key.d.ts +0 -2
  122. package/dist/authorization/model/api_key.d.ts.map +0 -1
  123. package/dist/authorization/model/api_key.js +0 -27
  124. package/dist/authorization/model/api_key.js.map +0 -1
  125. package/dist/authorization/model/artifact.d.ts +0 -2
  126. package/dist/authorization/model/artifact.d.ts.map +0 -1
  127. package/dist/authorization/model/artifact.js +0 -27
  128. package/dist/authorization/model/artifact.js.map +0 -1
  129. package/dist/authorization/model/channel_app.d.ts +0 -2
  130. package/dist/authorization/model/channel_app.d.ts.map +0 -1
  131. package/dist/authorization/model/channel_app.js +0 -28
  132. package/dist/authorization/model/channel_app.js.map +0 -1
  133. package/dist/authorization/model/environment.d.ts +0 -2
  134. package/dist/authorization/model/environment.d.ts.map +0 -1
  135. package/dist/authorization/model/environment.js +0 -33
  136. package/dist/authorization/model/environment.js.map +0 -1
  137. package/dist/authorization/model/execution_context.d.ts +0 -2
  138. package/dist/authorization/model/execution_context.d.ts.map +0 -1
  139. package/dist/authorization/model/execution_context.js +0 -19
  140. package/dist/authorization/model/execution_context.js.map +0 -1
  141. package/dist/authorization/model/iam_policy.d.ts +0 -2
  142. package/dist/authorization/model/iam_policy.d.ts.map +0 -1
  143. package/dist/authorization/model/iam_policy.js +0 -31
  144. package/dist/authorization/model/iam_policy.js.map +0 -1
  145. package/dist/authorization/model/identity_account.d.ts +0 -2
  146. package/dist/authorization/model/identity_account.d.ts.map +0 -1
  147. package/dist/authorization/model/identity_account.js +0 -25
  148. package/dist/authorization/model/identity_account.js.map +0 -1
  149. package/dist/authorization/model/mcp_server.d.ts +0 -2
  150. package/dist/authorization/model/mcp_server.d.ts.map +0 -1
  151. package/dist/authorization/model/mcp_server.js +0 -38
  152. package/dist/authorization/model/mcp_server.js.map +0 -1
  153. package/dist/authorization/model/memory.d.ts +0 -2
  154. package/dist/authorization/model/memory.d.ts.map +0 -1
  155. package/dist/authorization/model/memory.js +0 -26
  156. package/dist/authorization/model/memory.js.map +0 -1
  157. package/dist/authorization/model/oauth_app.d.ts +0 -2
  158. package/dist/authorization/model/oauth_app.d.ts.map +0 -1
  159. package/dist/authorization/model/oauth_app.js +0 -31
  160. package/dist/authorization/model/oauth_app.js.map +0 -1
  161. package/dist/authorization/model/organization.d.ts +0 -2
  162. package/dist/authorization/model/organization.d.ts.map +0 -1
  163. package/dist/authorization/model/organization.js +0 -58
  164. package/dist/authorization/model/organization.js.map +0 -1
  165. package/dist/authorization/model/platform_client.d.ts +0 -2
  166. package/dist/authorization/model/platform_client.d.ts.map +0 -1
  167. package/dist/authorization/model/platform_client.js +0 -31
  168. package/dist/authorization/model/platform_client.js.map +0 -1
  169. package/dist/authorization/model/plugin.d.ts +0 -2
  170. package/dist/authorization/model/plugin.d.ts.map +0 -1
  171. package/dist/authorization/model/plugin.js +0 -45
  172. package/dist/authorization/model/plugin.js.map +0 -1
  173. package/dist/authorization/model/schedule.d.ts +0 -2
  174. package/dist/authorization/model/schedule.d.ts.map +0 -1
  175. package/dist/authorization/model/schedule.js +0 -34
  176. package/dist/authorization/model/schedule.js.map +0 -1
  177. package/dist/authorization/model/session.d.ts +0 -2
  178. package/dist/authorization/model/session.d.ts.map +0 -1
  179. package/dist/authorization/model/session.js +0 -38
  180. package/dist/authorization/model/session.js.map +0 -1
  181. package/dist/authorization/model/skill.d.ts +0 -2
  182. package/dist/authorization/model/skill.d.ts.map +0 -1
  183. package/dist/authorization/model/skill.js +0 -39
  184. package/dist/authorization/model/skill.js.map +0 -1
  185. package/dist/authorization/model/workflow.d.ts +0 -2
  186. package/dist/authorization/model/workflow.d.ts.map +0 -1
  187. package/dist/authorization/model/workflow.js +0 -39
  188. package/dist/authorization/model/workflow.js.map +0 -1
  189. package/dist/authorization/model/workflow_execution.d.ts +0 -2
  190. package/dist/authorization/model/workflow_execution.d.ts.map +0 -1
  191. package/dist/authorization/model/workflow_execution.js +0 -33
  192. package/dist/authorization/model/workflow_execution.js.map +0 -1
  193. package/dist/authorization/model/workflow_instance.d.ts +0 -2
  194. package/dist/authorization/model/workflow_instance.d.ts.map +0 -1
  195. package/dist/authorization/model/workflow_instance.js +0 -96
  196. package/dist/authorization/model/workflow_instance.js.map +0 -1
  197. package/dist/authorization/store-test-kit.d.ts +0 -62
  198. package/dist/authorization/store-test-kit.d.ts.map +0 -1
  199. package/dist/authorization/store-test-kit.js +0 -265
  200. package/dist/authorization/store-test-kit.js.map +0 -1
  201. package/src/authorization/__tests__/fixtures/fga/agent-channel-owner.fga.yaml +0 -112
  202. package/src/authorization/__tests__/fixtures/fga/agent-instance-creation.fga.yaml +0 -177
  203. package/src/authorization/__tests__/fixtures/fga/agent-share-owner.fga.yaml +0 -109
  204. package/src/authorization/__tests__/fixtures/fga/artifact-org-and-owner.fga.yaml +0 -128
  205. package/src/authorization/__tests__/fixtures/fga/blueprint-private-visibility.fga.yaml +0 -318
  206. package/src/authorization/__tests__/fixtures/fga/channel-app-owner.fga.yaml +0 -125
  207. package/src/authorization/__tests__/fixtures/fga/channel-participation.fga.yaml +0 -201
  208. package/src/authorization/__tests__/fixtures/fga/channel-session-visibility.fga.yaml +0 -187
  209. package/src/authorization/__tests__/fixtures/fga/default-instance-inheritance.fga.yaml +0 -214
  210. package/src/authorization/__tests__/fixtures/fga/mcp-server-authoring.fga.yaml +0 -129
  211. package/src/authorization/__tests__/fixtures/fga/memory-subject-only.fga.yaml +0 -72
  212. package/src/authorization/__tests__/fixtures/fga/org-admin-owner-inheritance.fga.yaml +0 -308
  213. package/src/authorization/__tests__/fixtures/fga/org-shared-environment.fga.yaml +0 -144
  214. package/src/authorization/__tests__/fixtures/fga/platform-visibility.fga.yaml +0 -199
  215. package/src/authorization/__tests__/fixtures/fga/provider-standing-viewer.fga.yaml +0 -40
  216. package/src/authorization/__tests__/fixtures/fga/reserved-label-writer.fga.yaml +0 -41
  217. package/src/authorization/__tests__/fixtures/fga/schedule-owner.fga.yaml +0 -113
  218. package/src/authorization/__tests__/fixtures/fga/schedule-session-visibility.fga.yaml +0 -214
  219. package/src/authorization/__tests__/fixtures/fga/session-personal-resource.fga.yaml +0 -117
  220. package/src/authorization/__tests__/fixtures/fga/workflow-execution-sharing.fga.yaml +0 -190
  221. package/src/authorization/model/agent.ts +0 -64
  222. package/src/authorization/model/agent_channel.ts +0 -57
  223. package/src/authorization/model/agent_execution.ts +0 -33
  224. package/src/authorization/model/agent_instance.ts +0 -66
  225. package/src/authorization/model/agent_share.ts +0 -40
  226. package/src/authorization/model/api_key.ts +0 -28
  227. package/src/authorization/model/artifact.ts +0 -38
  228. package/src/authorization/model/channel_app.ts +0 -39
  229. package/src/authorization/model/environment.ts +0 -48
  230. package/src/authorization/model/execution_context.ts +0 -20
  231. package/src/authorization/model/iam_policy.ts +0 -42
  232. package/src/authorization/model/identity_account.ts +0 -26
  233. package/src/authorization/model/mcp_server.ts +0 -59
  234. package/src/authorization/model/memory.ts +0 -27
  235. package/src/authorization/model/oauth_app.ts +0 -43
  236. package/src/authorization/model/organization.ts +0 -59
  237. package/src/authorization/model/platform_client.ts +0 -43
  238. package/src/authorization/model/plugin.ts +0 -66
  239. package/src/authorization/model/schedule.ts +0 -49
  240. package/src/authorization/model/session.ts +0 -50
  241. package/src/authorization/model/skill.ts +0 -60
  242. package/src/authorization/model/workflow.ts +0 -60
  243. package/src/authorization/model/workflow_execution.ts +0 -46
  244. package/src/authorization/model/workflow_instance.ts +0 -125
  245. package/src/authorization/store-test-kit.ts +0 -395
@@ -1,41 +0,0 @@
1
- # Pinned copy of stigmer-cloud backend/services/stigmer-server/fga/tests/reserved-label-writer.fga.yaml
2
- # at commit b87dd1170 (the OpenFGA store test the cloud runs against its live model).
3
- # The body below is byte-identical to the source; the cloud re-runs the LIVE
4
- # file against this evaluator at the re-pin, so a stale copy is caught there.
5
- # Store tests for the reserved-label write permission (cloud#320).
6
- #
7
- # can_write_reserved_labels gates who may introduce or change labels in
8
- # the reserved stigmer.ai/* namespace at client-facing write boundaries
9
- # (GuardReservedLabelsStep). It derives from the platform operator role
10
- # — the seeding machine account holds it, ordinary tenants (even org
11
- # owners) never do, regardless of what they own.
12
- #
13
- # Run with:
14
- # fga model test --tests reserved-label-writer.fga.yaml
15
- name: reserved-label-writer
16
- model_file: ../model/fga.mod
17
-
18
- tuples:
19
- # The bootstrap machine account is the platform operator
20
- # (BootstrapIdentitySeeder re-asserts this tuple on every boot).
21
- - user: identity_account:machine
22
- relation: operator
23
- object: platform:stigmer
24
-
25
- # A tenant org owner — owns everything in their org, nothing on the
26
- # platform.
27
- - user: identity_account:mallory
28
- relation: owner
29
- object: organization:acme
30
-
31
- tests:
32
- - name: operator may write reserved labels, tenants may not
33
- check:
34
- - user: identity_account:machine
35
- object: platform:stigmer
36
- assertions:
37
- can_write_reserved_labels: true
38
- - user: identity_account:mallory
39
- object: platform:stigmer
40
- assertions:
41
- can_write_reserved_labels: false
@@ -1,113 +0,0 @@
1
- # Pinned copy of stigmer-cloud backend/services/stigmer-server/fga/tests/schedule-owner.fga.yaml
2
- # at commit b87dd1170 (the OpenFGA store test the cloud runs against its live model).
3
- # The body below is byte-identical to the source; the cloud re-runs the LIVE
4
- # file against this evaluator at the re-pin, so a stale copy is caught there.
5
- # Schedules are owner-scoped operational config (whatsapp-proactive-
6
- # messaging DD-008/DD-009, cloned from the agent_channel model): the
7
- # creator owns the schedule; view/edit/delete require ownership or an
8
- # explicit grant. Plain org members get NO implicit access — a schedule's
9
- # levers are billing-affecting (every fire spends the owning org's
10
- # credits, unattended). Creation is target-gated (can_edit on the
11
- # referenced agent, checked in-handler), so no organization-level
12
- # can_create_schedule relation exists to test.
13
- #
14
- # Org ADMINS inherit owner (T08, consistent with agents and channels — an
15
- # admin who can edit the agent can manage its schedules). The narrowness
16
- # these tests pin: owner + admins have control, granted viewers read,
17
- # plain members have nothing.
18
- #
19
- # Run: fga model test --tests schedule-owner.fga.yaml
20
-
21
- name: schedule-owner
22
- model_file: ../model/fga.mod
23
-
24
- tuples:
25
- # Org membership for both accounts — proving membership grants nothing.
26
- - user: identity_account:alice
27
- relation: member
28
- object: organization:acme
29
- - user: identity_account:mallory
30
- relation: member
31
- object: organization:acme
32
-
33
- # Org admin — proving T08 inheritance reaches schedules.
34
- - user: identity_account:ana
35
- relation: admin
36
- object: organization:acme
37
-
38
- # The schedule, created by alice (the config-driven create tuples).
39
- - user: organization:acme
40
- relation: organization
41
- object: schedule:daily-fee-reminders
42
- - user: identity_account:alice
43
- relation: owner
44
- object: schedule:daily-fee-reminders
45
-
46
- # An explicit viewer grant to carol (not even an org member).
47
- - user: identity_account:carol
48
- relation: viewer
49
- object: schedule:daily-fee-reminders
50
-
51
- tests:
52
- - name: owner has full control including grant management
53
- check:
54
- - user: identity_account:alice
55
- object: schedule:daily-fee-reminders
56
- assertions:
57
- can_view: true
58
- can_edit: true
59
- can_delete: true
60
- can_grant_access: true
61
- can_view_access: true
62
-
63
- - name: explicitly granted viewer can read but not mutate
64
- check:
65
- - user: identity_account:carol
66
- object: schedule:daily-fee-reminders
67
- assertions:
68
- can_view: true
69
- can_edit: false
70
- can_delete: false
71
- can_grant_access: false
72
- can_view_access: true
73
-
74
- - name: fellow org member has no implicit access
75
- check:
76
- - user: identity_account:mallory
77
- object: schedule:daily-fee-reminders
78
- assertions:
79
- can_view: false
80
- can_edit: false
81
- can_delete: false
82
- can_grant_access: false
83
- can_view_access: false
84
-
85
- - name: org admin inherits schedule management (T08)
86
- check:
87
- - user: identity_account:ana
88
- object: schedule:daily-fee-reminders
89
- assertions:
90
- can_view: true
91
- can_edit: true
92
- can_delete: true
93
- can_grant_access: true
94
-
95
- - name: listing schedules reflects ownership and grants, not membership
96
- list_objects:
97
- - user: identity_account:alice
98
- type: schedule
99
- assertions:
100
- can_view:
101
- - schedule:daily-fee-reminders
102
- can_edit:
103
- - schedule:daily-fee-reminders
104
- - user: identity_account:carol
105
- type: schedule
106
- assertions:
107
- can_view:
108
- - schedule:daily-fee-reminders
109
- can_edit: []
110
- - user: identity_account:mallory
111
- type: schedule
112
- assertions:
113
- can_view: []
@@ -1,214 +0,0 @@
1
- # Pinned copy of stigmer-cloud backend/services/stigmer-server/fga/tests/schedule-session-visibility.fga.yaml
2
- # at commit b87dd1170 (the OpenFGA store test the cloud runs against its live model).
3
- # The body below is byte-identical to the source; the cloud re-runs the LIVE
4
- # file against this evaluator at the re-pin, so a stale copy is caught there.
5
- # Store tests for schedule-session read-only observability (the session
6
- # `schedule` structural link — project DD-012 D-E, the channel-session
7
- # idiom's second application).
8
- #
9
- # A session created by the schedule runtime carries a single
10
- # session#schedule@schedule:<id>
11
- # tuple and inherits the schedule's viewer set (creator owner + org admins
12
- # via `admin from organization` on schedule + explicit grantees) into
13
- # can_view ONLY — `viewer from schedule` is composed into session.can_view,
14
- # deliberately NOT into session.viewer, so schedule observers never gain
15
- # can_create_execution_in / can_edit / can_delete / can_grant_access
16
- # (injecting a console message into an unattended run is not
17
- # observability). Executions follow through agent_execution's
18
- # `can_view: viewer or can_view from session`.
19
- #
20
- # The personal-session invariant is untouched: console sessions never carry
21
- # a schedule tuple, so `viewer from schedule` resolves to nothing for them
22
- # (pinned below and by session-personal-resource.fga.yaml).
23
- #
24
- # Run with:
25
- # fga model test --tests schedule-session-visibility.fga.yaml
26
- #
27
- # Scenario: org "acme" has admin alice, member bob (who created the
28
- # fee-reminder schedule and owns it), member carol (no relation to the
29
- # schedule), and member dave (an explicit schedule viewer grant — the
30
- # console "share this schedule" affordance). "rival" is another org whose
31
- # admin eve must see nothing. The schedule session is owned by acme's
32
- # system-schedule account; bob also has a normal personal console session
33
- # to prove the invariant.
34
- name: schedule-session-visibility
35
- model_file: ../model/fga.mod
36
-
37
- tuples:
38
- # --- Org roles ---
39
- - user: identity_account:alice
40
- relation: admin
41
- object: organization:acme
42
- - user: identity_account:bob
43
- relation: member
44
- object: organization:acme
45
- - user: identity_account:carol
46
- relation: member
47
- object: organization:acme
48
- - user: identity_account:dave
49
- relation: member
50
- object: organization:acme
51
- - user: identity_account:eve
52
- relation: admin
53
- object: organization:rival
54
-
55
- # --- The Schedule (tuples written on create: org link + creator owner) ---
56
- - user: organization:acme
57
- relation: organization
58
- object: schedule:fee-reminder
59
- - user: identity_account:bob
60
- relation: owner
61
- object: schedule:fee-reminder
62
- # dave's explicit viewer grant on the schedule (never on the session):
63
- - user: identity_account:dave
64
- relation: viewer
65
- object: schedule:fee-reminder
66
-
67
- # --- The schedule session (owned by the org's system-schedule account) ---
68
- - user: organization:acme
69
- relation: organization
70
- object: session:scheduled-run
71
- - user: identity_account:sys-schedule-acme
72
- relation: owner
73
- object: session:scheduled-run
74
- # The structural link written by ScheduleSessionLinkStep:
75
- - user: schedule:fee-reminder
76
- relation: schedule
77
- object: session:scheduled-run
78
-
79
- # --- An execution inside the schedule session ---
80
- - user: session:scheduled-run
81
- relation: session
82
- object: agent_execution:scheduled-run-1
83
-
84
- # --- bob's ordinary personal console session (NO schedule tuple) ---
85
- - user: organization:acme
86
- relation: organization
87
- object: session:bobs-chat
88
- - user: identity_account:bob
89
- relation: owner
90
- object: session:bobs-chat
91
- - user: session:bobs-chat
92
- relation: session
93
- object: agent_execution:bobs-run-1
94
-
95
- tests:
96
- - name: schedule creator can view the run but only view it
97
- check:
98
- - user: identity_account:bob
99
- object: session:scheduled-run
100
- assertions:
101
- can_view: true
102
- can_create_execution_in: false
103
- can_edit: false
104
- can_delete: false
105
- can_grant_access: false
106
- can_view_access: false
107
-
108
- - name: org admin inherits view through the schedule, read-only
109
- check:
110
- - user: identity_account:alice
111
- object: session:scheduled-run
112
- assertions:
113
- can_view: true
114
- can_create_execution_in: false
115
- can_edit: false
116
- can_delete: false
117
- can_grant_access: false
118
-
119
- - name: plain org member without schedule access sees nothing
120
- check:
121
- - user: identity_account:carol
122
- object: session:scheduled-run
123
- assertions:
124
- can_view: false
125
- can_create_execution_in: false
126
-
127
- - name: another org's admin sees nothing
128
- check:
129
- - user: identity_account:eve
130
- object: session:scheduled-run
131
- assertions:
132
- can_view: false
133
-
134
- - name: the system-schedule account keeps full session ownership
135
- check:
136
- - user: identity_account:sys-schedule-acme
137
- object: session:scheduled-run
138
- assertions:
139
- can_view: true
140
- can_create_execution_in: true
141
- can_edit: true
142
- can_delete: true
143
-
144
- - name: executions inherit read-only schedule observability
145
- check:
146
- - user: identity_account:bob
147
- object: agent_execution:scheduled-run-1
148
- assertions:
149
- can_view: true
150
- can_edit: false
151
- - user: identity_account:alice
152
- object: agent_execution:scheduled-run-1
153
- assertions:
154
- can_view: true
155
- can_edit: false
156
- - user: identity_account:carol
157
- object: agent_execution:scheduled-run-1
158
- assertions:
159
- can_view: false
160
-
161
- - name: an explicit schedule viewer grant reaches the run read-only
162
- check:
163
- # dave holds schedule viewer only — he can open the runs, still
164
- # read-only, and gains nothing on the schedule's management levers.
165
- - user: identity_account:dave
166
- object: session:scheduled-run
167
- assertions:
168
- can_view: true
169
- can_create_execution_in: false
170
- can_edit: false
171
- - user: identity_account:dave
172
- object: agent_execution:scheduled-run-1
173
- assertions:
174
- can_view: true
175
- can_edit: false
176
-
177
- - name: personal-session invariant is untouched by the schedule model
178
- check:
179
- # Admin still has no path into a console session (no schedule tuple).
180
- - user: identity_account:alice
181
- object: session:bobs-chat
182
- assertions:
183
- can_view: false
184
- can_edit: false
185
- can_delete: false
186
- - user: identity_account:alice
187
- object: agent_execution:bobs-run-1
188
- assertions:
189
- can_view: false
190
- # And the owner's own access is unchanged.
191
- - user: identity_account:bob
192
- object: session:bobs-chat
193
- assertions:
194
- can_view: true
195
- can_edit: true
196
- can_create_execution_in: true
197
-
198
- - name: list viewable sessions resolves the schedule chain
199
- list_objects:
200
- - user: identity_account:alice
201
- type: session
202
- assertions:
203
- can_view:
204
- - session:scheduled-run
205
- - user: identity_account:bob
206
- type: session
207
- assertions:
208
- can_view:
209
- - session:scheduled-run
210
- - session:bobs-chat
211
- - user: identity_account:carol
212
- type: session
213
- assertions:
214
- can_view: []
@@ -1,117 +0,0 @@
1
- # Pinned copy of stigmer-cloud backend/services/stigmer-server/fga/tests/session-personal-resource.fga.yaml
2
- # at commit b87dd1170 (the OpenFGA store test the cloud runs against its live model).
3
- # The body below is byte-identical to the source; the cloud re-runs the LIVE
4
- # file against this evaluator at the re-pin, so a stale copy is caught there.
5
- # Store tests for the session personal-resource model, including owner
6
- # deletability (2026-07-08-owner-session-delete changelog entry).
7
- #
8
- # Sessions are always private: no visibility tuples are ever written, so
9
- # access is owner + explicit viewer grants only. Org admins have no implicit
10
- # access, and platform operators have no session-delete override — the
11
- # platform-level can_delete_session relation was removed in favor of
12
- # `can_delete: owner` on the session itself (deletion no longer threatens
13
- # the billing trail; usage records are immutable and denormalized).
14
- #
15
- # Agent executions inherit ALL access from their parent session
16
- # (`owner from session`), so the execution assertions here pin the
17
- # inheritance that session cascade-delete relies on.
18
- #
19
- # Run with:
20
- # fga model test --tests session-personal-resource.fga.yaml
21
- #
22
- # Scenario: org "acme" has admin alice, member bob (session creator), and
23
- # member carol. dana is a platform operator with no relation to the session.
24
- name: session-personal-resource
25
- model_file: ../model/fga.mod
26
-
27
- tuples:
28
- # --- Org roles ---
29
- - user: identity_account:alice
30
- relation: admin
31
- object: organization:acme
32
- - user: identity_account:bob
33
- relation: member
34
- object: organization:acme
35
- - user: identity_account:carol
36
- relation: member
37
- object: organization:acme
38
-
39
- # --- Platform operator (no relation to the session) ---
40
- - user: identity_account:dana
41
- relation: operator
42
- object: platform:stigmer
43
-
44
- # --- bob's session (tuples written on create) ---
45
- - user: organization:acme
46
- relation: organization
47
- object: session:bobs-chat
48
- - user: identity_account:bob
49
- relation: owner
50
- object: session:bobs-chat
51
-
52
- # --- carol holds an explicit viewer grant on the session ---
53
- - user: identity_account:carol
54
- relation: viewer
55
- object: session:bobs-chat
56
-
57
- # --- an execution inside the session ---
58
- - user: session:bobs-chat
59
- relation: session
60
- object: agent_execution:run-1
61
-
62
- tests:
63
- - name: owner has full control including delete
64
- check:
65
- - user: identity_account:bob
66
- object: session:bobs-chat
67
- assertions:
68
- can_view: true
69
- can_edit: true
70
- can_delete: true
71
- can_create_execution_in: true
72
- can_grant_access: true
73
-
74
- - name: explicit viewer can view and run, but not edit or delete
75
- check:
76
- - user: identity_account:carol
77
- object: session:bobs-chat
78
- assertions:
79
- can_view: true
80
- can_create_execution_in: true
81
- can_edit: false
82
- can_delete: false
83
- can_grant_access: false
84
-
85
- - name: org admin has no implicit access to a personal session
86
- check:
87
- - user: identity_account:alice
88
- object: session:bobs-chat
89
- assertions:
90
- can_view: false
91
- can_edit: false
92
- can_delete: false
93
-
94
- - name: platform operator has no session-delete override
95
- check:
96
- - user: identity_account:dana
97
- object: session:bobs-chat
98
- assertions:
99
- can_view: false
100
- can_delete: false
101
-
102
- - name: execution access is inherited from the parent session
103
- check:
104
- - user: identity_account:bob
105
- object: agent_execution:run-1
106
- assertions:
107
- can_view: true
108
- can_edit: true
109
- - user: identity_account:carol
110
- object: agent_execution:run-1
111
- assertions:
112
- can_view: true
113
- can_edit: false
114
- - user: identity_account:alice
115
- object: agent_execution:run-1
116
- assertions:
117
- can_view: false
@@ -1,190 +0,0 @@
1
- # Pinned copy of stigmer-cloud backend/services/stigmer-server/fga/tests/workflow-execution-sharing.fga.yaml
2
- # as changed by stigmer-cloud#765 (the OpenFGA store test the cloud runs against its live model).
3
- # The body below is byte-identical to the source; the cloud re-runs the LIVE
4
- # file against this evaluator at the re-pin, so a stale copy is caught there.
5
- # Store tests for workflow_execution sharing and run observability.
6
- #
7
- # Two independent axes govern who can read a run's inputs/outputs:
8
- #
9
- # 1. Per-execution sharing — the triggerer (owner) grants viewer on a single
10
- # workflow_execution. Enabled by the new can_grant_access / can_view_access
11
- # relations (mirrors session.fga).
12
- # 2. Instance-level run observability — opt-in via the workflow_instance's
13
- # `execution_viewer` relation, inherited by every execution through
14
- # `viewer = ... or execution_viewer from workflow_instance`.
15
- #
16
- # The critical invariant: making an instance org-RUNNABLE (instance#viewer for
17
- # org members) must NOT leak run history. Only execution_viewer does that.
18
- #
19
- # Run with:
20
- # fga model test --tests workflow-execution-sharing.fga.yaml
21
- #
22
- # Scenario: org "acme" with members alice (triggerer), bob, carol; outsider
23
- # org with member mallory. inst1 is org-runnable but keeps runs private; inst2
24
- # opts into org-wide run observability.
25
- name: workflow-execution-sharing
26
- model_file: ../model/fga.mod
27
-
28
- tuples:
29
- # --- Org memberships ---
30
- - user: identity_account:alice
31
- relation: member
32
- object: organization:acme
33
- - user: identity_account:bob
34
- relation: member
35
- object: organization:acme
36
- - user: identity_account:carol
37
- relation: member
38
- object: organization:acme
39
- - user: identity_account:vera
40
- relation: viewer
41
- object: organization:acme
42
- - user: identity_account:mallory
43
- relation: member
44
- object: organization:outsider
45
-
46
- # --- inst1: ORG-RUNNABLE instance, runs stay PRIVATE (no execution_viewer) ---
47
- - user: organization:acme
48
- relation: organization
49
- object: workflow_instance:inst1
50
- - user: identity_account:alice
51
- relation: owner
52
- object: workflow_instance:inst1
53
- # Everyone in the org can SEE the instance (cloud#257 viewer shape;
54
- # RUNNING it is additionally gated in Java on can_create_execution_in)...
55
- - user: organization:acme#viewer
56
- relation: viewer
57
- object: workflow_instance:inst1
58
- # ...but NO execution_viewer tuple, so run history is not shared.
59
-
60
- # run1: alice's run on inst1, no explicit grants.
61
- - user: organization:acme
62
- relation: organization
63
- object: workflow_execution:run1
64
- - user: workflow_instance:inst1
65
- relation: workflow_instance
66
- object: workflow_execution:run1
67
- - user: identity_account:alice
68
- relation: owner
69
- object: workflow_execution:run1
70
-
71
- # run1b: alice's run on inst1, explicitly shared with bob (per-execution).
72
- - user: organization:acme
73
- relation: organization
74
- object: workflow_execution:run1b
75
- - user: workflow_instance:inst1
76
- relation: workflow_instance
77
- object: workflow_execution:run1b
78
- - user: identity_account:alice
79
- relation: owner
80
- object: workflow_execution:run1b
81
- - user: identity_account:bob
82
- relation: viewer
83
- object: workflow_execution:run1b
84
-
85
- # --- inst2: opts into ORG-WIDE run observability (execution_viewer) ---
86
- - user: organization:acme
87
- relation: organization
88
- object: workflow_instance:inst2
89
- - user: identity_account:alice
90
- relation: owner
91
- object: workflow_instance:inst2
92
- - user: organization:acme#viewer
93
- relation: execution_viewer
94
- object: workflow_instance:inst2
95
-
96
- # run2: alice's run on inst2.
97
- - user: organization:acme
98
- relation: organization
99
- object: workflow_execution:run2
100
- - user: workflow_instance:inst2
101
- relation: workflow_instance
102
- object: workflow_execution:run2
103
- - user: identity_account:alice
104
- relation: owner
105
- object: workflow_execution:run2
106
-
107
- tests:
108
- - name: triggerer always sees and can manage sharing of their own run
109
- check:
110
- - user: identity_account:alice
111
- object: workflow_execution:run1
112
- assertions:
113
- can_view: true
114
- can_grant_access: true
115
- can_view_access: true
116
-
117
- - name: org-runnable instance does NOT leak run history to teammates
118
- check:
119
- # bob and carol can see/run inst1, but cannot read alice's run1.
120
- - user: identity_account:bob
121
- object: workflow_execution:run1
122
- assertions:
123
- can_view: false
124
- can_view_access: false
125
- - user: identity_account:carol
126
- object: workflow_execution:run1
127
- assertions:
128
- can_view: false
129
-
130
- - name: per-execution share grants exactly the named teammate
131
- check:
132
- - user: identity_account:bob
133
- object: workflow_execution:run1b
134
- assertions:
135
- can_view: true
136
- can_view_access: true
137
- # A viewer cannot re-share (only the owner can grant).
138
- - user: identity_account:bob
139
- object: workflow_execution:run1b
140
- assertions:
141
- can_grant_access: false
142
- # Another org member not on the grant sees nothing.
143
- - user: identity_account:carol
144
- object: workflow_execution:run1b
145
- assertions:
146
- can_view: false
147
-
148
- - name: instance execution_viewer opt-in shares all runs org-wide
149
- check:
150
- - user: identity_account:bob
151
- object: workflow_execution:run2
152
- assertions:
153
- can_view: true
154
- - user: identity_account:carol
155
- object: workflow_execution:run2
156
- assertions:
157
- can_view: true
158
- # cloud#257: run observability is a pure read grant, so the org's
159
- # read-only viewers are exactly its audience.
160
- - user: identity_account:vera
161
- object: workflow_execution:run2
162
- assertions:
163
- can_view: true
164
- # Outsiders never gain access through org-scoped observability.
165
- - user: identity_account:mallory
166
- object: workflow_execution:run2
167
- assertions:
168
- can_view: false
169
-
170
- - name: run privacy holds against org viewers exactly as against members
171
- check:
172
- # No execution_viewer opt-in on inst1 → vera reads the instance but
173
- # never alice's run history.
174
- - user: identity_account:vera
175
- object: workflow_instance:inst1
176
- assertions:
177
- can_view: true
178
- - user: identity_account:vera
179
- object: workflow_execution:run1
180
- assertions:
181
- can_view: false
182
-
183
- - name: list a teammate's viewable runs reflects both sharing axes
184
- list_objects:
185
- - user: identity_account:bob
186
- type: workflow_execution
187
- assertions:
188
- can_view:
189
- - workflow_execution:run1b
190
- - workflow_execution:run2