@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,61 +1,52 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The
|
|
3
|
-
*
|
|
4
|
-
* and
|
|
2
|
+
* The evaluator's vocabulary for the authorization model: the five
|
|
3
|
+
* relation-rewrite forms OpenFGA's JSON uses in the compiled model
|
|
4
|
+
* (data/authorization-model.json, read by openfga-json.ts), and a kind's
|
|
5
|
+
* declaration as the evaluator consumes it. The model itself is the
|
|
6
|
+
* `.fga` files under fga/model; this module only names its shapes.
|
|
5
7
|
*
|
|
6
|
-
* define organization: [organization]
|
|
8
|
+
* define organization: [organization] → this, subjects [organization]
|
|
7
9
|
* define owner: [identity_account] or admin from organization
|
|
8
|
-
* → union(
|
|
9
|
-
* define viewer: [identity_account, organization#
|
|
10
|
-
*
|
|
11
|
-
* → union(direct(objectOf(...), usersetOf(...), usersetOf(...)),
|
|
12
|
-
* computed("owner"), computed("platform_viewer"))
|
|
10
|
+
* → union(this, from("admin", "organization"))
|
|
11
|
+
* define viewer: [identity_account, organization#viewer] or owner
|
|
12
|
+
* → union(this, computed("owner"))
|
|
13
13
|
* define member: [identity_account] and viewer from organization
|
|
14
|
-
* → intersection(
|
|
15
|
-
* define can_view: viewer
|
|
14
|
+
* → intersection(this, from("viewer", "organization"))
|
|
15
|
+
* define can_view: viewer → computed("viewer")
|
|
16
16
|
*
|
|
17
17
|
* `and` exists for one shape: a relation that is true only while another
|
|
18
|
-
* holds too
|
|
18
|
+
* holds too (a team's member is a person granted the role AND still one
|
|
19
19
|
* of the organization's viewers, so leaving the organization ends every
|
|
20
|
-
* team-derived grant with no cleanup.
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
* refuses
|
|
24
|
-
* a line needs it, the transcript cannot be written and the gap is a
|
|
20
|
+
* team-derived grant with no cleanup). Operators nest to any depth, as
|
|
21
|
+
* the DSL's parentheses allow; the evaluator recurses through them.
|
|
22
|
+
* `but not`, wildcards (`type:*`) and conditions have no form here: the
|
|
23
|
+
* reader refuses them by name, and the day the model needs one is a
|
|
25
24
|
* design act.
|
|
26
25
|
*
|
|
27
|
-
* A subject type is an object type or a userset; the model admits no
|
|
28
|
-
* wildcard (`type:*`) and declares no condition, so neither has a form
|
|
29
|
-
* here. The day a line needs one, the transcript cannot be written and
|
|
30
|
-
* the gap is a design act.
|
|
31
|
-
*
|
|
32
|
-
* A declaration file (model/<kind>.ts) is a TRANSCRIPT of its `.fga`
|
|
33
|
-
* file: the same relations, in the file's order, each line rewritten in
|
|
34
|
-
* these builders so a reader with the model open sees the same text, and
|
|
35
|
-
* so a structural compare against the file (the cloud's drift test at
|
|
36
|
-
* the re-pin) needs no translation table.
|
|
37
|
-
*
|
|
38
26
|
* The direct form carries its type restrictions (`[identity_account,
|
|
39
27
|
* organization#viewer]`) because the evaluator ENFORCES them: a tuple
|
|
40
28
|
* whose subject the line does not list is ignored, which is what OpenFGA
|
|
41
|
-
* does at write time. That is the fail-closed property of this design
|
|
29
|
+
* does at write time. That is the fail-closed property of this design:
|
|
42
30
|
* a derivation that drifts from the model (a userset the line dropped)
|
|
43
|
-
* makes
|
|
31
|
+
* makes the evaluator deny, never allow.
|
|
44
32
|
*
|
|
45
33
|
* `derived` names the relations `kind_meta.authorization` cannot derive
|
|
46
|
-
* from the row alone: `default_of` on an instance (the
|
|
47
|
-
*
|
|
48
|
-
*
|
|
49
|
-
* instance
|
|
50
|
-
* (
|
|
51
|
-
*
|
|
52
|
-
*
|
|
34
|
+
* from the row alone: `default_of` on an instance (the blueprint's
|
|
35
|
+
* `status.default_instance_id` must name this row; default-of.ts, shared
|
|
36
|
+
* by the two instance kinds) and `execution_viewer` on a workflow
|
|
37
|
+
* instance (`spec.execution_visibility`; execution-viewer.ts). The
|
|
38
|
+
* binding table (bindings.ts) attaches them; the tuple source dispatches
|
|
39
|
+
* to them by relation.
|
|
40
|
+
*
|
|
41
|
+
* Only types live here: the one producer of production declarations is
|
|
42
|
+
* the reader joined with the bindings (model/index.ts). Tests build
|
|
43
|
+
* throwaway models (a cycle, a chain past the depth bound) with the
|
|
44
|
+
* builders in __tests__/throwaway-model.ts.
|
|
53
45
|
*/
|
|
54
46
|
import type { DescMessage, Message } from "@bufbuild/protobuf";
|
|
55
47
|
|
|
56
48
|
import type { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
|
|
57
49
|
|
|
58
|
-
import { kindEnumName } from "../../pipeline/apiresource-meta.js";
|
|
59
50
|
import type { ObjectRef, RowLoader, Tuple } from "../tuples.js";
|
|
60
51
|
|
|
61
52
|
/** One entry of a direct line's type restriction list. */
|
|
@@ -88,38 +79,6 @@ export type Rewrite =
|
|
|
88
79
|
readonly members: ReadonlyArray<Rewrite>;
|
|
89
80
|
};
|
|
90
81
|
|
|
91
|
-
// ---------------------------------------------------------------------------
|
|
92
|
-
// Builders — named so a transcript reads like its `.fga` line.
|
|
93
|
-
// ---------------------------------------------------------------------------
|
|
94
|
-
|
|
95
|
-
export function objectOf(type: string): SubjectType {
|
|
96
|
-
return { form: "object", type };
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
export function usersetOf(type: string, relation: string): SubjectType {
|
|
100
|
-
return { form: "userset", type, relation };
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
export function direct(...subjects: ReadonlyArray<SubjectType>): Rewrite {
|
|
104
|
-
return { node: "this", subjects };
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
export function computed(relation: string): Rewrite {
|
|
108
|
-
return { node: "computed", relation };
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
export function from(relation: string, tupleset: string): Rewrite {
|
|
112
|
-
return { node: "from", relation, tupleset };
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
export function union(...members: ReadonlyArray<Rewrite>): Rewrite {
|
|
116
|
-
return { node: "union", members };
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
export function intersection(...members: ReadonlyArray<Rewrite>): Rewrite {
|
|
120
|
-
return { node: "intersection", members };
|
|
121
|
-
}
|
|
122
|
-
|
|
123
82
|
// ---------------------------------------------------------------------------
|
|
124
83
|
// A kind's declaration.
|
|
125
84
|
// ---------------------------------------------------------------------------
|
|
@@ -139,127 +98,19 @@ export type DerivedRelation = (
|
|
|
139
98
|
|
|
140
99
|
export interface KindDeclaration {
|
|
141
100
|
readonly kind: ApiResourceKind;
|
|
142
|
-
/** The FGA type name
|
|
101
|
+
/** The FGA type name: the kind's enum member name, as every edition renders objects. */
|
|
143
102
|
readonly type: string;
|
|
144
|
-
/**
|
|
145
|
-
|
|
146
|
-
|
|
103
|
+
/**
|
|
104
|
+
* The kind's message schema: what a stored row decodes with, and where
|
|
105
|
+
* its audit lives. Undefined for a ROWLESS type (bindings.ts), one with
|
|
106
|
+
* no stored resource (`platform`): it resolves over tuples alone, and
|
|
107
|
+
* no row is ever loaded or listed for it.
|
|
108
|
+
*/
|
|
109
|
+
readonly schema: DescMessage | undefined;
|
|
110
|
+
/** The `.fga` file the type is defined in, relative to the server package. */
|
|
147
111
|
readonly source: string;
|
|
148
|
-
/** Every relation the
|
|
112
|
+
/** Every relation the type defines, sorted by name. */
|
|
149
113
|
readonly relations: ReadonlyMap<string, Rewrite>;
|
|
150
114
|
/** The relations `kind_meta` cannot derive (the module header). */
|
|
151
115
|
readonly derived: ReadonlyMap<string, DerivedRelation>;
|
|
152
116
|
}
|
|
153
|
-
|
|
154
|
-
export interface KindDeclarationInput {
|
|
155
|
-
readonly kind: ApiResourceKind;
|
|
156
|
-
readonly schema: DescMessage;
|
|
157
|
-
readonly source: string;
|
|
158
|
-
readonly relations: ReadonlyArray<readonly [name: string, rewrite: Rewrite]>;
|
|
159
|
-
readonly derived?: ReadonlyArray<
|
|
160
|
-
readonly [name: string, rule: DerivedRelation]
|
|
161
|
-
>;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
/**
|
|
165
|
-
* Builds a declaration and refuses a transcript that cannot be right at
|
|
166
|
-
* module load: a relation declared twice, a `computed` naming a relation
|
|
167
|
-
* the kind does not define, a `from` whose tupleset the kind does not
|
|
168
|
-
* define (its `relation` is the PARENT's and is resolved at evaluation),
|
|
169
|
-
* a derived rule for a relation the transcript does not declare, and a
|
|
170
|
-
* line no `.fga` file could hold without parentheses (a union inside an
|
|
171
|
-
* intersection or the reverse, an operator nested in itself, an operator
|
|
172
|
-
* over fewer than two members).
|
|
173
|
-
*/
|
|
174
|
-
export function declareKind(input: KindDeclarationInput): KindDeclaration {
|
|
175
|
-
const type = kindEnumName(input.kind);
|
|
176
|
-
const relations = new Map<string, Rewrite>();
|
|
177
|
-
for (const [name, rewrite] of input.relations) {
|
|
178
|
-
if (relations.has(name)) {
|
|
179
|
-
throw new Error(`${input.source}: relation '${name}' is declared twice`);
|
|
180
|
-
}
|
|
181
|
-
const shape = unwritableShape(rewrite);
|
|
182
|
-
if (shape !== undefined) {
|
|
183
|
-
throw new Error(`${input.source}: '${name}' ${shape}`);
|
|
184
|
-
}
|
|
185
|
-
relations.set(name, rewrite);
|
|
186
|
-
}
|
|
187
|
-
for (const [name, rewrite] of relations) {
|
|
188
|
-
for (const reference of localReferences(rewrite)) {
|
|
189
|
-
if (!relations.has(reference.relation)) {
|
|
190
|
-
throw new Error(
|
|
191
|
-
`${input.source}: '${name}' names ${reference.role} '${reference.relation}', which ${type} does not declare`,
|
|
192
|
-
);
|
|
193
|
-
}
|
|
194
|
-
}
|
|
195
|
-
}
|
|
196
|
-
const derived = new Map<string, DerivedRelation>();
|
|
197
|
-
for (const [name, rule] of input.derived ?? []) {
|
|
198
|
-
if (!relations.has(name)) {
|
|
199
|
-
throw new Error(
|
|
200
|
-
`${input.source}: a derived rule for '${name}', which ${type} does not declare`,
|
|
201
|
-
);
|
|
202
|
-
}
|
|
203
|
-
derived.set(name, rule);
|
|
204
|
-
}
|
|
205
|
-
return {
|
|
206
|
-
kind: input.kind,
|
|
207
|
-
type,
|
|
208
|
-
schema: input.schema,
|
|
209
|
-
source: input.source,
|
|
210
|
-
relations,
|
|
211
|
-
derived,
|
|
212
|
-
};
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
/** The relations of the SAME kind a rewrite names: computed targets and tuplesets. */
|
|
216
|
-
function localReferences(
|
|
217
|
-
rewrite: Rewrite,
|
|
218
|
-
): ReadonlyArray<{ readonly role: string; readonly relation: string }> {
|
|
219
|
-
switch (rewrite.node) {
|
|
220
|
-
case "this":
|
|
221
|
-
return [];
|
|
222
|
-
case "computed":
|
|
223
|
-
return [{ role: "relation", relation: rewrite.relation }];
|
|
224
|
-
case "from":
|
|
225
|
-
return [{ role: "tupleset", relation: rewrite.tupleset }];
|
|
226
|
-
case "union":
|
|
227
|
-
case "intersection":
|
|
228
|
-
return rewrite.members.flatMap(localReferences);
|
|
229
|
-
default: {
|
|
230
|
-
const exhaustive: never = rewrite;
|
|
231
|
-
throw new Error(`unknown rewrite node: ${JSON.stringify(exhaustive)}`);
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
/**
|
|
237
|
-
* Why a line could not be written in a `.fga` file without parentheses,
|
|
238
|
-
* or undefined when it can: an operator's members are leaves (a direct
|
|
239
|
-
* list, a sibling relation, a tuple-to-userset), and there are at least
|
|
240
|
-
* two of them.
|
|
241
|
-
*/
|
|
242
|
-
function unwritableShape(rewrite: Rewrite): string | undefined {
|
|
243
|
-
switch (rewrite.node) {
|
|
244
|
-
case "this":
|
|
245
|
-
case "computed":
|
|
246
|
-
case "from":
|
|
247
|
-
return undefined;
|
|
248
|
-
case "union":
|
|
249
|
-
case "intersection": {
|
|
250
|
-
if (rewrite.members.length < 2) {
|
|
251
|
-
return `is ${rewrite.node === "union" ? "an or" : "an and"} over fewer than two members`;
|
|
252
|
-
}
|
|
253
|
-
const nested = rewrite.members.find(
|
|
254
|
-
(member) => member.node === "union" || member.node === "intersection",
|
|
255
|
-
);
|
|
256
|
-
return nested === undefined
|
|
257
|
-
? undefined
|
|
258
|
-
: `nests ${nested.node === "union" ? "or" : "and"} inside ${rewrite.node === "union" ? "or" : "and"}, which a .fga line cannot say without parentheses`;
|
|
259
|
-
}
|
|
260
|
-
default: {
|
|
261
|
-
const exhaustive: never = rewrite;
|
|
262
|
-
throw new Error(`unknown rewrite node: ${JSON.stringify(exhaustive)}`);
|
|
263
|
-
}
|
|
264
|
-
}
|
|
265
|
-
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Strict reads of a parsed JSON or YAML value, for the two inputs the
|
|
3
|
+
* authorization module takes as data: the compiled model
|
|
4
|
+
* (model/openfga-json.ts) and the `.fga.yaml` store tests the evaluator is
|
|
5
|
+
* proven against (__tests__/store-test-kit.ts). Both are written by a
|
|
6
|
+
* format this module does not own (OpenFGA's), so both are read as
|
|
7
|
+
* `unknown` and refused loudly on anything unexpected: a change upstream
|
|
8
|
+
* is a thrown fault naming where it failed, never a half-read input.
|
|
9
|
+
*
|
|
10
|
+
* Every function takes `where`, the path of the value in its document
|
|
11
|
+
* (`authorization-model.json: type_definitions[3].relations.viewer`), and
|
|
12
|
+
* puts it at the head of the message.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
/** A mapping, refusing any key outside `allowedKeys` when they are given. */
|
|
16
|
+
export function record(
|
|
17
|
+
value: unknown,
|
|
18
|
+
where: string,
|
|
19
|
+
allowedKeys?: ReadonlyArray<string>,
|
|
20
|
+
): Record<string, unknown> {
|
|
21
|
+
if (value === null || typeof value !== "object" || Array.isArray(value)) {
|
|
22
|
+
throw new Error(`${where}: expected a mapping`);
|
|
23
|
+
}
|
|
24
|
+
const entry = value as Record<string, unknown>;
|
|
25
|
+
if (allowedKeys !== undefined) {
|
|
26
|
+
for (const key of Object.keys(entry)) {
|
|
27
|
+
if (!allowedKeys.includes(key)) {
|
|
28
|
+
throw new Error(`${where}: unknown key '${key}'`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return entry;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
export function list(value: unknown, where: string): ReadonlyArray<unknown> {
|
|
36
|
+
if (!Array.isArray(value)) {
|
|
37
|
+
throw new Error(`${where}: expected a list`);
|
|
38
|
+
}
|
|
39
|
+
return value as ReadonlyArray<unknown>;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** A list, or the empty list when the key is absent. */
|
|
43
|
+
export function optionalList(value: unknown, where: string): ReadonlyArray<unknown> {
|
|
44
|
+
return value === undefined ? [] : list(value, where);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
export function text(value: unknown, where: string): string {
|
|
48
|
+
if (typeof value !== "string") {
|
|
49
|
+
throw new Error(`${where}: expected a string`);
|
|
50
|
+
}
|
|
51
|
+
return value;
|
|
52
|
+
}
|
package/src/boot/compose.ts
CHANGED
|
@@ -385,13 +385,15 @@ export async function composeServer(
|
|
|
385
385
|
requireAuthentication,
|
|
386
386
|
});
|
|
387
387
|
const builtInAuthorization = authorizationPosture !== "unit-authorizer";
|
|
388
|
-
// The built-in authorizer
|
|
389
|
-
//
|
|
390
|
-
//
|
|
391
|
-
//
|
|
392
|
-
//
|
|
393
|
-
//
|
|
394
|
-
//
|
|
388
|
+
// The built-in authorizer evaluates the one model every edition reads,
|
|
389
|
+
// but it derives each resource's tuples from the rows in this server's
|
|
390
|
+
// store. A wider edition's kinds are served by extensions that keep
|
|
391
|
+
// their rows in stores of their own, which the built-in tuple source
|
|
392
|
+
// cannot read, so a composition that serves a wider edition must bring
|
|
393
|
+
// its own Authorizer rather than get answers derived from rows that are
|
|
394
|
+
// not there. Refused at boot, the same class as a misconfigured
|
|
395
|
+
// registry and the verifierless posture below: caught before any side
|
|
396
|
+
// effect.
|
|
395
397
|
if (
|
|
396
398
|
authorizationPosture === "built-in" &&
|
|
397
399
|
extensions.edition !== ServerEdition.oss
|
|
@@ -764,16 +764,13 @@ describe("built-in list scope (C4: two boots, one seed — the scope is the only
|
|
|
764
764
|
let unscopedStore: Store | undefined;
|
|
765
765
|
const passThrough: ListReadScope = {
|
|
766
766
|
async authorizedResourceIds(_caller, kind) {
|
|
767
|
-
const
|
|
768
|
-
if (unscopedStore === undefined ||
|
|
767
|
+
const schema = builtInModel.byKind(kind)?.schema;
|
|
768
|
+
if (unscopedStore === undefined || schema === undefined) {
|
|
769
769
|
throw new Error("the pass-through is bound to a booted server");
|
|
770
770
|
}
|
|
771
771
|
const rows = await unscopedStore.listResources(kind);
|
|
772
772
|
return new Set(
|
|
773
|
-
rows.map(
|
|
774
|
-
(bytes) =>
|
|
775
|
-
metadataOf(fromBinary(declaration.schema, bytes))?.id ?? "",
|
|
776
|
-
),
|
|
773
|
+
rows.map((bytes) => metadataOf(fromBinary(schema, bytes))?.id ?? ""),
|
|
777
774
|
);
|
|
778
775
|
},
|
|
779
776
|
restrictListEntries: (_caller, _kind, entries) =>
|
|
@@ -99,7 +99,8 @@
|
|
|
99
99
|
* with. A driver MAY answer the parent's question in place of the
|
|
100
100
|
* child's: by the model's construction the two answers are identical
|
|
101
101
|
* (the child's `owner`, `viewer` and `can_view` are all `from` the
|
|
102
|
-
* parent
|
|
102
|
+
* parent; authorization/model/__tests__/registry.test.ts holds that
|
|
103
|
+
* for every such kind), and the parent's resolution is direct tuples where the
|
|
103
104
|
* child's walks the parent's whole set (OpenFGA's learned `weight2`
|
|
104
105
|
* strategy read the founder's 423 sessions per execution; that is what
|
|
105
106
|
* rolled back twice on 2026-09-14). A driver that ignores the field is
|
|
@@ -131,7 +132,10 @@ import type { ApiResourceAudit } from "@stigmer/protos/ai/stigmer/commons/apires
|
|
|
131
132
|
// protos and each other, so there is no cycle. Deliberate — one resolver
|
|
132
133
|
// for the tuple writer, the point-check driver and the list reader beats
|
|
133
134
|
// a copy in the seam.
|
|
134
|
-
import {
|
|
135
|
+
import {
|
|
136
|
+
inheritedAuthorizationParentOf,
|
|
137
|
+
kindEnumName,
|
|
138
|
+
} from "../pipeline/apiresource-meta.js";
|
|
135
139
|
import { rowAuthorizationFactsOf } from "../pipeline/steps/authorization-facts.js";
|
|
136
140
|
|
|
137
141
|
import type { CallerIdentity } from "./identity.js";
|
|
@@ -192,8 +196,9 @@ export interface ListReadScope {
|
|
|
192
196
|
* `caller` is never the `internal` class: `restrictListByReadScope`,
|
|
193
197
|
* the one consumption idiom, answers that class before any driver is
|
|
194
198
|
* asked (the header's contract line). A driver that is offered it has
|
|
195
|
-
* been reached around the idiom and
|
|
196
|
-
* evaluate the server as a
|
|
199
|
+
* been reached around the idiom and refuses with
|
|
200
|
+
* `InternalCallerOfferedError` rather than evaluate the server as a
|
|
201
|
+
* person.
|
|
197
202
|
*/
|
|
198
203
|
restrictListEntries(
|
|
199
204
|
caller: CallerIdentity,
|
|
@@ -202,6 +207,29 @@ export interface ListReadScope {
|
|
|
202
207
|
): Promise<ReadonlySet<string>>;
|
|
203
208
|
}
|
|
204
209
|
|
|
210
|
+
/**
|
|
211
|
+
* The restrict verb's refusal of the `internal` class (its doc above):
|
|
212
|
+
* thrown by a driver that is offered the server acting as itself, which
|
|
213
|
+
* `restrictListByReadScope` answers before any driver is asked. Being
|
|
214
|
+
* offered it means a list lane reached the driver around that idiom, and
|
|
215
|
+
* evaluating the server as a person would answer a quiet short list, the
|
|
216
|
+
* failure stigmer#1207 fixed. It is a consumer bug, never a denial (a
|
|
217
|
+
* denial is an empty set): the lane faults and the pipeline answers its
|
|
218
|
+
* sanitized INTERNAL. One type for every edition's driver, so each refuses
|
|
219
|
+
* the class the same way.
|
|
220
|
+
*/
|
|
221
|
+
export class InternalCallerOfferedError extends Error {
|
|
222
|
+
readonly kind: ApiResourceKind;
|
|
223
|
+
|
|
224
|
+
constructor(kind: ApiResourceKind) {
|
|
225
|
+
super(
|
|
226
|
+
`the internal caller class was offered to the list scope for kind '${kindEnumName(kind)}' — the shared helper answers that class before any driver; a list lane reached the driver around it`,
|
|
227
|
+
);
|
|
228
|
+
this.name = "InternalCallerOfferedError";
|
|
229
|
+
this.kind = kind;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
205
233
|
/**
|
|
206
234
|
* The shape every stored API resource message presents to the shared
|
|
207
235
|
* helper — the metadata fields the scope's candidates are built from, the
|
package/src/index.ts
CHANGED
|
@@ -10,6 +10,12 @@
|
|
|
10
10
|
* to this file are owner-visible surface changes, extended only through
|
|
11
11
|
* gates (the DD-005 review property: a surface change is a one-file diff).
|
|
12
12
|
*
|
|
13
|
+
* One data file is published beside it, through its own exports entry:
|
|
14
|
+
* `@stigmer/server/authorization-model.json`, the compiled authorization
|
|
15
|
+
* model (OpenFGA's JSON, generated from fga/model, whose README states the
|
|
16
|
+
* file's contract). Every edition reads those bytes: this server
|
|
17
|
+
* evaluates them, and an edition that runs OpenFGA applies them.
|
|
18
|
+
*
|
|
13
19
|
* The surface is exactly what the ratified architecture names (blueprint
|
|
14
20
|
* 20260826.02/03 §1) and the parameter types those entries force:
|
|
15
21
|
* - the compose entry and config loading (composeServer + its options'
|
|
@@ -224,51 +230,12 @@ export {
|
|
|
224
230
|
canSign,
|
|
225
231
|
platformTokenKeyRingFromPem,
|
|
226
232
|
} from "./platformtoken/key-ring.js";
|
|
227
|
-
// The built-in authorizer's model seams: the kind
|
|
228
|
-
// declarations (transcripts of the cloud's `.fga` files), the evaluator,
|
|
229
|
-
// and the OpenFGA store-test kit — exported so the cloud's drift test
|
|
230
|
-
// compares the live model against the transcripts and runs its live
|
|
231
|
-
// store tests through the evaluator, both from the published package.
|
|
232
|
-
// The drivers themselves are composed by the root and are not exported.
|
|
233
|
-
export type {
|
|
234
|
-
DerivedRelation,
|
|
235
|
-
KindDeclaration,
|
|
236
|
-
Rewrite,
|
|
237
|
-
SubjectType,
|
|
238
|
-
} from "./authorization/model/rewrite.js";
|
|
239
|
-
export type { Model } from "./authorization/model/index.js";
|
|
240
|
-
export {
|
|
241
|
-
builtInModel,
|
|
242
|
-
declarationFor,
|
|
243
|
-
newModel,
|
|
244
|
-
} from "./authorization/model/index.js";
|
|
245
|
-
export type {
|
|
246
|
-
ObjectRef,
|
|
247
|
-
Person,
|
|
248
|
-
Subject,
|
|
249
|
-
Tuple,
|
|
250
|
-
TupleSource,
|
|
251
|
-
} from "./authorization/tuples.js";
|
|
252
|
-
export type { EvaluationFault } from "./authorization/evaluator.js";
|
|
253
|
-
export {
|
|
254
|
-
AuthorizationEvaluationError,
|
|
255
|
-
MAX_RESOLUTION_DEPTH,
|
|
256
|
-
checkRelation,
|
|
257
|
-
} from "./authorization/evaluator.js";
|
|
258
|
-
export type {
|
|
259
|
-
StoreTestCase,
|
|
260
|
-
StoreTestDocument,
|
|
261
|
-
StoreTestKit,
|
|
262
|
-
StoreTestSkip,
|
|
263
|
-
StoreTestSkipReason,
|
|
264
|
-
} from "./authorization/store-test-kit.js";
|
|
265
|
-
export {
|
|
266
|
-
parseStoreTestDocument,
|
|
267
|
-
storeTestCases,
|
|
268
|
-
} from "./authorization/store-test-kit.js";
|
|
269
233
|
// The kinds whose missing row the built-in authorizer denies instead of
|
|
270
|
-
// answering not-found
|
|
271
|
-
//
|
|
234
|
+
// answering not-found: exported so a composition that authorizes with its
|
|
235
|
+
// own engine and probes existence itself pins its exemptions to this set.
|
|
236
|
+
// The model the authorizer evaluates is not exported as code: it is the
|
|
237
|
+
// data subpath `@stigmer/server/authorization-model.json` (this file's
|
|
238
|
+
// header).
|
|
272
239
|
export { NOT_FOUND_EXEMPT_KINDS } from "./authorization/authorizer.js";
|
|
273
240
|
export type {
|
|
274
241
|
ListReadScope,
|
|
@@ -279,6 +246,10 @@ export type {
|
|
|
279
246
|
// its rows exactly as the library's lanes do, instead of building each
|
|
280
247
|
// candidate's authorization facts by hand.
|
|
281
248
|
export { restrictListByReadScope } from "./extensions/list-read-scope.js";
|
|
249
|
+
// The seam's refusal of the `internal` caller class on the restrict verb,
|
|
250
|
+
// which that idiom answers before any driver is asked: exported so a
|
|
251
|
+
// composition's driver refuses the class exactly as the built-in one does.
|
|
252
|
+
export { InternalCallerOfferedError } from "./extensions/list-read-scope.js";
|
|
282
253
|
// The stigmer-cloud#572 seam: the identity a schedule fire acts as
|
|
283
254
|
// (drivers.scheduleFireCaller) — the composition mints it per fire; the
|
|
284
255
|
// RunStarter propagates it through the R5 in-process header. A mint that
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../../src/authorization/model/agent.ts"],"names":[],"mappings":"AAwBA,eAAO,MAAM,gBAAgB,wCAuC3B,CAAC"}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Transcript of fga/model/agentic/agent.fga — a blueprint: owned by its
|
|
3
|
-
* creator and by the organization's admins (`admin from organization`),
|
|
4
|
-
* read by whoever the visibility axis lets in. The `organization#member`
|
|
5
|
-
* and `organization#viewer` usersets on `viewer` are the org-visibility
|
|
6
|
-
* tuple's two shapes (the cloud writes `#viewer` since cloud#257; `#member`
|
|
7
|
-
* is the legacy shape it still honours), and `platform_viewer` is an
|
|
8
|
-
* identity-provider userset no open-source tuple ever names. `team#member`
|
|
9
|
-
* is the Enterprise team grant; open source serves no team, so no tuple
|
|
10
|
-
* here ever names one.
|
|
11
|
-
*/
|
|
12
|
-
import { AgentSchema } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/api_pb";
|
|
13
|
-
import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
|
|
14
|
-
import { computed, declareKind, direct, from, objectOf, union, usersetOf, } from "./rewrite.js";
|
|
15
|
-
export const agentDeclaration = declareKind({
|
|
16
|
-
kind: ApiResourceKind.agent,
|
|
17
|
-
schema: AgentSchema,
|
|
18
|
-
source: "fga/model/agentic/agent.fga",
|
|
19
|
-
relations: [
|
|
20
|
-
["organization", direct(objectOf("organization"))],
|
|
21
|
-
[
|
|
22
|
-
"owner",
|
|
23
|
-
union(direct(objectOf("identity_account")), from("admin", "organization")),
|
|
24
|
-
],
|
|
25
|
-
[
|
|
26
|
-
"platform_viewer",
|
|
27
|
-
direct(usersetOf("identity_provider", "platform_user")),
|
|
28
|
-
],
|
|
29
|
-
[
|
|
30
|
-
"viewer",
|
|
31
|
-
union(direct(objectOf("identity_account"), usersetOf("organization", "member"), usersetOf("organization", "viewer"), usersetOf("team", "member")), computed("owner"), computed("platform_viewer")),
|
|
32
|
-
],
|
|
33
|
-
["can_view", computed("viewer")],
|
|
34
|
-
["can_edit", computed("owner")],
|
|
35
|
-
["can_delete", computed("owner")],
|
|
36
|
-
["can_execute", computed("viewer")],
|
|
37
|
-
["can_create_instance", computed("can_execute")],
|
|
38
|
-
["can_clone", computed("viewer")],
|
|
39
|
-
["can_grant_access", computed("owner")],
|
|
40
|
-
["can_view_access", computed("viewer")],
|
|
41
|
-
],
|
|
42
|
-
});
|
|
43
|
-
//# sourceMappingURL=agent.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"agent.js","sourceRoot":"","sources":["../../../src/authorization/model/agent.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,WAAW,EAAE,MAAM,oDAAoD,CAAC;AACjF,OAAO,EAAE,eAAe,EAAE,MAAM,qFAAqF,CAAC;AAEtH,OAAO,EACL,QAAQ,EACR,WAAW,EACX,MAAM,EACN,IAAI,EACJ,QAAQ,EACR,KAAK,EACL,SAAS,GACV,MAAM,cAAc,CAAC;AAEtB,MAAM,CAAC,MAAM,gBAAgB,GAAG,WAAW,CAAC;IAC1C,IAAI,EAAE,eAAe,CAAC,KAAK;IAC3B,MAAM,EAAE,WAAW;IACnB,MAAM,EAAE,6BAA6B;IACrC,SAAS,EAAE;QACT,CAAC,cAAc,EAAE,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC;QAClD;YACE,OAAO;YACP,KAAK,CACH,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC,EACpC,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,CAC9B;SACF;QACD;YACE,iBAAiB;YACjB,MAAM,CAAC,SAAS,CAAC,mBAAmB,EAAE,eAAe,CAAC,CAAC;SACxD;QACD;YACE,QAAQ;YACR,KAAK,CACH,MAAM,CACJ,QAAQ,CAAC,kBAAkB,CAAC,EAC5B,SAAS,CAAC,cAAc,EAAE,QAAQ,CAAC,EACnC,SAAS,CAAC,cAAc,EAAE,QAAQ,CAAC,EACnC,SAAS,CAAC,MAAM,EAAE,QAAQ,CAAC,CAC5B,EACD,QAAQ,CAAC,OAAO,CAAC,EACjB,QAAQ,CAAC,iBAAiB,CAAC,CAC5B;SACF;QACD,CAAC,UAAU,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAChC,CAAC,UAAU,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;QAC/B,CAAC,YAAY,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;QACjC,CAAC,aAAa,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACnC,CAAC,qBAAqB,EAAE,QAAQ,CAAC,aAAa,CAAC,CAAC;QAChD,CAAC,WAAW,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACjC,CAAC,kBAAkB,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;QACvC,CAAC,iBAAiB,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;KACxC;CACF,CAAC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"agent_channel.d.ts","sourceRoot":"","sources":["../../../src/authorization/model/agent_channel.ts"],"names":[],"mappings":"AAsBA,eAAO,MAAM,uBAAuB,wCAkClC,CAAC"}
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Transcript of fga/model/agentic/agent_channel.fga — a channel binding,
|
|
3
|
-
* admin-owned like a blueprint, with `participant` as the one relation
|
|
4
|
-
* between owner and viewer: the conversation-participation role
|
|
5
|
-
* (reply and takeover without configuration authority), grantable as a
|
|
6
|
-
* role on this kind alone. Every owner participates; every participant
|
|
7
|
-
* views. Both grantable relations may name an Enterprise team
|
|
8
|
-
* (`team#member`), which no open-source tuple ever does.
|
|
9
|
-
*/
|
|
10
|
-
import { AgentChannelSchema } from "@stigmer/protos/ai/stigmer/agentic/agentchannel/v1/api_pb";
|
|
11
|
-
import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
|
|
12
|
-
import { computed, declareKind, direct, from, objectOf, union, usersetOf, } from "./rewrite.js";
|
|
13
|
-
export const agentChannelDeclaration = declareKind({
|
|
14
|
-
kind: ApiResourceKind.agent_channel,
|
|
15
|
-
schema: AgentChannelSchema,
|
|
16
|
-
source: "fga/model/agentic/agent_channel.fga",
|
|
17
|
-
relations: [
|
|
18
|
-
["organization", direct(objectOf("organization"))],
|
|
19
|
-
[
|
|
20
|
-
"owner",
|
|
21
|
-
union(direct(objectOf("identity_account")), from("admin", "organization")),
|
|
22
|
-
],
|
|
23
|
-
[
|
|
24
|
-
"participant",
|
|
25
|
-
union(direct(objectOf("identity_account"), usersetOf("team", "member")), computed("owner")),
|
|
26
|
-
],
|
|
27
|
-
[
|
|
28
|
-
"viewer",
|
|
29
|
-
union(direct(objectOf("identity_account"), usersetOf("team", "member")), computed("participant")),
|
|
30
|
-
],
|
|
31
|
-
["can_view", computed("viewer")],
|
|
32
|
-
["can_edit", computed("owner")],
|
|
33
|
-
["can_delete", computed("owner")],
|
|
34
|
-
["can_participate", computed("participant")],
|
|
35
|
-
["can_grant_access", computed("owner")],
|
|
36
|
-
["can_view_access", computed("viewer")],
|
|
37
|
-
],
|
|
38
|
-
});
|
|
39
|
-
//# sourceMappingURL=agent_channel.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"agent_channel.js","sourceRoot":"","sources":["../../../src/authorization/model/agent_channel.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,kBAAkB,EAAE,MAAM,2DAA2D,CAAC;AAC/F,OAAO,EAAE,eAAe,EAAE,MAAM,qFAAqF,CAAC;AAEtH,OAAO,EACL,QAAQ,EACR,WAAW,EACX,MAAM,EACN,IAAI,EACJ,QAAQ,EACR,KAAK,EACL,SAAS,GACV,MAAM,cAAc,CAAC;AAEtB,MAAM,CAAC,MAAM,uBAAuB,GAAG,WAAW,CAAC;IACjD,IAAI,EAAE,eAAe,CAAC,aAAa;IACnC,MAAM,EAAE,kBAAkB;IAC1B,MAAM,EAAE,qCAAqC;IAC7C,SAAS,EAAE;QACT,CAAC,cAAc,EAAE,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAC,CAAC,CAAC;QAClD;YACE,OAAO;YACP,KAAK,CACH,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAC,CAAC,EACpC,IAAI,CAAC,OAAO,EAAE,cAAc,CAAC,CAC9B;SACF;QACD;YACE,aAAa;YACb,KAAK,CACH,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,SAAS,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,EACjE,QAAQ,CAAC,OAAO,CAAC,CAClB;SACF;QACD;YACE,QAAQ;YACR,KAAK,CACH,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAC,EAAE,SAAS,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,EACjE,QAAQ,CAAC,aAAa,CAAC,CACxB;SACF;QACD,CAAC,UAAU,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAChC,CAAC,UAAU,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;QAC/B,CAAC,YAAY,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;QACjC,CAAC,iBAAiB,EAAE,QAAQ,CAAC,aAAa,CAAC,CAAC;QAC5C,CAAC,kBAAkB,EAAE,QAAQ,CAAC,OAAO,CAAC,CAAC;QACvC,CAAC,iBAAiB,EAAE,QAAQ,CAAC,QAAQ,CAAC,CAAC;KACxC;CACF,CAAC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"agent_execution.d.ts","sourceRoot":"","sources":["../../../src/authorization/model/agent_execution.ts"],"names":[],"mappings":"AAqBA,eAAO,MAAM,yBAAyB,wCAWpC,CAAC"}
|