@stigmer/server 3.27.2 → 3.29.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.
- package/README.md +2 -0
- package/dist/authorization/authorizer.d.ts +3 -3
- package/dist/authorization/authorizer.js +3 -3
- package/dist/authorization/derived-tuples.js +6 -1
- package/dist/authorization/derived-tuples.js.map +1 -1
- package/dist/authorization/evaluator.d.ts +9 -10
- package/dist/authorization/evaluator.d.ts.map +1 -1
- package/dist/authorization/evaluator.js.map +1 -1
- package/dist/authorization/list-read-scope.d.ts.map +1 -1
- package/dist/authorization/list-read-scope.js +29 -18
- package/dist/authorization/list-read-scope.js.map +1 -1
- package/dist/authorization/model/bindings.d.ts +41 -0
- package/dist/authorization/model/bindings.d.ts.map +1 -0
- package/dist/authorization/model/bindings.js +89 -0
- package/dist/authorization/model/bindings.js.map +1 -0
- package/dist/authorization/model/data/authorization-model.json +3141 -0
- package/dist/authorization/model/default-of.d.ts +2 -2
- package/dist/authorization/model/execution-viewer.d.ts +3 -0
- package/dist/authorization/model/execution-viewer.d.ts.map +1 -0
- package/dist/authorization/model/execution-viewer.js +50 -0
- package/dist/authorization/model/execution-viewer.js.map +1 -0
- package/dist/authorization/model/index.d.ts +33 -21
- package/dist/authorization/model/index.d.ts.map +1 -1
- package/dist/authorization/model/index.js +74 -52
- package/dist/authorization/model/index.js.map +1 -1
- package/dist/authorization/model/openfga-json.d.ts +18 -0
- package/dist/authorization/model/openfga-json.d.ts.map +1 -0
- package/dist/authorization/model/openfga-json.js +266 -0
- package/dist/authorization/model/openfga-json.js.map +1 -0
- package/dist/authorization/model/rewrite.d.ts +39 -67
- package/dist/authorization/model/rewrite.d.ts.map +1 -1
- package/dist/authorization/model/rewrite.js +1 -117
- package/dist/authorization/model/rewrite.js.map +1 -1
- package/dist/authorization/strict-json.d.ts +20 -0
- package/dist/authorization/strict-json.d.ts.map +1 -0
- package/dist/authorization/strict-json.js +45 -0
- package/dist/authorization/strict-json.js.map +1 -0
- package/dist/boot/compose.d.ts.map +1 -1
- package/dist/boot/compose.js +9 -7
- package/dist/boot/compose.js.map +1 -1
- package/dist/domain/workflowexecution/list-index.d.ts +1 -1
- package/dist/extensions/list-read-scope.d.ts +20 -3
- package/dist/extensions/list-read-scope.d.ts.map +1 -1
- package/dist/extensions/list-read-scope.js +20 -1
- package/dist/extensions/list-read-scope.js.map +1 -1
- package/dist/index.d.ts +7 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -5
- package/dist/index.js.map +1 -1
- package/package.json +7 -6
- package/src/authorization/README.md +41 -34
- package/src/authorization/__tests__/authorizer.test.ts +5 -14
- package/src/authorization/__tests__/derived-tuples.test.ts +29 -27
- package/src/authorization/__tests__/evaluator.test.ts +53 -160
- package/src/authorization/__tests__/facts.test.ts +5 -11
- package/src/authorization/__tests__/list-read-scope.measure.test.ts +12 -20
- package/src/authorization/__tests__/list-read-scope.test.ts +15 -14
- package/src/authorization/__tests__/organization-directory.test.ts +2 -2
- package/src/authorization/__tests__/store-test-kit.ts +246 -0
- package/src/authorization/__tests__/store-tests.test.ts +92 -223
- package/src/authorization/__tests__/support.ts +30 -2
- package/src/authorization/__tests__/throwaway-model.ts +75 -0
- package/src/authorization/__tests__/wire-permissions.test.ts +141 -107
- package/src/authorization/authorizer.ts +3 -3
- package/src/authorization/derived-tuples.ts +7 -2
- package/src/authorization/evaluator.ts +8 -10
- package/src/authorization/list-read-scope.ts +37 -22
- package/src/authorization/model/__tests__/openfga-json.test.ts +353 -0
- package/src/authorization/model/__tests__/registry.test.ts +345 -277
- package/src/authorization/model/bindings.ts +131 -0
- package/src/authorization/model/data/authorization-model.json +3141 -0
- package/src/authorization/model/default-of.ts +2 -2
- package/src/authorization/model/execution-viewer.ts +56 -0
- package/src/authorization/model/index.ts +81 -72
- package/src/authorization/model/openfga-json.ts +310 -0
- package/src/authorization/model/rewrite.ts +39 -188
- package/src/authorization/strict-json.ts +52 -0
- package/src/boot/compose.ts +9 -7
- package/src/extensions/__tests__/built-in-authorization-composed.test.ts +3 -6
- package/src/extensions/list-read-scope.ts +32 -4
- package/src/index.ts +15 -44
- package/dist/authorization/model/agent.d.ts +0 -2
- package/dist/authorization/model/agent.d.ts.map +0 -1
- package/dist/authorization/model/agent.js +0 -43
- package/dist/authorization/model/agent.js.map +0 -1
- package/dist/authorization/model/agent_channel.d.ts +0 -2
- package/dist/authorization/model/agent_channel.d.ts.map +0 -1
- package/dist/authorization/model/agent_channel.js +0 -39
- package/dist/authorization/model/agent_channel.js.map +0 -1
- package/dist/authorization/model/agent_execution.d.ts +0 -2
- package/dist/authorization/model/agent_execution.d.ts.map +0 -1
- package/dist/authorization/model/agent_execution.js +0 -25
- package/dist/authorization/model/agent_execution.js.map +0 -1
- package/dist/authorization/model/agent_instance.d.ts +0 -2
- package/dist/authorization/model/agent_instance.d.ts.map +0 -1
- package/dist/authorization/model/agent_instance.js +0 -48
- package/dist/authorization/model/agent_instance.js.map +0 -1
- package/dist/authorization/model/agent_share.d.ts +0 -2
- package/dist/authorization/model/agent_share.d.ts.map +0 -1
- package/dist/authorization/model/agent_share.js +0 -29
- package/dist/authorization/model/agent_share.js.map +0 -1
- package/dist/authorization/model/api_key.d.ts +0 -2
- package/dist/authorization/model/api_key.d.ts.map +0 -1
- package/dist/authorization/model/api_key.js +0 -27
- package/dist/authorization/model/api_key.js.map +0 -1
- package/dist/authorization/model/artifact.d.ts +0 -2
- package/dist/authorization/model/artifact.d.ts.map +0 -1
- package/dist/authorization/model/artifact.js +0 -27
- package/dist/authorization/model/artifact.js.map +0 -1
- package/dist/authorization/model/channel_app.d.ts +0 -2
- package/dist/authorization/model/channel_app.d.ts.map +0 -1
- package/dist/authorization/model/channel_app.js +0 -28
- package/dist/authorization/model/channel_app.js.map +0 -1
- package/dist/authorization/model/environment.d.ts +0 -2
- package/dist/authorization/model/environment.d.ts.map +0 -1
- package/dist/authorization/model/environment.js +0 -33
- package/dist/authorization/model/environment.js.map +0 -1
- package/dist/authorization/model/execution_context.d.ts +0 -2
- package/dist/authorization/model/execution_context.d.ts.map +0 -1
- package/dist/authorization/model/execution_context.js +0 -19
- package/dist/authorization/model/execution_context.js.map +0 -1
- package/dist/authorization/model/iam_policy.d.ts +0 -2
- package/dist/authorization/model/iam_policy.d.ts.map +0 -1
- package/dist/authorization/model/iam_policy.js +0 -31
- package/dist/authorization/model/iam_policy.js.map +0 -1
- package/dist/authorization/model/identity_account.d.ts +0 -2
- package/dist/authorization/model/identity_account.d.ts.map +0 -1
- package/dist/authorization/model/identity_account.js +0 -25
- package/dist/authorization/model/identity_account.js.map +0 -1
- package/dist/authorization/model/mcp_server.d.ts +0 -2
- package/dist/authorization/model/mcp_server.d.ts.map +0 -1
- package/dist/authorization/model/mcp_server.js +0 -38
- package/dist/authorization/model/mcp_server.js.map +0 -1
- package/dist/authorization/model/memory.d.ts +0 -2
- package/dist/authorization/model/memory.d.ts.map +0 -1
- package/dist/authorization/model/memory.js +0 -26
- package/dist/authorization/model/memory.js.map +0 -1
- package/dist/authorization/model/oauth_app.d.ts +0 -2
- package/dist/authorization/model/oauth_app.d.ts.map +0 -1
- package/dist/authorization/model/oauth_app.js +0 -31
- package/dist/authorization/model/oauth_app.js.map +0 -1
- package/dist/authorization/model/organization.d.ts +0 -2
- package/dist/authorization/model/organization.d.ts.map +0 -1
- package/dist/authorization/model/organization.js +0 -58
- package/dist/authorization/model/organization.js.map +0 -1
- package/dist/authorization/model/platform_client.d.ts +0 -2
- package/dist/authorization/model/platform_client.d.ts.map +0 -1
- package/dist/authorization/model/platform_client.js +0 -31
- package/dist/authorization/model/platform_client.js.map +0 -1
- package/dist/authorization/model/plugin.d.ts +0 -2
- package/dist/authorization/model/plugin.d.ts.map +0 -1
- package/dist/authorization/model/plugin.js +0 -45
- package/dist/authorization/model/plugin.js.map +0 -1
- package/dist/authorization/model/schedule.d.ts +0 -2
- package/dist/authorization/model/schedule.d.ts.map +0 -1
- package/dist/authorization/model/schedule.js +0 -34
- package/dist/authorization/model/schedule.js.map +0 -1
- package/dist/authorization/model/session.d.ts +0 -2
- package/dist/authorization/model/session.d.ts.map +0 -1
- package/dist/authorization/model/session.js +0 -38
- package/dist/authorization/model/session.js.map +0 -1
- package/dist/authorization/model/skill.d.ts +0 -2
- package/dist/authorization/model/skill.d.ts.map +0 -1
- package/dist/authorization/model/skill.js +0 -39
- package/dist/authorization/model/skill.js.map +0 -1
- package/dist/authorization/model/workflow.d.ts +0 -2
- package/dist/authorization/model/workflow.d.ts.map +0 -1
- package/dist/authorization/model/workflow.js +0 -39
- package/dist/authorization/model/workflow.js.map +0 -1
- package/dist/authorization/model/workflow_execution.d.ts +0 -2
- package/dist/authorization/model/workflow_execution.d.ts.map +0 -1
- package/dist/authorization/model/workflow_execution.js +0 -33
- package/dist/authorization/model/workflow_execution.js.map +0 -1
- package/dist/authorization/model/workflow_instance.d.ts +0 -2
- package/dist/authorization/model/workflow_instance.d.ts.map +0 -1
- package/dist/authorization/model/workflow_instance.js +0 -96
- package/dist/authorization/model/workflow_instance.js.map +0 -1
- package/dist/authorization/store-test-kit.d.ts +0 -62
- package/dist/authorization/store-test-kit.d.ts.map +0 -1
- package/dist/authorization/store-test-kit.js +0 -265
- package/dist/authorization/store-test-kit.js.map +0 -1
- package/src/authorization/__tests__/enterprise-model.ts +0 -59
- package/src/authorization/__tests__/fixtures/fga/agent-channel-owner.fga.yaml +0 -112
- package/src/authorization/__tests__/fixtures/fga/agent-instance-creation.fga.yaml +0 -177
- package/src/authorization/__tests__/fixtures/fga/agent-share-owner.fga.yaml +0 -109
- package/src/authorization/__tests__/fixtures/fga/artifact-org-and-owner.fga.yaml +0 -128
- package/src/authorization/__tests__/fixtures/fga/blueprint-private-visibility.fga.yaml +0 -318
- package/src/authorization/__tests__/fixtures/fga/channel-app-owner.fga.yaml +0 -125
- package/src/authorization/__tests__/fixtures/fga/channel-participation.fga.yaml +0 -201
- package/src/authorization/__tests__/fixtures/fga/channel-session-visibility.fga.yaml +0 -187
- package/src/authorization/__tests__/fixtures/fga/default-instance-inheritance.fga.yaml +0 -214
- package/src/authorization/__tests__/fixtures/fga/mcp-server-authoring.fga.yaml +0 -129
- package/src/authorization/__tests__/fixtures/fga/memory-subject-only.fga.yaml +0 -72
- package/src/authorization/__tests__/fixtures/fga/org-admin-owner-inheritance.fga.yaml +0 -308
- package/src/authorization/__tests__/fixtures/fga/org-shared-environment.fga.yaml +0 -144
- package/src/authorization/__tests__/fixtures/fga/platform-visibility.fga.yaml +0 -199
- package/src/authorization/__tests__/fixtures/fga/provider-standing-viewer.fga.yaml +0 -40
- package/src/authorization/__tests__/fixtures/fga/reserved-label-writer.fga.yaml +0 -41
- package/src/authorization/__tests__/fixtures/fga/schedule-owner.fga.yaml +0 -113
- package/src/authorization/__tests__/fixtures/fga/schedule-session-visibility.fga.yaml +0 -214
- package/src/authorization/__tests__/fixtures/fga/session-personal-resource.fga.yaml +0 -117
- package/src/authorization/__tests__/fixtures/fga/workflow-execution-sharing.fga.yaml +0 -190
- package/src/authorization/model/agent.ts +0 -64
- package/src/authorization/model/agent_channel.ts +0 -57
- package/src/authorization/model/agent_execution.ts +0 -33
- package/src/authorization/model/agent_instance.ts +0 -66
- package/src/authorization/model/agent_share.ts +0 -40
- package/src/authorization/model/api_key.ts +0 -28
- package/src/authorization/model/artifact.ts +0 -38
- package/src/authorization/model/channel_app.ts +0 -39
- package/src/authorization/model/environment.ts +0 -48
- package/src/authorization/model/execution_context.ts +0 -20
- package/src/authorization/model/iam_policy.ts +0 -42
- package/src/authorization/model/identity_account.ts +0 -26
- package/src/authorization/model/mcp_server.ts +0 -59
- package/src/authorization/model/memory.ts +0 -27
- package/src/authorization/model/oauth_app.ts +0 -43
- package/src/authorization/model/organization.ts +0 -59
- package/src/authorization/model/platform_client.ts +0 -43
- package/src/authorization/model/plugin.ts +0 -66
- package/src/authorization/model/schedule.ts +0 -49
- package/src/authorization/model/session.ts +0 -50
- package/src/authorization/model/skill.ts +0 -60
- package/src/authorization/model/workflow.ts +0 -60
- package/src/authorization/model/workflow_execution.ts +0 -46
- package/src/authorization/model/workflow_instance.ts +0 -125
- package/src/authorization/store-test-kit.ts +0 -395
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
# Pinned copy of stigmer-cloud backend/services/stigmer-server/fga/tests/agent-share-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
|
-
# Agent shares are owner-scoped channel config (decision 011, D1):
|
|
6
|
-
# the creator owns the share; view/edit/delete/rotate require ownership or
|
|
7
|
-
# an explicit grant. Plain org members get NO implicit access, and —
|
|
8
|
-
# critically — no visitor-facing tuples exist at all: guest/member
|
|
9
|
-
# admission to the hosted chat is app-level (shared-profile, mint, and
|
|
10
|
-
# create-time gates), never FGA.
|
|
11
|
-
#
|
|
12
|
-
# T08: org ADMINS inherit owner (consistent with agents — an admin who can
|
|
13
|
-
# edit the agent can manage its channels). The narrowness these tests pin
|
|
14
|
-
# is now: owner + admins have control, granted viewers read, plain members
|
|
15
|
-
# have nothing.
|
|
16
|
-
|
|
17
|
-
name: agent-share-owner
|
|
18
|
-
model_file: ../model/fga.mod
|
|
19
|
-
|
|
20
|
-
tuples:
|
|
21
|
-
# Org membership for both accounts — proving membership grants nothing.
|
|
22
|
-
- user: identity_account:alice
|
|
23
|
-
relation: member
|
|
24
|
-
object: organization:acme
|
|
25
|
-
- user: identity_account:mallory
|
|
26
|
-
relation: member
|
|
27
|
-
object: organization:acme
|
|
28
|
-
|
|
29
|
-
# Org admin — proving T08 inheritance reaches shares.
|
|
30
|
-
- user: identity_account:ana
|
|
31
|
-
relation: admin
|
|
32
|
-
object: organization:acme
|
|
33
|
-
|
|
34
|
-
# The share, created by alice (the config-driven create tuples).
|
|
35
|
-
- user: organization:acme
|
|
36
|
-
relation: organization
|
|
37
|
-
object: agent_share:support-bot-share
|
|
38
|
-
- user: identity_account:alice
|
|
39
|
-
relation: owner
|
|
40
|
-
object: agent_share:support-bot-share
|
|
41
|
-
|
|
42
|
-
# An explicit viewer grant to carol (not even an org member).
|
|
43
|
-
- user: identity_account:carol
|
|
44
|
-
relation: viewer
|
|
45
|
-
object: agent_share:support-bot-share
|
|
46
|
-
|
|
47
|
-
tests:
|
|
48
|
-
- name: owner has full control including grant management
|
|
49
|
-
check:
|
|
50
|
-
- user: identity_account:alice
|
|
51
|
-
object: agent_share:support-bot-share
|
|
52
|
-
assertions:
|
|
53
|
-
can_view: true
|
|
54
|
-
can_edit: true
|
|
55
|
-
can_delete: true
|
|
56
|
-
can_grant_access: true
|
|
57
|
-
can_view_access: true
|
|
58
|
-
|
|
59
|
-
- name: explicitly granted viewer can read but not mutate
|
|
60
|
-
check:
|
|
61
|
-
- user: identity_account:carol
|
|
62
|
-
object: agent_share:support-bot-share
|
|
63
|
-
assertions:
|
|
64
|
-
can_view: true
|
|
65
|
-
can_edit: false
|
|
66
|
-
can_delete: false
|
|
67
|
-
can_grant_access: false
|
|
68
|
-
can_view_access: true
|
|
69
|
-
|
|
70
|
-
- name: fellow org member has no implicit access
|
|
71
|
-
check:
|
|
72
|
-
- user: identity_account:mallory
|
|
73
|
-
object: agent_share:support-bot-share
|
|
74
|
-
assertions:
|
|
75
|
-
can_view: false
|
|
76
|
-
can_edit: false
|
|
77
|
-
can_delete: false
|
|
78
|
-
can_grant_access: false
|
|
79
|
-
can_view_access: false
|
|
80
|
-
|
|
81
|
-
- name: org admin inherits share management (T08)
|
|
82
|
-
check:
|
|
83
|
-
- user: identity_account:ana
|
|
84
|
-
object: agent_share:support-bot-share
|
|
85
|
-
assertions:
|
|
86
|
-
can_view: true
|
|
87
|
-
can_edit: true
|
|
88
|
-
can_delete: true
|
|
89
|
-
can_grant_access: true
|
|
90
|
-
|
|
91
|
-
- name: listing shares reflects ownership and grants, not membership
|
|
92
|
-
list_objects:
|
|
93
|
-
- user: identity_account:alice
|
|
94
|
-
type: agent_share
|
|
95
|
-
assertions:
|
|
96
|
-
can_view:
|
|
97
|
-
- agent_share:support-bot-share
|
|
98
|
-
can_edit:
|
|
99
|
-
- agent_share:support-bot-share
|
|
100
|
-
- user: identity_account:carol
|
|
101
|
-
type: agent_share
|
|
102
|
-
assertions:
|
|
103
|
-
can_view:
|
|
104
|
-
- agent_share:support-bot-share
|
|
105
|
-
can_edit: []
|
|
106
|
-
- user: identity_account:mallory
|
|
107
|
-
type: agent_share
|
|
108
|
-
assertions:
|
|
109
|
-
can_view: []
|
|
@@ -1,128 +0,0 @@
|
|
|
1
|
-
# Pinned copy of stigmer-cloud backend/services/stigmer-server/fga/tests/artifact-org-and-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
|
-
# Artifacts are org-scoped execution outputs with creator ownership on
|
|
6
|
-
# top (cloud#216). The two access arms these tests pin:
|
|
7
|
-
#
|
|
8
|
-
# 1. Org inheritance — anyone who is at least a viewer of the owning org
|
|
9
|
-
# can view its artifacts ("if you can view resources in the org, you
|
|
10
|
-
# can view its artifacts"). Editing stays org-admin-only.
|
|
11
|
-
# 2. Creator ownership — the identity whose execution produced the
|
|
12
|
-
# artifact can view it WITHOUT any org role. This is the guest-share /
|
|
13
|
-
# embedded-user case: org guests are not org viewers, but their
|
|
14
|
-
# sessions render artifact-backed review payloads and artifact tabs.
|
|
15
|
-
#
|
|
16
|
-
# The narrowness pinned: creator-owners read but never edit (all guests
|
|
17
|
-
# of an org share one guest identity account — owner-edit would let one
|
|
18
|
-
# guest soft-delete another's artifacts), and no arm crosses org
|
|
19
|
-
# boundaries.
|
|
20
|
-
#
|
|
21
|
-
# Run: fga model test --tests artifact-org-and-owner.fga.yaml
|
|
22
|
-
|
|
23
|
-
name: artifact-org-and-owner
|
|
24
|
-
model_file: ../model/fga.mod
|
|
25
|
-
|
|
26
|
-
tuples:
|
|
27
|
-
# Org roles: victor views, ana administers acme. Rival org for the
|
|
28
|
-
# cross-org boundary.
|
|
29
|
-
- user: identity_account:victor
|
|
30
|
-
relation: viewer
|
|
31
|
-
object: organization:acme
|
|
32
|
-
- user: identity_account:ana
|
|
33
|
-
relation: admin
|
|
34
|
-
object: organization:acme
|
|
35
|
-
- user: identity_account:eve
|
|
36
|
-
relation: member
|
|
37
|
-
object: organization:rival
|
|
38
|
-
|
|
39
|
-
# Guest identity: an org GUEST, deliberately not an org viewer.
|
|
40
|
-
- user: identity_account:acme-guest
|
|
41
|
-
relation: guest
|
|
42
|
-
object: organization:acme
|
|
43
|
-
|
|
44
|
-
# Artifact produced by a signed-in member's execution.
|
|
45
|
-
- user: organization:acme
|
|
46
|
-
relation: organization
|
|
47
|
-
object: artifact:art_report
|
|
48
|
-
- user: identity_account:victor
|
|
49
|
-
relation: owner
|
|
50
|
-
object: artifact:art_report
|
|
51
|
-
|
|
52
|
-
# Artifact produced by a guest-share execution: creator is the guest
|
|
53
|
-
# identity account (runner tokens carry the acting identity as sub).
|
|
54
|
-
- user: organization:acme
|
|
55
|
-
relation: organization
|
|
56
|
-
object: artifact:art_guest_plan
|
|
57
|
-
- user: identity_account:acme-guest
|
|
58
|
-
relation: owner
|
|
59
|
-
object: artifact:art_guest_plan
|
|
60
|
-
|
|
61
|
-
tests:
|
|
62
|
-
- name: org viewer reads any org artifact but cannot edit
|
|
63
|
-
check:
|
|
64
|
-
- user: identity_account:victor
|
|
65
|
-
object: artifact:art_report
|
|
66
|
-
assertions:
|
|
67
|
-
can_view: true
|
|
68
|
-
can_edit: false
|
|
69
|
-
- user: identity_account:victor
|
|
70
|
-
object: artifact:art_guest_plan
|
|
71
|
-
assertions:
|
|
72
|
-
can_view: true
|
|
73
|
-
can_edit: false
|
|
74
|
-
|
|
75
|
-
- name: org admin views and edits org artifacts
|
|
76
|
-
check:
|
|
77
|
-
- user: identity_account:ana
|
|
78
|
-
object: artifact:art_report
|
|
79
|
-
assertions:
|
|
80
|
-
can_view: true
|
|
81
|
-
can_edit: true
|
|
82
|
-
|
|
83
|
-
- name: guest creator reads own execution's artifact via ownership, never edits
|
|
84
|
-
check:
|
|
85
|
-
- user: identity_account:acme-guest
|
|
86
|
-
object: artifact:art_guest_plan
|
|
87
|
-
assertions:
|
|
88
|
-
can_view: true
|
|
89
|
-
can_edit: false
|
|
90
|
-
|
|
91
|
-
- name: guest role alone grants nothing on other artifacts in the org
|
|
92
|
-
check:
|
|
93
|
-
- user: identity_account:acme-guest
|
|
94
|
-
object: artifact:art_report
|
|
95
|
-
assertions:
|
|
96
|
-
can_view: false
|
|
97
|
-
can_edit: false
|
|
98
|
-
|
|
99
|
-
- name: cross-org caller is denied everything
|
|
100
|
-
check:
|
|
101
|
-
- user: identity_account:eve
|
|
102
|
-
object: artifact:art_report
|
|
103
|
-
assertions:
|
|
104
|
-
can_view: false
|
|
105
|
-
can_edit: false
|
|
106
|
-
- user: identity_account:eve
|
|
107
|
-
object: artifact:art_guest_plan
|
|
108
|
-
assertions:
|
|
109
|
-
can_view: false
|
|
110
|
-
can_edit: false
|
|
111
|
-
|
|
112
|
-
- name: listing reflects org inheritance plus creator ownership
|
|
113
|
-
list_objects:
|
|
114
|
-
- user: identity_account:victor
|
|
115
|
-
type: artifact
|
|
116
|
-
assertions:
|
|
117
|
-
can_view:
|
|
118
|
-
- artifact:art_report
|
|
119
|
-
- artifact:art_guest_plan
|
|
120
|
-
- user: identity_account:acme-guest
|
|
121
|
-
type: artifact
|
|
122
|
-
assertions:
|
|
123
|
-
can_view:
|
|
124
|
-
- artifact:art_guest_plan
|
|
125
|
-
- user: identity_account:eve
|
|
126
|
-
type: artifact
|
|
127
|
-
assertions:
|
|
128
|
-
can_view: []
|
|
@@ -1,318 +0,0 @@
|
|
|
1
|
-
# Pinned copy of stigmer-cloud backend/services/stigmer-server/fga/tests/blueprint-private-visibility.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 real blueprint privacy (Phase 3 of the visibility model).
|
|
6
|
-
#
|
|
7
|
-
# Blueprint viewer relations no longer include the unconditional
|
|
8
|
-
# `viewer from organization` grant: a PRIVATE blueprint is invisible to the
|
|
9
|
-
# rest of its own org. Every broader level is an explicit tuple written by
|
|
10
|
-
# VisibilityTupleReconciler:
|
|
11
|
-
#
|
|
12
|
-
# ORG viewer@organization:<org>#viewer (the org's FULL read audience —
|
|
13
|
-
# every role satisfies organization#viewer, including read-only
|
|
14
|
-
# viewers; pre-cloud#257 tuples carried #member, which excluded
|
|
15
|
-
# viewer-role users — still honored until backfilled, see the
|
|
16
|
-
# legacy-bot fixture)
|
|
17
|
-
# PLATFORM platform_viewer@identity_provider:<idp>#platform_user + the ORG tuple
|
|
18
|
-
#
|
|
19
|
-
# Read vs spend: an org viewer-role user READS org-visible blueprints (and, at
|
|
20
|
-
# the model level, satisfies can_execute — run-what-you-can-read), but every
|
|
21
|
-
# spend path is gated in Java on the org-level can_create_session /
|
|
22
|
-
# can_create_execution_in permissions, which require member-or-guest. The
|
|
23
|
-
# vera assertions pin both halves of that contract.
|
|
24
|
-
#
|
|
25
|
-
# The ORG tuple rides along on PLATFORM (the "org floor") so a shared
|
|
26
|
-
# blueprint stays listable in its own org.
|
|
27
|
-
#
|
|
28
|
-
# T08 exception: org ADMINS (and org owners, via the role hierarchy) are
|
|
29
|
-
# composed into blueprint `owner` and therefore see, list, and manage
|
|
30
|
-
# PRIVATE blueprints — the GitHub-org-admin model. "Private is real" now
|
|
31
|
-
# means: invisible to plain members, never to org admins. Pinned by the
|
|
32
|
-
# oscar (org admin) assertions below.
|
|
33
|
-
#
|
|
34
|
-
# Run with:
|
|
35
|
-
# fga model test --tests blueprint-private-visibility.fga.yaml
|
|
36
|
-
#
|
|
37
|
-
# Scenario: org "acme" has owner-creator carol, org admin oscar, plain
|
|
38
|
-
# member dave, and read-only viewer vera (the role SSO auto-provisioning
|
|
39
|
-
# grants by default); mallory belongs to an unrelated org. Carol authors one
|
|
40
|
-
# blueprint of each kind at PRIVATE, plus an ORG agent and a legacy ORG
|
|
41
|
-
# agent whose tuple still carries the pre-cloud#257 shape.
|
|
42
|
-
name: blueprint-private-visibility
|
|
43
|
-
model_file: ../model/fga.mod
|
|
44
|
-
|
|
45
|
-
tuples:
|
|
46
|
-
# --- Org memberships ---
|
|
47
|
-
- user: identity_account:carol
|
|
48
|
-
relation: owner
|
|
49
|
-
object: organization:acme
|
|
50
|
-
- user: identity_account:oscar
|
|
51
|
-
relation: admin
|
|
52
|
-
object: organization:acme
|
|
53
|
-
- user: identity_account:dave
|
|
54
|
-
relation: member
|
|
55
|
-
object: organization:acme
|
|
56
|
-
- user: identity_account:vera
|
|
57
|
-
relation: viewer
|
|
58
|
-
object: organization:acme
|
|
59
|
-
- user: identity_account:mallory
|
|
60
|
-
relation: member
|
|
61
|
-
object: organization:outsider
|
|
62
|
-
|
|
63
|
-
# --- PRIVATE blueprints (no visibility tuples at all) ---
|
|
64
|
-
- user: organization:acme
|
|
65
|
-
relation: organization
|
|
66
|
-
object: agent:secret-bot
|
|
67
|
-
- user: identity_account:carol
|
|
68
|
-
relation: owner
|
|
69
|
-
object: agent:secret-bot
|
|
70
|
-
- user: organization:acme
|
|
71
|
-
relation: organization
|
|
72
|
-
object: skill:secret-notes
|
|
73
|
-
- user: identity_account:carol
|
|
74
|
-
relation: owner
|
|
75
|
-
object: skill:secret-notes
|
|
76
|
-
- user: organization:acme
|
|
77
|
-
relation: organization
|
|
78
|
-
object: workflow:secret-flow
|
|
79
|
-
- user: identity_account:carol
|
|
80
|
-
relation: owner
|
|
81
|
-
object: workflow:secret-flow
|
|
82
|
-
- user: organization:acme
|
|
83
|
-
relation: organization
|
|
84
|
-
object: mcp_server:secret-tools
|
|
85
|
-
- user: identity_account:carol
|
|
86
|
-
relation: owner
|
|
87
|
-
object: mcp_server:secret-tools
|
|
88
|
-
|
|
89
|
-
# --- ORG-visible agent (explicit org viewer tuple, cloud#257 shape) ---
|
|
90
|
-
- user: organization:acme
|
|
91
|
-
relation: organization
|
|
92
|
-
object: agent:team-bot
|
|
93
|
-
- user: identity_account:carol
|
|
94
|
-
relation: owner
|
|
95
|
-
object: agent:team-bot
|
|
96
|
-
- user: organization:acme#viewer
|
|
97
|
-
relation: viewer
|
|
98
|
-
object: agent:team-bot
|
|
99
|
-
|
|
100
|
-
# --- ORG-visible agent with the LEGACY pre-cloud#257 tuple shape ---
|
|
101
|
-
# Pins two transition facts until the boot backfill converges prod tuples:
|
|
102
|
-
# members must keep their access through the old shape, and viewer-role
|
|
103
|
-
# users are still refused by it (the cloud#257 defect, alive on legacy
|
|
104
|
-
# tuples only).
|
|
105
|
-
- user: organization:acme
|
|
106
|
-
relation: organization
|
|
107
|
-
object: agent:legacy-bot
|
|
108
|
-
- user: identity_account:carol
|
|
109
|
-
relation: owner
|
|
110
|
-
object: agent:legacy-bot
|
|
111
|
-
- user: organization:acme#member
|
|
112
|
-
relation: viewer
|
|
113
|
-
object: agent:legacy-bot
|
|
114
|
-
|
|
115
|
-
# --- PRIVATE agent with an explicit individual viewer grant ---
|
|
116
|
-
- user: organization:acme
|
|
117
|
-
relation: organization
|
|
118
|
-
object: agent:shared-secret
|
|
119
|
-
- user: identity_account:carol
|
|
120
|
-
relation: owner
|
|
121
|
-
object: agent:shared-secret
|
|
122
|
-
- user: identity_account:dave
|
|
123
|
-
relation: viewer
|
|
124
|
-
object: agent:shared-secret
|
|
125
|
-
|
|
126
|
-
tests:
|
|
127
|
-
- name: private blueprints are invisible to fellow org members (all four kinds)
|
|
128
|
-
check:
|
|
129
|
-
- user: identity_account:dave
|
|
130
|
-
object: agent:secret-bot
|
|
131
|
-
assertions:
|
|
132
|
-
can_view: false
|
|
133
|
-
can_execute: false
|
|
134
|
-
can_create_instance: false
|
|
135
|
-
can_clone: false
|
|
136
|
-
- user: identity_account:dave
|
|
137
|
-
object: skill:secret-notes
|
|
138
|
-
assertions:
|
|
139
|
-
can_view: false
|
|
140
|
-
can_use: false
|
|
141
|
-
- user: identity_account:dave
|
|
142
|
-
object: workflow:secret-flow
|
|
143
|
-
assertions:
|
|
144
|
-
can_view: false
|
|
145
|
-
can_execute: false
|
|
146
|
-
- user: identity_account:dave
|
|
147
|
-
object: mcp_server:secret-tools
|
|
148
|
-
assertions:
|
|
149
|
-
can_view: false
|
|
150
|
-
can_use: false
|
|
151
|
-
can_connect: false
|
|
152
|
-
|
|
153
|
-
- name: org admin sees and manages private blueprints of every kind (T08)
|
|
154
|
-
check:
|
|
155
|
-
- user: identity_account:oscar
|
|
156
|
-
object: agent:secret-bot
|
|
157
|
-
assertions:
|
|
158
|
-
can_view: true
|
|
159
|
-
can_edit: true
|
|
160
|
-
can_delete: true
|
|
161
|
-
can_execute: true
|
|
162
|
-
- user: identity_account:oscar
|
|
163
|
-
object: skill:secret-notes
|
|
164
|
-
assertions:
|
|
165
|
-
can_view: true
|
|
166
|
-
can_edit: true
|
|
167
|
-
- user: identity_account:oscar
|
|
168
|
-
object: workflow:secret-flow
|
|
169
|
-
assertions:
|
|
170
|
-
can_view: true
|
|
171
|
-
can_edit: true
|
|
172
|
-
# mcp_server had admin inheritance before T08 — asserted here so all
|
|
173
|
-
# four private-blueprint kinds are pinned to the same rule.
|
|
174
|
-
- user: identity_account:oscar
|
|
175
|
-
object: mcp_server:secret-tools
|
|
176
|
-
assertions:
|
|
177
|
-
can_view: true
|
|
178
|
-
can_edit: true
|
|
179
|
-
|
|
180
|
-
- name: org admin's listable agents include private ones (T08)
|
|
181
|
-
list_objects:
|
|
182
|
-
- user: identity_account:oscar
|
|
183
|
-
type: agent
|
|
184
|
-
assertions:
|
|
185
|
-
can_view:
|
|
186
|
-
- agent:secret-bot
|
|
187
|
-
- agent:team-bot
|
|
188
|
-
- agent:legacy-bot
|
|
189
|
-
- agent:shared-secret
|
|
190
|
-
|
|
191
|
-
- name: owner retains full access to private blueprints
|
|
192
|
-
check:
|
|
193
|
-
- user: identity_account:carol
|
|
194
|
-
object: agent:secret-bot
|
|
195
|
-
assertions:
|
|
196
|
-
can_view: true
|
|
197
|
-
can_execute: true
|
|
198
|
-
can_create_instance: true
|
|
199
|
-
can_edit: true
|
|
200
|
-
can_delete: true
|
|
201
|
-
- user: identity_account:carol
|
|
202
|
-
object: workflow:secret-flow
|
|
203
|
-
assertions:
|
|
204
|
-
can_view: true
|
|
205
|
-
can_execute: true
|
|
206
|
-
can_edit: true
|
|
207
|
-
|
|
208
|
-
- name: org-visible agent is viewable and runnable by org members, not outsiders
|
|
209
|
-
check:
|
|
210
|
-
- user: identity_account:dave
|
|
211
|
-
object: agent:team-bot
|
|
212
|
-
assertions:
|
|
213
|
-
can_view: true
|
|
214
|
-
can_execute: true
|
|
215
|
-
can_create_instance: true
|
|
216
|
-
can_edit: false
|
|
217
|
-
can_delete: false
|
|
218
|
-
- user: identity_account:mallory
|
|
219
|
-
object: agent:team-bot
|
|
220
|
-
assertions:
|
|
221
|
-
can_view: false
|
|
222
|
-
can_execute: false
|
|
223
|
-
|
|
224
|
-
- name: explicit individual viewer grant on a private agent conveys view and run
|
|
225
|
-
check:
|
|
226
|
-
# Run-what-you-can-read: can_execute derives from viewer, so an
|
|
227
|
-
# explicit viewer grant is enough to run (matches the execution gate,
|
|
228
|
-
# which checks can_view).
|
|
229
|
-
- user: identity_account:dave
|
|
230
|
-
object: agent:shared-secret
|
|
231
|
-
assertions:
|
|
232
|
-
can_view: true
|
|
233
|
-
can_execute: true
|
|
234
|
-
can_edit: false
|
|
235
|
-
|
|
236
|
-
- name: org member's listable agents exclude private ones
|
|
237
|
-
list_objects:
|
|
238
|
-
- user: identity_account:dave
|
|
239
|
-
type: agent
|
|
240
|
-
assertions:
|
|
241
|
-
can_view:
|
|
242
|
-
- agent:team-bot
|
|
243
|
-
- agent:legacy-bot
|
|
244
|
-
- agent:shared-secret
|
|
245
|
-
|
|
246
|
-
- name: owner's listable agents include everything they authored
|
|
247
|
-
list_objects:
|
|
248
|
-
- user: identity_account:carol
|
|
249
|
-
type: agent
|
|
250
|
-
assertions:
|
|
251
|
-
can_view:
|
|
252
|
-
- agent:secret-bot
|
|
253
|
-
- agent:team-bot
|
|
254
|
-
- agent:legacy-bot
|
|
255
|
-
- agent:shared-secret
|
|
256
|
-
|
|
257
|
-
# ── cloud#257: the viewer-role cell (previously untested) ──────────────
|
|
258
|
-
|
|
259
|
-
- name: org viewer reads org-visible blueprints — the cloud#257 contract
|
|
260
|
-
check:
|
|
261
|
-
# View, clone and (model-level) execute all derive from viewer; the
|
|
262
|
-
# spend refusal is pinned separately on the org permissions below.
|
|
263
|
-
- user: identity_account:vera
|
|
264
|
-
object: agent:team-bot
|
|
265
|
-
assertions:
|
|
266
|
-
can_view: true
|
|
267
|
-
can_clone: true
|
|
268
|
-
can_execute: true
|
|
269
|
-
can_edit: false
|
|
270
|
-
can_delete: false
|
|
271
|
-
# Private stays private — the viewer role grants nothing beyond the
|
|
272
|
-
# explicit visibility tuples.
|
|
273
|
-
- user: identity_account:vera
|
|
274
|
-
object: agent:secret-bot
|
|
275
|
-
assertions:
|
|
276
|
-
can_view: false
|
|
277
|
-
can_execute: false
|
|
278
|
-
|
|
279
|
-
- name: org viewer holds no spend authority on the org (the cost gate)
|
|
280
|
-
check:
|
|
281
|
-
# Java execution lanes (session create, agent-execution create,
|
|
282
|
-
# workflow-execution create, EC create) all check these org-level
|
|
283
|
-
# permissions — this is why widening read to viewers exposes no cost.
|
|
284
|
-
- user: identity_account:vera
|
|
285
|
-
object: organization:acme
|
|
286
|
-
assertions:
|
|
287
|
-
can_view: true
|
|
288
|
-
can_create_session: false
|
|
289
|
-
can_create_execution_in: false
|
|
290
|
-
- user: identity_account:dave
|
|
291
|
-
object: organization:acme
|
|
292
|
-
assertions:
|
|
293
|
-
can_create_session: true
|
|
294
|
-
can_create_execution_in: true
|
|
295
|
-
|
|
296
|
-
- name: legacy member-shaped tuple keeps members but still excludes viewers (until backfilled)
|
|
297
|
-
check:
|
|
298
|
-
- user: identity_account:dave
|
|
299
|
-
object: agent:legacy-bot
|
|
300
|
-
assertions:
|
|
301
|
-
can_view: true
|
|
302
|
-
can_execute: true
|
|
303
|
-
# The original cloud#257 defect, pinned on the legacy shape: the org
|
|
304
|
-
# role hierarchy flows downward, so a viewer-role user never satisfies
|
|
305
|
-
# organization#member. The boot backfill converges these tuples.
|
|
306
|
-
- user: identity_account:vera
|
|
307
|
-
object: agent:legacy-bot
|
|
308
|
-
assertions:
|
|
309
|
-
can_view: false
|
|
310
|
-
can_execute: false
|
|
311
|
-
|
|
312
|
-
- name: org viewer's listable agents are exactly the viewer-shaped org-visible ones
|
|
313
|
-
list_objects:
|
|
314
|
-
- user: identity_account:vera
|
|
315
|
-
type: agent
|
|
316
|
-
assertions:
|
|
317
|
-
can_view:
|
|
318
|
-
- agent:team-bot
|
|
@@ -1,125 +0,0 @@
|
|
|
1
|
-
# Pinned copy of stigmer-cloud backend/services/stigmer-server/fga/tests/channel-app-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
|
-
# Channel apps are owner-scoped provider credentials (T04 item 2, the
|
|
6
|
-
# oauth_app RESTRICTED posture with T08 admin inheritance): the creator
|
|
7
|
-
# owns the app; view/edit/delete require ownership or an explicit grant.
|
|
8
|
-
# Plain org members get NO implicit access — the resource carries the
|
|
9
|
-
# org's webhook signing secret and OAuth client secret.
|
|
10
|
-
#
|
|
11
|
-
# Org ADMINS inherit owner (T08): a credential holder needs an operator
|
|
12
|
-
# of last resort more than any blueprint does — an ex-employee owner must
|
|
13
|
-
# never strand secret rotation. The narrowness these tests pin: owner +
|
|
14
|
-
# admins have control, granted viewers read, plain members have nothing,
|
|
15
|
-
# and only admins can create.
|
|
16
|
-
#
|
|
17
|
-
# Run: fga model test --tests channel-app-owner.fga.yaml
|
|
18
|
-
|
|
19
|
-
name: channel-app-owner
|
|
20
|
-
model_file: ../model/fga.mod
|
|
21
|
-
|
|
22
|
-
tuples:
|
|
23
|
-
# Org membership for both accounts — proving membership grants nothing.
|
|
24
|
-
# alice created the app while she was an admin and was later demoted to
|
|
25
|
-
# member (creation is admin-gated; the owner tuple survives demotion) —
|
|
26
|
-
# this keeps the direct-owner path distinct from admin inheritance.
|
|
27
|
-
- user: identity_account:alice
|
|
28
|
-
relation: member
|
|
29
|
-
object: organization:acme
|
|
30
|
-
- user: identity_account:mallory
|
|
31
|
-
relation: member
|
|
32
|
-
object: organization:acme
|
|
33
|
-
|
|
34
|
-
# Org admin — proving T08 inheritance reaches channel apps.
|
|
35
|
-
- user: identity_account:ana
|
|
36
|
-
relation: admin
|
|
37
|
-
object: organization:acme
|
|
38
|
-
|
|
39
|
-
# The channel app, created by alice (the config-driven create tuples).
|
|
40
|
-
- user: organization:acme
|
|
41
|
-
relation: organization
|
|
42
|
-
object: channel_app:acme-support-bot
|
|
43
|
-
- user: identity_account:alice
|
|
44
|
-
relation: owner
|
|
45
|
-
object: channel_app:acme-support-bot
|
|
46
|
-
|
|
47
|
-
# An explicit viewer grant to carol (not even an org member).
|
|
48
|
-
- user: identity_account:carol
|
|
49
|
-
relation: viewer
|
|
50
|
-
object: channel_app:acme-support-bot
|
|
51
|
-
|
|
52
|
-
tests:
|
|
53
|
-
- name: owner has full control including grant management
|
|
54
|
-
check:
|
|
55
|
-
- user: identity_account:alice
|
|
56
|
-
object: channel_app:acme-support-bot
|
|
57
|
-
assertions:
|
|
58
|
-
can_view: true
|
|
59
|
-
can_edit: true
|
|
60
|
-
can_delete: true
|
|
61
|
-
can_grant_access: true
|
|
62
|
-
can_view_access: true
|
|
63
|
-
|
|
64
|
-
- name: explicitly granted viewer can read but not mutate
|
|
65
|
-
check:
|
|
66
|
-
- user: identity_account:carol
|
|
67
|
-
object: channel_app:acme-support-bot
|
|
68
|
-
assertions:
|
|
69
|
-
can_view: true
|
|
70
|
-
can_edit: false
|
|
71
|
-
can_delete: false
|
|
72
|
-
can_grant_access: false
|
|
73
|
-
can_view_access: true
|
|
74
|
-
|
|
75
|
-
- name: fellow org member has no implicit access
|
|
76
|
-
check:
|
|
77
|
-
- user: identity_account:mallory
|
|
78
|
-
object: channel_app:acme-support-bot
|
|
79
|
-
assertions:
|
|
80
|
-
can_view: false
|
|
81
|
-
can_edit: false
|
|
82
|
-
can_delete: false
|
|
83
|
-
can_grant_access: false
|
|
84
|
-
can_view_access: false
|
|
85
|
-
|
|
86
|
-
- name: org admin inherits channel app management (T08)
|
|
87
|
-
check:
|
|
88
|
-
- user: identity_account:ana
|
|
89
|
-
object: channel_app:acme-support-bot
|
|
90
|
-
assertions:
|
|
91
|
-
can_view: true
|
|
92
|
-
can_edit: true
|
|
93
|
-
can_delete: true
|
|
94
|
-
can_grant_access: true
|
|
95
|
-
|
|
96
|
-
- name: creation is admin-gated on the organization
|
|
97
|
-
check:
|
|
98
|
-
- user: identity_account:ana
|
|
99
|
-
object: organization:acme
|
|
100
|
-
assertions:
|
|
101
|
-
can_create_channel_app: true
|
|
102
|
-
- user: identity_account:mallory
|
|
103
|
-
object: organization:acme
|
|
104
|
-
assertions:
|
|
105
|
-
can_create_channel_app: false
|
|
106
|
-
|
|
107
|
-
- name: listing channel apps reflects ownership and grants, not membership
|
|
108
|
-
list_objects:
|
|
109
|
-
- user: identity_account:alice
|
|
110
|
-
type: channel_app
|
|
111
|
-
assertions:
|
|
112
|
-
can_view:
|
|
113
|
-
- channel_app:acme-support-bot
|
|
114
|
-
can_edit:
|
|
115
|
-
- channel_app:acme-support-bot
|
|
116
|
-
- user: identity_account:carol
|
|
117
|
-
type: channel_app
|
|
118
|
-
assertions:
|
|
119
|
-
can_view:
|
|
120
|
-
- channel_app:acme-support-bot
|
|
121
|
-
can_edit: []
|
|
122
|
-
- user: identity_account:mallory
|
|
123
|
-
type: channel_app
|
|
124
|
-
assertions:
|
|
125
|
-
can_view: []
|