@stigmer/server 3.21.0 → 3.22.1-dev.20260922095755
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/dist/authorization/authorizer.d.ts +4 -8
- package/dist/authorization/authorizer.d.ts.map +1 -1
- package/dist/authorization/authorizer.js +5 -9
- package/dist/authorization/authorizer.js.map +1 -1
- package/dist/authorization/derived-tuples.d.ts.map +1 -1
- package/dist/authorization/derived-tuples.js +10 -25
- package/dist/authorization/derived-tuples.js.map +1 -1
- package/dist/authorization/evaluator.d.ts +13 -8
- package/dist/authorization/evaluator.d.ts.map +1 -1
- package/dist/authorization/evaluator.js +4 -20
- 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 +24 -20
- package/dist/authorization/list-read-scope.js.map +1 -1
- package/dist/authorization/model/agent.d.ts.map +1 -1
- package/dist/authorization/model/agent.js +4 -5
- package/dist/authorization/model/agent.js.map +1 -1
- package/dist/authorization/model/agent_instance.d.ts.map +1 -1
- package/dist/authorization/model/agent_instance.js +2 -2
- package/dist/authorization/model/agent_instance.js.map +1 -1
- package/dist/authorization/model/mcp_server.d.ts.map +1 -1
- package/dist/authorization/model/mcp_server.js +2 -2
- package/dist/authorization/model/mcp_server.js.map +1 -1
- package/dist/authorization/model/organization.d.ts.map +1 -1
- package/dist/authorization/model/organization.js +2 -0
- package/dist/authorization/model/organization.js.map +1 -1
- package/dist/authorization/model/plugin.d.ts.map +1 -1
- package/dist/authorization/model/plugin.js +3 -4
- package/dist/authorization/model/plugin.js.map +1 -1
- package/dist/authorization/model/rewrite.d.ts +8 -10
- package/dist/authorization/model/rewrite.d.ts.map +1 -1
- package/dist/authorization/model/rewrite.js +0 -3
- package/dist/authorization/model/rewrite.js.map +1 -1
- package/dist/authorization/model/skill.d.ts.map +1 -1
- package/dist/authorization/model/skill.js +2 -2
- package/dist/authorization/model/skill.js.map +1 -1
- package/dist/authorization/model/workflow.d.ts.map +1 -1
- package/dist/authorization/model/workflow.js +2 -2
- package/dist/authorization/model/workflow.js.map +1 -1
- package/dist/authorization/model/workflow_instance.d.ts.map +1 -1
- package/dist/authorization/model/workflow_instance.js +2 -2
- package/dist/authorization/model/workflow_instance.js.map +1 -1
- package/dist/authorization/organization-directory.d.ts.map +1 -1
- package/dist/authorization/organization-directory.js +2 -3
- package/dist/authorization/organization-directory.js.map +1 -1
- package/dist/authorization/store-test-kit.d.ts +0 -6
- package/dist/authorization/store-test-kit.d.ts.map +1 -1
- package/dist/authorization/store-test-kit.js +16 -62
- package/dist/authorization/store-test-kit.js.map +1 -1
- package/dist/authorization/tuples.d.ts +13 -32
- package/dist/authorization/tuples.d.ts.map +1 -1
- package/dist/authorization/tuples.js +3 -11
- package/dist/authorization/tuples.js.map +1 -1
- package/dist/domain/agent/controller.d.ts.map +1 -1
- package/dist/domain/agent/controller.js +6 -4
- package/dist/domain/agent/controller.js.map +1 -1
- package/dist/domain/agentchannel/controller.d.ts.map +1 -1
- package/dist/domain/agentchannel/controller.js +9 -2
- package/dist/domain/agentchannel/controller.js.map +1 -1
- package/dist/domain/agentchannel/steps.d.ts +19 -0
- package/dist/domain/agentchannel/steps.d.ts.map +1 -1
- package/dist/domain/agentchannel/steps.js +32 -0
- package/dist/domain/agentchannel/steps.js.map +1 -1
- package/dist/domain/agentexecution/controller.d.ts.map +1 -1
- package/dist/domain/agentexecution/controller.js +3 -1
- package/dist/domain/agentexecution/controller.js.map +1 -1
- package/dist/domain/agentinstance/controller.d.ts +5 -5
- package/dist/domain/agentinstance/controller.d.ts.map +1 -1
- package/dist/domain/agentinstance/controller.js +9 -5
- package/dist/domain/agentinstance/controller.js.map +1 -1
- package/dist/domain/agentinstance/steps.d.ts +43 -8
- package/dist/domain/agentinstance/steps.d.ts.map +1 -1
- package/dist/domain/agentinstance/steps.js +71 -8
- package/dist/domain/agentinstance/steps.js.map +1 -1
- package/dist/domain/agentshare/constants.d.ts +6 -11
- package/dist/domain/agentshare/constants.d.ts.map +1 -1
- package/dist/domain/agentshare/constants.js +8 -16
- package/dist/domain/agentshare/constants.js.map +1 -1
- package/dist/domain/agentshare/controller.d.ts.map +1 -1
- package/dist/domain/agentshare/controller.js +10 -2
- package/dist/domain/agentshare/controller.js.map +1 -1
- package/dist/domain/agentshare/steps.d.ts +61 -10
- package/dist/domain/agentshare/steps.d.ts.map +1 -1
- package/dist/domain/agentshare/steps.js +121 -117
- package/dist/domain/agentshare/steps.js.map +1 -1
- package/dist/domain/artifact/controller.js +21 -25
- package/dist/domain/artifact/controller.js.map +1 -1
- package/dist/domain/channelapp/controller.d.ts.map +1 -1
- package/dist/domain/channelapp/controller.js +2 -0
- package/dist/domain/channelapp/controller.js.map +1 -1
- package/dist/domain/environment/controller.d.ts.map +1 -1
- package/dist/domain/environment/controller.js +4 -3
- package/dist/domain/environment/controller.js.map +1 -1
- package/dist/domain/executioncontext/controller.d.ts.map +1 -1
- package/dist/domain/executioncontext/controller.js +4 -1
- package/dist/domain/executioncontext/controller.js.map +1 -1
- package/dist/domain/executioncontext/steps.d.ts.map +1 -1
- package/dist/domain/executioncontext/steps.js +2 -1
- package/dist/domain/executioncontext/steps.js.map +1 -1
- package/dist/domain/mcpserver/connect.d.ts.map +1 -1
- package/dist/domain/mcpserver/connect.js +8 -7
- package/dist/domain/mcpserver/connect.js.map +1 -1
- package/dist/domain/mcpserver/controller.d.ts.map +1 -1
- package/dist/domain/mcpserver/controller.js +5 -4
- package/dist/domain/mcpserver/controller.js.map +1 -1
- package/dist/domain/mcpserver/start-connect.d.ts.map +1 -1
- package/dist/domain/mcpserver/start-connect.js +8 -7
- package/dist/domain/mcpserver/start-connect.js.map +1 -1
- package/dist/domain/memory/controller.d.ts.map +1 -1
- package/dist/domain/memory/controller.js +6 -1
- package/dist/domain/memory/controller.js.map +1 -1
- package/dist/domain/memory/steps.d.ts +23 -0
- package/dist/domain/memory/steps.d.ts.map +1 -1
- package/dist/domain/memory/steps.js +35 -0
- package/dist/domain/memory/steps.js.map +1 -1
- package/dist/domain/oauthapp/controller.d.ts.map +1 -1
- package/dist/domain/oauthapp/controller.js +2 -0
- package/dist/domain/oauthapp/controller.js.map +1 -1
- package/dist/domain/plugin/controller.d.ts.map +1 -1
- package/dist/domain/plugin/controller.js +6 -27
- package/dist/domain/plugin/controller.js.map +1 -1
- package/dist/domain/plugin/push.d.ts +7 -5
- package/dist/domain/plugin/push.d.ts.map +1 -1
- package/dist/domain/plugin/push.js +8 -14
- package/dist/domain/plugin/push.js.map +1 -1
- package/dist/domain/schedule/controller.d.ts.map +1 -1
- package/dist/domain/schedule/controller.js +10 -2
- package/dist/domain/schedule/controller.js.map +1 -1
- package/dist/domain/schedule/steps.d.ts +19 -0
- package/dist/domain/schedule/steps.d.ts.map +1 -1
- package/dist/domain/schedule/steps.js +32 -0
- package/dist/domain/schedule/steps.js.map +1 -1
- package/dist/domain/session/controller.d.ts.map +1 -1
- package/dist/domain/session/controller.js +3 -2
- package/dist/domain/session/controller.js.map +1 -1
- package/dist/domain/session/steps.d.ts +8 -9
- package/dist/domain/session/steps.d.ts.map +1 -1
- package/dist/domain/session/steps.js +17 -21
- package/dist/domain/session/steps.js.map +1 -1
- package/dist/domain/skill/controller.d.ts.map +1 -1
- package/dist/domain/skill/controller.js +8 -19
- package/dist/domain/skill/controller.js.map +1 -1
- package/dist/domain/workflow/agent-call-references.d.ts +54 -0
- package/dist/domain/workflow/agent-call-references.d.ts.map +1 -0
- package/dist/domain/workflow/agent-call-references.js +97 -0
- package/dist/domain/workflow/agent-call-references.js.map +1 -0
- package/dist/domain/workflow/controller.d.ts.map +1 -1
- package/dist/domain/workflow/controller.js +44 -113
- package/dist/domain/workflow/controller.js.map +1 -1
- package/dist/domain/workflow/registry/data/task-kind-registry.json +1 -1
- package/dist/domain/workflow/validation/task-config-constraints.d.ts +10 -1
- package/dist/domain/workflow/validation/task-config-constraints.d.ts.map +1 -1
- package/dist/domain/workflow/validation/task-config-constraints.js +3 -2
- package/dist/domain/workflow/validation/task-config-constraints.js.map +1 -1
- package/dist/domain/workflow/version-resolution.d.ts +5 -0
- package/dist/domain/workflow/version-resolution.d.ts.map +1 -0
- package/dist/domain/workflow/version-resolution.js +113 -0
- package/dist/domain/workflow/version-resolution.js.map +1 -0
- package/dist/domain/workflowexecution/controller.d.ts.map +1 -1
- package/dist/domain/workflowexecution/controller.js +4 -2
- package/dist/domain/workflowexecution/controller.js.map +1 -1
- package/dist/domain/workflowinstance/controller.d.ts.map +1 -1
- package/dist/domain/workflowinstance/controller.js +9 -5
- package/dist/domain/workflowinstance/controller.js.map +1 -1
- package/dist/domain/workflowinstance/steps.d.ts +20 -0
- package/dist/domain/workflowinstance/steps.d.ts.map +1 -1
- package/dist/domain/workflowinstance/steps.js +39 -0
- package/dist/domain/workflowinstance/steps.js.map +1 -1
- package/dist/extensions/authorization-queries.d.ts +6 -5
- package/dist/extensions/authorization-queries.d.ts.map +1 -1
- package/dist/extensions/identity.d.ts +19 -0
- package/dist/extensions/identity.d.ts.map +1 -1
- package/dist/extensions/identity.js +22 -3
- package/dist/extensions/identity.js.map +1 -1
- package/dist/extensions/list-read-scope.d.ts +42 -8
- package/dist/extensions/list-read-scope.d.ts.map +1 -1
- package/dist/extensions/list-read-scope.js +13 -2
- package/dist/extensions/list-read-scope.js.map +1 -1
- package/dist/extensions/resource-authorization.d.ts +3 -2
- package/dist/extensions/resource-authorization.d.ts.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js.map +1 -1
- package/dist/pipeline/apiresource-meta.d.ts +12 -3
- package/dist/pipeline/apiresource-meta.d.ts.map +1 -1
- package/dist/pipeline/apiresource-meta.js +21 -10
- package/dist/pipeline/apiresource-meta.js.map +1 -1
- package/dist/pipeline/steps/authorization-tuples.d.ts +9 -3
- package/dist/pipeline/steps/authorization-tuples.d.ts.map +1 -1
- package/dist/pipeline/steps/authorization-tuples.js +9 -11
- package/dist/pipeline/steps/authorization-tuples.js.map +1 -1
- package/dist/pipeline/steps/authorize-resolved-target.d.ts +88 -0
- package/dist/pipeline/steps/authorize-resolved-target.d.ts.map +1 -0
- package/dist/pipeline/steps/authorize-resolved-target.js +36 -0
- package/dist/pipeline/steps/authorize-resolved-target.js.map +1 -0
- package/dist/pipeline/steps/authorize.d.ts +27 -0
- package/dist/pipeline/steps/authorize.d.ts.map +1 -1
- package/dist/pipeline/steps/authorize.js +49 -10
- package/dist/pipeline/steps/authorize.js.map +1 -1
- package/dist/pipeline/steps/guard-memory-capture.d.ts.map +1 -1
- package/dist/pipeline/steps/guard-memory-capture.js +2 -1
- package/dist/pipeline/steps/guard-memory-capture.js.map +1 -1
- package/dist/pipeline/steps/guard-reserved-labels.d.ts.map +1 -1
- package/dist/pipeline/steps/guard-reserved-labels.js +6 -7
- package/dist/pipeline/steps/guard-reserved-labels.js.map +1 -1
- package/dist/pipeline/steps/helpers.d.ts +9 -5
- package/dist/pipeline/steps/helpers.d.ts.map +1 -1
- package/dist/pipeline/steps/helpers.js +11 -15
- package/dist/pipeline/steps/helpers.js.map +1 -1
- package/dist/pipeline/steps/references.d.ts +178 -20
- package/dist/pipeline/steps/references.d.ts.map +1 -1
- package/dist/pipeline/steps/references.js +344 -43
- package/dist/pipeline/steps/references.js.map +1 -1
- package/dist/pipeline/steps/version-history.d.ts +11 -0
- package/dist/pipeline/steps/version-history.d.ts.map +1 -1
- package/dist/pipeline/steps/version-history.js +26 -0
- package/dist/pipeline/steps/version-history.js.map +1 -1
- package/dist/query/search/controller.js +0 -1
- package/dist/query/search/controller.js.map +1 -1
- package/dist/query/search/criteria.d.ts +1 -5
- package/dist/query/search/criteria.d.ts.map +1 -1
- package/dist/query/search/criteria.js +3 -13
- package/dist/query/search/criteria.js.map +1 -1
- package/dist/query/search/handler.d.ts +5 -4
- package/dist/query/search/handler.d.ts.map +1 -1
- package/dist/query/search/handler.js +7 -6
- package/dist/query/search/handler.js.map +1 -1
- package/dist/query/search/query-store.d.ts.map +1 -1
- package/dist/query/search/query-store.js +0 -2
- package/dist/query/search/query-store.js.map +1 -1
- package/dist/store/interface.d.ts +3 -6
- package/dist/store/interface.d.ts.map +1 -1
- package/dist/store/interface.js.map +1 -1
- package/dist/store/postgres/migrations.d.ts +3 -1
- package/dist/store/postgres/migrations.d.ts.map +1 -1
- package/dist/store/postgres/migrations.js +35 -1
- package/dist/store/postgres/migrations.js.map +1 -1
- package/dist/store/postgres/store.d.ts.map +1 -1
- package/dist/store/postgres/store.js +4 -9
- package/dist/store/postgres/store.js.map +1 -1
- package/dist/store/public-visibility-retired.d.ts +67 -0
- package/dist/store/public-visibility-retired.d.ts.map +1 -0
- package/dist/store/public-visibility-retired.js +55 -0
- package/dist/store/public-visibility-retired.js.map +1 -0
- package/dist/store/sqlite/migrations.d.ts +3 -1
- package/dist/store/sqlite/migrations.d.ts.map +1 -1
- package/dist/store/sqlite/migrations.js +36 -1
- package/dist/store/sqlite/migrations.js.map +1 -1
- package/dist/store/sqlite/store.d.ts.map +1 -1
- package/dist/store/sqlite/store.js +4 -8
- package/dist/store/sqlite/store.js.map +1 -1
- package/package.json +6 -6
- package/src/authorization/README.md +24 -26
- package/src/authorization/__tests__/authorizer.test.ts +10 -9
- package/src/authorization/__tests__/derived-tuples.test.ts +4 -11
- package/src/authorization/__tests__/evaluator.test.ts +14 -73
- package/src/authorization/__tests__/facts.test.ts +2 -2
- package/src/authorization/__tests__/fixtures/fga/blueprint-private-visibility.fga.yaml +6 -98
- package/src/authorization/__tests__/fixtures/fga/default-instance-inheritance.fga.yaml +4 -61
- package/src/authorization/__tests__/fixtures/fga/org-admin-owner-inheritance.fga.yaml +1 -21
- package/src/authorization/__tests__/fixtures/fga/platform-visibility.fga.yaml +1 -25
- package/src/authorization/__tests__/fixtures/fga/workflow-execution-sharing.fga.yaml +1 -3
- package/src/authorization/__tests__/list-read-scope.test.ts +41 -29
- package/src/authorization/__tests__/skip-lane-inventory.test.ts +160 -0
- package/src/authorization/__tests__/store-tests.test.ts +1 -6
- package/src/authorization/__tests__/tuples.test.ts +12 -11
- package/src/authorization/__tests__/wire-permissions.test.ts +5 -5
- package/src/authorization/authorizer.ts +4 -9
- package/src/authorization/derived-tuples.ts +14 -31
- package/src/authorization/evaluator.ts +15 -44
- package/src/authorization/list-read-scope.ts +27 -22
- package/src/authorization/model/__tests__/registry.test.ts +2 -0
- package/src/authorization/model/agent.ts +2 -5
- package/src/authorization/model/agent_instance.ts +0 -2
- package/src/authorization/model/mcp_server.ts +0 -2
- package/src/authorization/model/organization.ts +2 -0
- package/src/authorization/model/plugin.ts +1 -4
- package/src/authorization/model/rewrite.ts +8 -13
- package/src/authorization/model/skill.ts +0 -2
- package/src/authorization/model/workflow.ts +0 -2
- package/src/authorization/model/workflow_instance.ts +0 -2
- package/src/authorization/organization-directory.ts +1 -3
- package/src/authorization/store-test-kit.ts +16 -75
- package/src/authorization/tuples.ts +16 -39
- package/src/domain/agent/__tests__/agent.test.ts +11 -4
- package/src/domain/agent/controller.ts +17 -7
- package/src/domain/agentchannel/__tests__/agentchannel.test.ts +223 -48
- package/src/domain/agentchannel/__tests__/create-authorization.test.ts +58 -0
- package/src/domain/agentchannel/controller.ts +25 -1
- package/src/domain/agentchannel/steps.ts +40 -0
- package/src/domain/agentexecution/controller.ts +6 -1
- package/src/domain/agentinstance/__tests__/create-authorization.composed.test.ts +243 -0
- package/src/domain/agentinstance/__tests__/create-authorization.test.ts +144 -0
- package/src/domain/agentinstance/controller.ts +30 -17
- package/src/domain/agentinstance/steps.ts +82 -8
- package/src/domain/agentshare/__tests__/agentshare.test.ts +196 -172
- package/src/domain/agentshare/__tests__/create-authorization.test.ts +71 -0
- package/src/domain/agentshare/__tests__/member-audience.test.ts +113 -0
- package/src/domain/agentshare/constants.ts +14 -26
- package/src/domain/agentshare/controller.ts +27 -1
- package/src/domain/agentshare/steps.ts +168 -155
- package/src/domain/artifact/controller.ts +18 -22
- package/src/domain/channelapp/controller.ts +10 -0
- package/src/domain/environment/controller.ts +15 -8
- package/src/domain/executioncontext/__tests__/executioncontext.test.ts +1 -0
- package/src/domain/executioncontext/controller.ts +15 -1
- package/src/domain/executioncontext/steps.ts +2 -1
- package/src/domain/mcpserver/__tests__/mcpserver.test.ts +115 -28
- package/src/domain/mcpserver/__tests__/oauth-handshake.test.ts +53 -18
- package/src/domain/mcpserver/connect.ts +11 -10
- package/src/domain/mcpserver/controller.ts +19 -13
- package/src/domain/mcpserver/start-connect.ts +17 -11
- package/src/domain/memory/__tests__/create-authorization.test.ts +59 -0
- package/src/domain/memory/controller.ts +11 -0
- package/src/domain/memory/steps.ts +41 -0
- package/src/domain/oauthapp/controller.ts +10 -0
- package/src/domain/plugin/controller.ts +23 -44
- package/src/domain/plugin/push.ts +8 -16
- package/src/domain/schedule/__tests__/create-authorization.test.ts +58 -0
- package/src/domain/schedule/controller.ts +26 -1
- package/src/domain/schedule/steps.ts +45 -2
- package/src/domain/session/controller.ts +12 -4
- package/src/domain/session/steps.ts +24 -32
- package/src/domain/skill/controller.ts +24 -30
- package/src/domain/workflow/__tests__/agent-call-references.test.ts +222 -0
- package/src/domain/workflow/agent-call-references.ts +157 -0
- package/src/domain/workflow/controller.ts +86 -155
- package/src/domain/workflow/registry/data/task-kind-registry.json +1 -1
- package/src/domain/workflow/validation/task-config-constraints.ts +7 -3
- package/src/domain/workflow/version-resolution.ts +166 -0
- package/src/domain/workflowexecution/controller.ts +7 -2
- package/src/domain/workflowinstance/__tests__/create-authorization.test.ts +109 -0
- package/src/domain/workflowinstance/controller.ts +25 -12
- package/src/domain/workflowinstance/steps.ts +49 -1
- package/src/extensions/__tests__/built-in-authorization-composed.test.ts +32 -19
- package/src/extensions/__tests__/composed-support.ts +38 -4
- package/src/extensions/__tests__/extension-composition.test.ts +4 -4
- package/src/extensions/__tests__/identity.test.ts +44 -1
- package/src/extensions/__tests__/list-read-scope-composed.test.ts +96 -7
- package/src/extensions/__tests__/list-read-scope.test.ts +63 -0
- package/src/extensions/authorization-queries.ts +6 -5
- package/src/extensions/identity.ts +23 -5
- package/src/extensions/list-read-scope.ts +48 -8
- package/src/extensions/resource-authorization.ts +3 -5
- package/src/index.ts +0 -1
- package/src/pipeline/__tests__/supports-visibility.test.ts +112 -0
- package/src/pipeline/apiresource-meta.ts +21 -10
- package/src/pipeline/steps/__tests__/authorization-tuples.test.ts +18 -31
- package/src/pipeline/steps/__tests__/authorize-resolved-target.test.ts +285 -0
- package/src/pipeline/steps/__tests__/references.test.ts +703 -0
- package/src/pipeline/steps/authorization-tuples.ts +9 -11
- package/src/pipeline/steps/authorize-resolved-target.ts +129 -0
- package/src/pipeline/steps/authorize.ts +70 -13
- package/src/pipeline/steps/guard-memory-capture.ts +2 -1
- package/src/pipeline/steps/guard-reserved-labels.ts +6 -9
- package/src/pipeline/steps/helpers.ts +11 -15
- package/src/pipeline/steps/references.ts +578 -70
- package/src/pipeline/steps/version-history.ts +34 -0
- package/src/query/search/__tests__/criteria.test.ts +0 -4
- package/src/query/search/__tests__/query-store.test.ts +11 -40
- package/src/query/search/controller.ts +0 -1
- package/src/query/search/criteria.ts +0 -14
- package/src/query/search/handler.ts +6 -7
- package/src/query/search/query-store.ts +0 -2
- package/src/store/__tests__/public-visibility-retired.test.ts +127 -0
- package/src/store/__tests__/store-contract.ts +6 -51
- package/src/store/interface.ts +3 -6
- package/src/store/postgres/__tests__/migrations.test.ts +187 -6
- package/src/store/postgres/__tests__/store-contract.test.ts +0 -2
- package/src/store/postgres/migrations.ts +48 -1
- package/src/store/postgres/store.ts +4 -11
- package/src/store/public-visibility-retired.ts +119 -0
- package/src/store/sqlite/__tests__/migrations.test.ts +191 -5
- package/src/store/sqlite/migrations.ts +45 -1
- package/src/store/sqlite/store.ts +4 -10
- package/dist/pipeline/steps/visibility-gates.d.ts +0 -27
- package/dist/pipeline/steps/visibility-gates.d.ts.map +0 -1
- package/dist/pipeline/steps/visibility-gates.js +0 -139
- package/dist/pipeline/steps/visibility-gates.js.map +0 -1
- package/src/authorization/__tests__/fixtures/fga/cross-org-share-creation.fga.yaml +0 -98
- package/src/authorization/__tests__/fixtures/fga/public-visibility-setter.fga.yaml +0 -52
- package/src/pipeline/steps/__tests__/visibility-gates.test.ts +0 -187
- package/src/pipeline/steps/visibility-gates.ts +0 -174
|
@@ -30,6 +30,7 @@ import { MemoryListSchema } from "@stigmer/protos/ai/stigmer/agentic/memory/v1/i
|
|
|
30
30
|
import { MemoryProvenanceSchema } from "@stigmer/protos/ai/stigmer/agentic/memory/v1/spec_pb";
|
|
31
31
|
import { MemoryStatusSchema } from "@stigmer/protos/ai/stigmer/agentic/memory/v1/status_pb";
|
|
32
32
|
import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
|
|
33
|
+
import { IamPermission } from "@stigmer/protos/ai/stigmer/iam/v1/enum_pb";
|
|
33
34
|
import { OrganizationSchema } from "@stigmer/protos/ai/stigmer/tenancy/organization/v1/api_pb";
|
|
34
35
|
|
|
35
36
|
import {
|
|
@@ -42,6 +43,8 @@ import type { PipelineStep } from "../../pipeline/pipeline.js";
|
|
|
42
43
|
import type { ListReadScope } from "../../extensions/list-read-scope.js";
|
|
43
44
|
import { restrictListByReadScope } from "../../extensions/list-read-scope.js";
|
|
44
45
|
import type { RequestContext } from "../../pipeline/request-context.js";
|
|
46
|
+
import { isServerComposedRequest } from "../../extensions/identity.js";
|
|
47
|
+
import type { AuthorizationTarget } from "../../pipeline/steps/authorize.js";
|
|
45
48
|
import {
|
|
46
49
|
generateId,
|
|
47
50
|
setAuditFieldsForUpdate,
|
|
@@ -159,6 +162,44 @@ export function newResolveMemoryDefaultsStep(): PipelineStep<
|
|
|
159
162
|
};
|
|
160
163
|
}
|
|
161
164
|
|
|
165
|
+
/** The deny copy of the create lane's organization bar. */
|
|
166
|
+
export const MEMORY_CREATE_DENIED_MESSAGE =
|
|
167
|
+
"unauthorized to capture memory in this organization";
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* The create lane's authorization question, for AuthorizeResolvedTarget
|
|
171
|
+
* after ResolveMemoryDefaults (which requires metadata.org) and BEFORE
|
|
172
|
+
* CheckMemoryEnablement, so a refused caller learns nothing about the
|
|
173
|
+
* organization's memory settings. The RPC is is_skip_authorization
|
|
174
|
+
* because the row does not exist yet and the subject IS the caller
|
|
175
|
+
* (command.proto); GuardMemoryCapture is the gate that decides WHO may
|
|
176
|
+
* capture at all, and this question is WHERE: can_create_session on
|
|
177
|
+
* metadata.org — memory is captured inside a conversation, so whoever may
|
|
178
|
+
* converse in an organization may remember there.
|
|
179
|
+
*
|
|
180
|
+
* The credentialed capture lane is already scoped to the run's
|
|
181
|
+
* organization by the credential provider (a mismatch is refused inside
|
|
182
|
+
* GuardMemoryCapture with its own copy); this question closes the plain
|
|
183
|
+
* path, a person with no run credential naming an organization they hold
|
|
184
|
+
* nothing in. A server-composed traversal asks nothing, as the gate itself
|
|
185
|
+
* says: the entry-point request already passed.
|
|
186
|
+
*/
|
|
187
|
+
export function resolveMemoryCreateTargets(
|
|
188
|
+
ctx: RequestContext<typeof MemorySchema>,
|
|
189
|
+
): ReadonlyArray<AuthorizationTarget> {
|
|
190
|
+
if (isServerComposedRequest(ctx.callerIdentity)) {
|
|
191
|
+
return [];
|
|
192
|
+
}
|
|
193
|
+
return [
|
|
194
|
+
{
|
|
195
|
+
permission: IamPermission.can_create_session,
|
|
196
|
+
resourceKind: ApiResourceKind.organization,
|
|
197
|
+
resourceId: ctx.newState.metadata?.org ?? "",
|
|
198
|
+
deniedMessage: MEMORY_CREATE_DENIED_MESSAGE,
|
|
199
|
+
},
|
|
200
|
+
];
|
|
201
|
+
}
|
|
202
|
+
|
|
162
203
|
/**
|
|
163
204
|
* CheckMemoryEnablement — Go checkMemoryEnablementStep: enforces the
|
|
164
205
|
* org's memory_enabled switch at write time, FAIL-CLOSED (DD-005 D2): a
|
|
@@ -52,6 +52,10 @@ import type { PipelineStep } from "../../pipeline/pipeline.js";
|
|
|
52
52
|
import { callerIdentityOf } from "../../pipeline/interceptors/auth.js";
|
|
53
53
|
import { RequestContext } from "../../pipeline/request-context.js";
|
|
54
54
|
import { newAuthorizeStep } from "../../pipeline/steps/authorize.js";
|
|
55
|
+
import {
|
|
56
|
+
loadedTargetAsMethod,
|
|
57
|
+
newAuthorizeResolvedTargetStep,
|
|
58
|
+
} from "../../pipeline/steps/authorize-resolved-target.js";
|
|
55
59
|
import { newGuardReservedLabelsStep } from "../../pipeline/steps/guard-reserved-labels.js";
|
|
56
60
|
import { newBuildUpdateStateStep } from "../../pipeline/steps/build-update-state.js";
|
|
57
61
|
import { newBuildNewStateStep } from "../../pipeline/steps/defaults.js";
|
|
@@ -362,6 +366,12 @@ async function getByReference(
|
|
|
362
366
|
)
|
|
363
367
|
.addStep(newValidateProtoStep())
|
|
364
368
|
.addStep(newLoadByReferenceStep(deps.store, OAuthAppSchema))
|
|
369
|
+
.addStep(
|
|
370
|
+
newAuthorizeResolvedTargetStep(
|
|
371
|
+
deps.authorizer,
|
|
372
|
+
loadedTargetAsMethod(OAuthAppQueryController.method.get),
|
|
373
|
+
),
|
|
374
|
+
)
|
|
365
375
|
.build()
|
|
366
376
|
.execute(reqCtx);
|
|
367
377
|
const app = reqCtx.get(TARGET_RESOURCE_KEY) as OAuthApp;
|
|
@@ -51,7 +51,6 @@ import type {
|
|
|
51
51
|
ApiResourceReference,
|
|
52
52
|
UpdateVisibilityInput,
|
|
53
53
|
} from "@stigmer/protos/ai/stigmer/commons/apiresource/io_pb";
|
|
54
|
-
import { IamPermission } from "@stigmer/protos/ai/stigmer/iam/v1/enum_pb";
|
|
55
54
|
|
|
56
55
|
import type { ContentAddressedArchiveStore } from "../../archive/content-store.js";
|
|
57
56
|
import { MAX_ZIP_SIZE } from "../../archive/limits.js";
|
|
@@ -74,10 +73,7 @@ import {
|
|
|
74
73
|
newRecordVisibilityBeforeUpdateStep,
|
|
75
74
|
newUpdateVisibilityTuplesStep,
|
|
76
75
|
} from "../../pipeline/steps/authorization-tuples.js";
|
|
77
|
-
import {
|
|
78
|
-
authorizeResolvedResource,
|
|
79
|
-
newAuthorizeStep,
|
|
80
|
-
} from "../../pipeline/steps/authorize.js";
|
|
76
|
+
import { newAuthorizeStep } from "../../pipeline/steps/authorize.js";
|
|
81
77
|
import { setAuditFieldsForUpdate } from "../../pipeline/steps/defaults.js";
|
|
82
78
|
import {
|
|
83
79
|
newDeleteResourceStep,
|
|
@@ -96,14 +92,17 @@ import { newValidateProtoStep } from "../../pipeline/steps/validation.js";
|
|
|
96
92
|
import { newValidateVisibilityUpdateStep } from "../../pipeline/steps/validate-visibility.js";
|
|
97
93
|
import { newDeleteVersionArchivesStep } from "../../pipeline/steps/version-archive.js";
|
|
98
94
|
import {
|
|
99
|
-
LIST_VERSIONS_RESOURCE_ID_KEY,
|
|
100
95
|
LIST_VERSIONS_RESPONSE_KEY,
|
|
101
96
|
newLoadAndMapVersionsStep,
|
|
102
97
|
newLoadByReferenceWithVersionStep,
|
|
103
98
|
newResolveBySlugForVersionsStep,
|
|
99
|
+
versionHistoryTarget,
|
|
104
100
|
} from "../../pipeline/steps/version-history.js";
|
|
101
|
+
import {
|
|
102
|
+
loadedTargetAsMethod,
|
|
103
|
+
newAuthorizeResolvedTargetStep,
|
|
104
|
+
} from "../../pipeline/steps/authorize-resolved-target.js";
|
|
105
105
|
import type { VersionHistoryBinding } from "../../pipeline/steps/version-history.js";
|
|
106
|
-
import { newAuthorizeVisibilityTransitionStep } from "../../pipeline/steps/visibility-gates.js";
|
|
107
106
|
import { metadataOf } from "../../pipeline/steps/shapes.js";
|
|
108
107
|
import type { Store } from "../../store/interface.js";
|
|
109
108
|
import { uploadUrl } from "../skill/transfer/handler.js";
|
|
@@ -226,7 +225,7 @@ async function push(
|
|
|
226
225
|
.addStep(newParseOverlayDocumentsStep())
|
|
227
226
|
.addStep(newSanitizePluginMetadataStep(deps.authorizer))
|
|
228
227
|
.addStep(newPlanMaterializationStep(deps.store, deps.authorizer))
|
|
229
|
-
.addStep(newGuardPluginVisibilityStep(
|
|
228
|
+
.addStep(newGuardPluginVisibilityStep())
|
|
230
229
|
.addStep(newResolveConvergenceStep())
|
|
231
230
|
.build()
|
|
232
231
|
.execute(reqCtx);
|
|
@@ -359,12 +358,6 @@ async function updateVisibility(
|
|
|
359
358
|
.addStep(newLoadPluginByIdStep(deps.store, UPDATE_VISIBILITY_PLUGIN_KEY))
|
|
360
359
|
.addStep(newRecordVisibilityBeforeUpdateStep(UPDATE_VISIBILITY_PLUGIN_KEY))
|
|
361
360
|
.addStep(newValidateVisibilityUpdateStep())
|
|
362
|
-
.addStep(
|
|
363
|
-
newAuthorizeVisibilityTransitionStep(
|
|
364
|
-
UPDATE_VISIBILITY_PLUGIN_KEY,
|
|
365
|
-
deps.authorizer,
|
|
366
|
-
),
|
|
367
|
-
)
|
|
368
361
|
.addStep(newSetPluginVisibilityStep())
|
|
369
362
|
.addStep(
|
|
370
363
|
newPersistPluginStep(
|
|
@@ -718,22 +711,13 @@ async function getByReference(
|
|
|
718
711
|
"LoadPluginByReference",
|
|
719
712
|
),
|
|
720
713
|
)
|
|
721
|
-
.addStep(
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
{
|
|
729
|
-
permission: IamPermission.can_view,
|
|
730
|
-
resourceKind: ApiResourceKind.plugin,
|
|
731
|
-
resourceId: resolved.metadata?.id ?? "",
|
|
732
|
-
},
|
|
733
|
-
"unauthorized to get plugin",
|
|
734
|
-
);
|
|
735
|
-
},
|
|
736
|
-
})
|
|
714
|
+
.addStep(
|
|
715
|
+
newAuthorizeResolvedTargetStep(
|
|
716
|
+
deps.authorizer,
|
|
717
|
+
loadedTargetAsMethod(PluginQueryController.method.get),
|
|
718
|
+
"AuthorizeResolvedPlugin",
|
|
719
|
+
),
|
|
720
|
+
)
|
|
737
721
|
.build()
|
|
738
722
|
.execute(reqCtx);
|
|
739
723
|
return reqCtx.get(TARGET_RESOURCE_KEY) as Plugin;
|
|
@@ -817,21 +801,16 @@ async function listVersions(
|
|
|
817
801
|
"ResolvePluginBySlug",
|
|
818
802
|
),
|
|
819
803
|
)
|
|
820
|
-
.addStep(
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
stepCtx.callerIdentity,
|
|
826
|
-
{
|
|
827
|
-
permission: IamPermission.can_view,
|
|
828
|
-
resourceKind: ApiResourceKind.plugin,
|
|
829
|
-
resourceId: stepCtx.get(LIST_VERSIONS_RESOURCE_ID_KEY) as string,
|
|
830
|
-
},
|
|
804
|
+
.addStep(
|
|
805
|
+
newAuthorizeResolvedTargetStep(
|
|
806
|
+
deps.authorizer,
|
|
807
|
+
versionHistoryTarget(
|
|
808
|
+
ApiResourceKind.plugin,
|
|
831
809
|
"unauthorized to view plugin version history",
|
|
832
|
-
)
|
|
833
|
-
|
|
834
|
-
|
|
810
|
+
),
|
|
811
|
+
"AuthorizeResolvedPlugin",
|
|
812
|
+
),
|
|
813
|
+
)
|
|
835
814
|
.addStep(
|
|
836
815
|
newLoadAndMapVersionsStep(
|
|
837
816
|
deps.store,
|
|
@@ -94,7 +94,6 @@ import { ARTIFACT_BYTES_KEY } from "../../pipeline/steps/resolve-artifact-source
|
|
|
94
94
|
import { generateSlug } from "../../pipeline/steps/slug.js";
|
|
95
95
|
import { rejectUnsupportedVisibility } from "../../pipeline/steps/validate-visibility.js";
|
|
96
96
|
import { newArchiveCurrentVersionStep } from "../../pipeline/steps/version-archive.js";
|
|
97
|
-
import { requireOperatorMaySetPublic } from "../../pipeline/steps/visibility-gates.js";
|
|
98
97
|
import { ResourceNotFoundError } from "../../store/interface.js";
|
|
99
98
|
import type { Store } from "../../store/interface.js";
|
|
100
99
|
import { openPluginArchive } from "./archive.js";
|
|
@@ -493,30 +492,23 @@ export function newPlanMaterializationStep(
|
|
|
493
492
|
|
|
494
493
|
/**
|
|
495
494
|
* GuardPluginVisibility — the requested level must be one the plugin and
|
|
496
|
-
* every planned member kind support
|
|
497
|
-
*
|
|
498
|
-
*
|
|
499
|
-
*
|
|
495
|
+
* every planned member kind support: the push chain's counterpart of the
|
|
496
|
+
* ValidateVisibility step on the resource create chains, asked here for
|
|
497
|
+
* the head and for each member kind before anything is written, so a
|
|
498
|
+
* plugin cannot be installed at a level one of its members may not hold.
|
|
499
|
+
* Each member's own chain checks again in-process; refusing here keeps the
|
|
500
|
+
* head from being written before the answer is known.
|
|
500
501
|
*/
|
|
501
|
-
export function newGuardPluginVisibilityStep(
|
|
502
|
-
authorizer: Authorizer,
|
|
503
|
-
): PipelineStep<PushDesc> {
|
|
502
|
+
export function newGuardPluginVisibilityStep(): PipelineStep<PushDesc> {
|
|
504
503
|
return {
|
|
505
504
|
name: "GuardPluginVisibility",
|
|
506
|
-
|
|
505
|
+
execute(ctx: RequestContext<PushDesc>): void {
|
|
507
506
|
const level = requestedVisibility(ctx);
|
|
508
507
|
const plan = ctx.get(PLUGIN_PLAN_KEY) as MaterializationPlan;
|
|
509
508
|
rejectUnsupportedVisibility(ctx.apiResourceKind, level);
|
|
510
509
|
for (const kind of new Set(plan.members.map((member) => member.kind))) {
|
|
511
510
|
rejectUnsupportedVisibility(kind, level);
|
|
512
511
|
}
|
|
513
|
-
if (level !== ApiResourceVisibility.visibility_public) {
|
|
514
|
-
return;
|
|
515
|
-
}
|
|
516
|
-
if (ctx.callerIdentity.callerClass === "internal") {
|
|
517
|
-
return;
|
|
518
|
-
}
|
|
519
|
-
await requireOperatorMaySetPublic(authorizer, ctx.callerIdentity);
|
|
520
512
|
},
|
|
521
513
|
};
|
|
522
514
|
}
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pins the create lane's authorization question (steps.ts,
|
|
3
|
+
* resolveScheduleCreateTargets): can_edit on the REFERENCED AGENT with the
|
|
4
|
+
* Java handler's copy, and nothing on the organization (the same-org
|
|
5
|
+
* invariant already binds the schedule to the agent's); a missing
|
|
6
|
+
* referenced agent throws.
|
|
7
|
+
*/
|
|
8
|
+
import { describe, expect, it } from "vitest";
|
|
9
|
+
import { create } from "@bufbuild/protobuf";
|
|
10
|
+
|
|
11
|
+
import { AgentSchema } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/api_pb";
|
|
12
|
+
import { ScheduleSchema } from "@stigmer/protos/ai/stigmer/agentic/schedule/v1/api_pb";
|
|
13
|
+
import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
|
|
14
|
+
import { IamPermission } from "@stigmer/protos/ai/stigmer/iam/v1/enum_pb";
|
|
15
|
+
|
|
16
|
+
import { testCallerIdentity } from "../../../pipeline/__tests__/support.js";
|
|
17
|
+
import { RequestContext } from "../../../pipeline/request-context.js";
|
|
18
|
+
import {
|
|
19
|
+
REFERENCED_AGENT_KEY,
|
|
20
|
+
SCHEDULE_CREATE_DENIED_MESSAGE,
|
|
21
|
+
resolveScheduleCreateTargets,
|
|
22
|
+
} from "../steps.js";
|
|
23
|
+
|
|
24
|
+
const agent = create(AgentSchema, {
|
|
25
|
+
metadata: { id: "agt_01target", name: "helper", org: "acme" },
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
function ctxFor(stash = true) {
|
|
29
|
+
const ctx = new RequestContext(
|
|
30
|
+
ScheduleSchema,
|
|
31
|
+
create(ScheduleSchema, { metadata: { name: "nightly", org: "acme" } }),
|
|
32
|
+
testCallerIdentity(),
|
|
33
|
+
ApiResourceKind.schedule,
|
|
34
|
+
);
|
|
35
|
+
if (stash) {
|
|
36
|
+
ctx.set(REFERENCED_AGENT_KEY, agent);
|
|
37
|
+
}
|
|
38
|
+
return ctx;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
describe("resolveScheduleCreateTargets", () => {
|
|
42
|
+
it("asks can_edit on the referenced agent and nothing else", () => {
|
|
43
|
+
expect(resolveScheduleCreateTargets(ctxFor())).toEqual([
|
|
44
|
+
{
|
|
45
|
+
permission: IamPermission.can_edit,
|
|
46
|
+
resourceKind: ApiResourceKind.agent,
|
|
47
|
+
resourceId: "agt_01target",
|
|
48
|
+
deniedMessage: SCHEDULE_CREATE_DENIED_MESSAGE,
|
|
49
|
+
},
|
|
50
|
+
]);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it("a missing referenced agent is a broken chain invariant and throws", () => {
|
|
54
|
+
expect(() => resolveScheduleCreateTargets(ctxFor(false))).toThrow(
|
|
55
|
+
"referenced agent not found in context",
|
|
56
|
+
);
|
|
57
|
+
});
|
|
58
|
+
});
|
|
@@ -62,6 +62,10 @@ import type { PipelineStep } from "../../pipeline/pipeline.js";
|
|
|
62
62
|
import { callerIdentityOf } from "../../pipeline/interceptors/auth.js";
|
|
63
63
|
import { RequestContext } from "../../pipeline/request-context.js";
|
|
64
64
|
import { newAuthorizeStep } from "../../pipeline/steps/authorize.js";
|
|
65
|
+
import {
|
|
66
|
+
loadedTargetAsMethod,
|
|
67
|
+
newAuthorizeResolvedTargetStep,
|
|
68
|
+
} from "../../pipeline/steps/authorize-resolved-target.js";
|
|
65
69
|
import { newGuardReservedLabelsStep } from "../../pipeline/steps/guard-reserved-labels.js";
|
|
66
70
|
import { newBuildNewStateStep } from "../../pipeline/steps/defaults.js";
|
|
67
71
|
import { newBuildUpdateStateStep } from "../../pipeline/steps/build-update-state.js";
|
|
@@ -93,7 +97,10 @@ import {
|
|
|
93
97
|
newCreateAuthorizationTuplesStep,
|
|
94
98
|
} from "../../pipeline/steps/authorization-tuples.js";
|
|
95
99
|
import { newPersistStep } from "../../pipeline/steps/persist.js";
|
|
96
|
-
import {
|
|
100
|
+
import {
|
|
101
|
+
newNormalizeReferencesStep,
|
|
102
|
+
newValidateReferencesStep,
|
|
103
|
+
} from "../../pipeline/steps/references.js";
|
|
97
104
|
import { newResolveSlugStep } from "../../pipeline/steps/slug.js";
|
|
98
105
|
import { newValidateProtoStep } from "../../pipeline/steps/validation.js";
|
|
99
106
|
import { newValidateVisibilityStep } from "../../pipeline/steps/validate-visibility.js";
|
|
@@ -116,6 +123,7 @@ import { newClearSchedulePauseStep } from "./resume.js";
|
|
|
116
123
|
import {
|
|
117
124
|
newResolveScheduleDefaultsStep,
|
|
118
125
|
newValidateScheduleUpdateStep,
|
|
126
|
+
resolveScheduleCreateTargets,
|
|
119
127
|
} from "./steps.js";
|
|
120
128
|
import {
|
|
121
129
|
TRIGGER_RESULT_KEY,
|
|
@@ -201,11 +209,21 @@ async function createSchedule(
|
|
|
201
209
|
.addStep(newValidateProtoStep())
|
|
202
210
|
.addStep(newValidateVisibilityStep())
|
|
203
211
|
.addStep(newResolveScheduleDefaultsStep(deps))
|
|
212
|
+
// Before the duplicate check and before ArmSchedule: a refused caller
|
|
213
|
+
// learns nothing about existing slugs and costs no Temporal schedule
|
|
214
|
+
// (steps.ts, resolveScheduleCreateTargets).
|
|
215
|
+
.addStep(
|
|
216
|
+
newAuthorizeResolvedTargetStep(
|
|
217
|
+
deps.authorizer,
|
|
218
|
+
resolveScheduleCreateTargets,
|
|
219
|
+
),
|
|
220
|
+
)
|
|
204
221
|
.addStep(newResolveSlugStep())
|
|
205
222
|
.addStep(newCheckDuplicateStep(deps.store))
|
|
206
223
|
.addStep(newBuildNewStateStep())
|
|
207
224
|
.addStep(newGuardReservedLabelsStep(deps.authorizer))
|
|
208
225
|
.addStep(newNormalizeReferencesStep())
|
|
226
|
+
.addStep(newValidateReferencesStep(deps.store))
|
|
209
227
|
.addStep(newPersistStep(deps.store))
|
|
210
228
|
.addStep(
|
|
211
229
|
newCreateAuthorizationTuplesStep(
|
|
@@ -245,6 +263,7 @@ async function update(
|
|
|
245
263
|
.addStep(newBuildUpdateStateStep())
|
|
246
264
|
.addStep(newGuardReservedLabelsStep(deps.authorizer))
|
|
247
265
|
.addStep(newNormalizeReferencesStep())
|
|
266
|
+
.addStep(newValidateReferencesStep(deps.store))
|
|
248
267
|
.addStep(newPersistScheduleUpdateStep(deps.store))
|
|
249
268
|
.addStep(newArmScheduleStep(deps.clock, deps.logger))
|
|
250
269
|
.build()
|
|
@@ -477,6 +496,12 @@ async function getByReference(
|
|
|
477
496
|
)
|
|
478
497
|
.addStep(newValidateProtoStep())
|
|
479
498
|
.addStep(newLoadByReferenceStep(deps.store, ScheduleSchema))
|
|
499
|
+
.addStep(
|
|
500
|
+
newAuthorizeResolvedTargetStep(
|
|
501
|
+
deps.authorizer,
|
|
502
|
+
loadedTargetAsMethod(ScheduleQueryController.method.get),
|
|
503
|
+
),
|
|
504
|
+
)
|
|
480
505
|
.build()
|
|
481
506
|
.execute(reqCtx);
|
|
482
507
|
return reqCtx.get(TARGET_RESOURCE_KEY) as Schedule;
|
|
@@ -8,10 +8,12 @@
|
|
|
8
8
|
* __tests__/schedule.composed.test.ts.
|
|
9
9
|
*/
|
|
10
10
|
import { AgentSchema } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/api_pb";
|
|
11
|
+
import type { Agent } from "@stigmer/protos/ai/stigmer/agentic/agent/v1/api_pb";
|
|
11
12
|
import { ScheduleSchema } from "@stigmer/protos/ai/stigmer/agentic/schedule/v1/api_pb";
|
|
12
13
|
import type { Schedule } from "@stigmer/protos/ai/stigmer/agentic/schedule/v1/api_pb";
|
|
13
14
|
import type { ScheduleSpec } from "@stigmer/protos/ai/stigmer/agentic/schedule/v1/spec_pb";
|
|
14
15
|
import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
|
|
16
|
+
import { IamPermission } from "@stigmer/protos/ai/stigmer/iam/v1/enum_pb";
|
|
15
17
|
|
|
16
18
|
import {
|
|
17
19
|
failedPreconditionError,
|
|
@@ -21,6 +23,7 @@ import {
|
|
|
21
23
|
} from "../../pipeline/errors.js";
|
|
22
24
|
import type { PipelineStep } from "../../pipeline/pipeline.js";
|
|
23
25
|
import type { RequestContext } from "../../pipeline/request-context.js";
|
|
26
|
+
import type { AuthorizationTarget } from "../../pipeline/steps/authorize.js";
|
|
24
27
|
import { findResourceBySlug } from "../../pipeline/steps/helpers.js";
|
|
25
28
|
import { EXISTING_RESOURCE_KEY } from "../../pipeline/steps/load-existing.js";
|
|
26
29
|
import type { Store } from "../../store/interface.js";
|
|
@@ -128,10 +131,47 @@ export function newResolveScheduleDefaultsStep(
|
|
|
128
131
|
if (agentRef !== undefined) {
|
|
129
132
|
agentRef.org = refOrg;
|
|
130
133
|
}
|
|
134
|
+
ctx.set(REFERENCED_AGENT_KEY, found);
|
|
131
135
|
},
|
|
132
136
|
};
|
|
133
137
|
}
|
|
134
138
|
|
|
139
|
+
/**
|
|
140
|
+
* Context key for the agent ResolveScheduleDefaults resolved from
|
|
141
|
+
* spec.agent.agent_ref, read by the create lane's authorization step.
|
|
142
|
+
*/
|
|
143
|
+
export const REFERENCED_AGENT_KEY = "scheduleReferencedAgent";
|
|
144
|
+
|
|
145
|
+
/** The deny copy of the create bar, the Java ScheduleCreateHandler's. */
|
|
146
|
+
export const SCHEDULE_CREATE_DENIED_MESSAGE =
|
|
147
|
+
"You don't have permission to schedule this agent";
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* The create lane's authorization question, for AuthorizeResolvedTarget
|
|
151
|
+
* after ResolveScheduleDefaults: can_edit on the REFERENCED AGENT. The RPC
|
|
152
|
+
* is is_skip_authorization because its target is that agent, resolved from
|
|
153
|
+
* a slug, not a request field; and there is deliberately no organization
|
|
154
|
+
* bar — a schedule is unattended spend on an agent, an editor's act, and
|
|
155
|
+
* the same-org invariant the resolve step enforces already binds the
|
|
156
|
+
* schedule's organization to the agent's (command.proto).
|
|
157
|
+
*/
|
|
158
|
+
export function resolveScheduleCreateTargets(
|
|
159
|
+
ctx: RequestContext<typeof ScheduleSchema>,
|
|
160
|
+
): ReadonlyArray<AuthorizationTarget> {
|
|
161
|
+
const agent = ctx.get(REFERENCED_AGENT_KEY) as Agent | undefined;
|
|
162
|
+
if (agent === undefined) {
|
|
163
|
+
throw new Error("referenced agent not found in context");
|
|
164
|
+
}
|
|
165
|
+
return [
|
|
166
|
+
{
|
|
167
|
+
permission: IamPermission.can_edit,
|
|
168
|
+
resourceKind: ApiResourceKind.agent,
|
|
169
|
+
resourceId: agent.metadata?.id ?? "",
|
|
170
|
+
deniedMessage: SCHEDULE_CREATE_DENIED_MESSAGE,
|
|
171
|
+
},
|
|
172
|
+
];
|
|
173
|
+
}
|
|
174
|
+
|
|
135
175
|
/**
|
|
136
176
|
* Enforces the schedule-specific workspace constraint on the shared
|
|
137
177
|
* AgentInvocation (DD-018 D-3): every workspace entry must be a git_repo
|
|
@@ -140,7 +180,9 @@ export function newResolveScheduleDefaultsStep(
|
|
|
140
180
|
* deterministic provisioning failure at 3 AM. Copy is cross-edition
|
|
141
181
|
* contract (Go validateScheduleWorkspace).
|
|
142
182
|
*/
|
|
143
|
-
export function validateScheduleWorkspace(
|
|
183
|
+
export function validateScheduleWorkspace(
|
|
184
|
+
spec: ScheduleSpec | undefined,
|
|
185
|
+
): void {
|
|
144
186
|
const entries =
|
|
145
187
|
spec?.target.case === "agent" ? spec.target.value.workspaceEntries : [];
|
|
146
188
|
for (const [i, entry] of entries.entries()) {
|
|
@@ -174,7 +216,8 @@ export function validateScheduleModelPinning(
|
|
|
174
216
|
if (presence !== "") {
|
|
175
217
|
throw invalidArgumentError(presence);
|
|
176
218
|
}
|
|
177
|
-
const invocation =
|
|
219
|
+
const invocation =
|
|
220
|
+
spec?.target.case === "agent" ? spec.target.value : undefined;
|
|
178
221
|
const existence = unknownModelPinRefusal(
|
|
179
222
|
modelRegistry,
|
|
180
223
|
"spec.agent.run_config.model_name",
|
|
@@ -85,7 +85,10 @@ import {
|
|
|
85
85
|
TARGET_RESOURCE_KEY,
|
|
86
86
|
newLoadTargetStep,
|
|
87
87
|
} from "../../pipeline/steps/load-target.js";
|
|
88
|
-
import {
|
|
88
|
+
import {
|
|
89
|
+
newNormalizeReferencesStep,
|
|
90
|
+
newValidateReferencesStep,
|
|
91
|
+
} from "../../pipeline/steps/references.js";
|
|
89
92
|
import {
|
|
90
93
|
newCleanupIamPoliciesStep,
|
|
91
94
|
newCreateAuthorizationTuplesStep,
|
|
@@ -208,7 +211,8 @@ async function createSession(
|
|
|
208
211
|
.addStep(newCheckDuplicateStep(deps.store))
|
|
209
212
|
.addStep(newBuildNewStateStep())
|
|
210
213
|
.addStep(newGuardReservedLabelsStep(deps.authorizer))
|
|
211
|
-
.addStep(newNormalizeReferencesStep())
|
|
214
|
+
.addStep(newNormalizeReferencesStep())
|
|
215
|
+
.addStep(newValidateReferencesStep(deps.store));
|
|
212
216
|
// The ratified pre-side-effect gate slot (blueprint 03 §3a; O4; Q2
|
|
213
217
|
// ruling — see the create doc comment). Empty in OSS.
|
|
214
218
|
for (const step of stepsForSlot<typeof SessionSchema>(
|
|
@@ -499,7 +503,9 @@ async function list(
|
|
|
499
503
|
newAuthorizeStep(SessionQueryController.method.list, deps.authorizer),
|
|
500
504
|
)
|
|
501
505
|
.addStep(newValidateProtoStep())
|
|
502
|
-
.addStep(
|
|
506
|
+
.addStep(
|
|
507
|
+
newListAllSessionsStep(deps.store, deps.logger, deps.listReadScope),
|
|
508
|
+
)
|
|
503
509
|
.build()
|
|
504
510
|
.execute(reqCtx);
|
|
505
511
|
return requireListResult(reqCtx.get(LIST_RESULT_KEY));
|
|
@@ -559,7 +565,9 @@ async function listByChannel(
|
|
|
559
565
|
)
|
|
560
566
|
.addStep(newValidateProtoStep())
|
|
561
567
|
.addStep(newAuthorizeChannelAccessStep(deps.authorizer))
|
|
562
|
-
.addStep(
|
|
568
|
+
.addStep(
|
|
569
|
+
newFilterByChannelStep(deps.store, deps.logger, deps.listReadScope),
|
|
570
|
+
)
|
|
563
571
|
.build()
|
|
564
572
|
.execute(reqCtx);
|
|
565
573
|
return requireListResult(reqCtx.get(LIST_RESULT_KEY));
|
|
@@ -44,7 +44,7 @@ import type { PipelineStep } from "../../pipeline/pipeline.js";
|
|
|
44
44
|
import type { Authorizer } from "../../extensions/authorizer.js";
|
|
45
45
|
import type { ListReadScope } from "../../extensions/list-read-scope.js";
|
|
46
46
|
import { restrictListByReadScope } from "../../extensions/list-read-scope.js";
|
|
47
|
-
import {
|
|
47
|
+
import { newAuthorizeResolvedTargetStep } from "../../pipeline/steps/authorize-resolved-target.js";
|
|
48
48
|
import type { RequestContext } from "../../pipeline/request-context.js";
|
|
49
49
|
import { RESOURCE_ID_KEY } from "../../pipeline/steps/delete.js";
|
|
50
50
|
import { compareCreatedAtDesc } from "../../pipeline/steps/helpers.js";
|
|
@@ -533,41 +533,33 @@ export function newFilterByAgentInstanceStep(
|
|
|
533
533
|
|
|
534
534
|
/**
|
|
535
535
|
* AuthorizeChannelAccess — the Java SessionListByChannelHandler's
|
|
536
|
-
* two-stage authorization, stage one
|
|
537
|
-
*
|
|
538
|
-
*
|
|
539
|
-
*
|
|
540
|
-
*
|
|
541
|
-
*
|
|
542
|
-
*
|
|
543
|
-
*
|
|
544
|
-
* checks only a named channel.
|
|
536
|
+
* two-stage authorization, stage one: an explicit can_view check on the
|
|
537
|
+
* TARGET agent_channel before any session work, so a caller without
|
|
538
|
+
* channel access learns nothing about the channel's sessions. The
|
|
539
|
+
* mid-chain resolved-target evaluation (the is_skip_authorization
|
|
540
|
+
* annotation makes the position-1 step a no-op on this lane); deny copy is
|
|
541
|
+
* the Java handler's byte-pinned "unauthorized to list channel
|
|
542
|
+
* conversations". The blank-id refusal stays FilterByChannel's (the step
|
|
543
|
+
* behind this gate) — the gate asks nothing when no channel is named.
|
|
545
544
|
*/
|
|
546
545
|
export function newAuthorizeChannelAccessStep(
|
|
547
546
|
authorizer: Authorizer,
|
|
548
547
|
): PipelineStep<typeof SessionQueryController.method.listByChannel.input> {
|
|
549
|
-
return
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
resourceKind: ApiResourceKind.agent_channel,
|
|
565
|
-
resourceId: ctx.input.channelId,
|
|
566
|
-
},
|
|
567
|
-
"unauthorized to list channel conversations",
|
|
568
|
-
);
|
|
569
|
-
},
|
|
570
|
-
};
|
|
548
|
+
return newAuthorizeResolvedTargetStep(
|
|
549
|
+
authorizer,
|
|
550
|
+
({ input }) =>
|
|
551
|
+
input.channelId === ""
|
|
552
|
+
? []
|
|
553
|
+
: [
|
|
554
|
+
{
|
|
555
|
+
permission: IamPermission.can_view,
|
|
556
|
+
resourceKind: ApiResourceKind.agent_channel,
|
|
557
|
+
resourceId: input.channelId,
|
|
558
|
+
deniedMessage: "unauthorized to list channel conversations",
|
|
559
|
+
},
|
|
560
|
+
],
|
|
561
|
+
"AuthorizeChannelAccess",
|
|
562
|
+
);
|
|
571
563
|
}
|
|
572
564
|
|
|
573
565
|
/**
|