@stigmer/server 3.40.1 → 3.41.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/dist/authorization/authorizer.d.ts +16 -10
- package/dist/authorization/authorizer.d.ts.map +1 -1
- package/dist/authorization/authorizer.js +17 -9
- package/dist/authorization/authorizer.js.map +1 -1
- package/dist/authorization/derived-tuples.d.ts +7 -3
- package/dist/authorization/derived-tuples.d.ts.map +1 -1
- package/dist/authorization/derived-tuples.js +62 -6
- package/dist/authorization/derived-tuples.js.map +1 -1
- package/dist/authorization/evaluator.d.ts +11 -7
- package/dist/authorization/evaluator.d.ts.map +1 -1
- package/dist/authorization/evaluator.js +16 -10
- package/dist/authorization/evaluator.js.map +1 -1
- package/dist/authorization/list-read-scope.d.ts +4 -0
- package/dist/authorization/list-read-scope.d.ts.map +1 -1
- package/dist/authorization/list-read-scope.js +1 -0
- package/dist/authorization/list-read-scope.js.map +1 -1
- package/dist/authorization/model/data/authorization-model.json +830 -67
- package/dist/authorization/model/execution-viewer.d.ts.map +1 -1
- package/dist/authorization/model/execution-viewer.js +26 -24
- package/dist/authorization/model/execution-viewer.js.map +1 -1
- package/dist/authorization/model/index.d.ts +4 -1
- package/dist/authorization/model/index.d.ts.map +1 -1
- package/dist/authorization/model/index.js +4 -1
- package/dist/authorization/model/index.js.map +1 -1
- package/dist/authorization/model/rewrite.d.ts +5 -3
- package/dist/authorization/model/rewrite.d.ts.map +1 -1
- package/dist/authorization/organization-directory.d.ts +44 -0
- package/dist/authorization/organization-directory.d.ts.map +1 -1
- package/dist/authorization/organization-directory.js +1 -0
- package/dist/authorization/organization-directory.js.map +1 -1
- package/dist/authorization/person.d.ts +14 -1
- package/dist/authorization/person.d.ts.map +1 -1
- package/dist/authorization/person.js +16 -0
- package/dist/authorization/person.js.map +1 -1
- package/dist/authorization/policy-check.d.ts +52 -0
- package/dist/authorization/policy-check.d.ts.map +1 -0
- package/dist/authorization/policy-check.js +35 -0
- package/dist/authorization/policy-check.js.map +1 -0
- package/dist/authorization/posture.d.ts +30 -4
- package/dist/authorization/posture.d.ts.map +1 -1
- package/dist/authorization/posture.js +58 -0
- package/dist/authorization/posture.js.map +1 -1
- package/dist/authorization/resource-creators.d.ts +4 -0
- package/dist/authorization/resource-creators.d.ts.map +1 -0
- package/dist/authorization/resource-creators.js +44 -0
- package/dist/authorization/resource-creators.js.map +1 -0
- package/dist/authorization/trusted-local-authorizer.d.ts +9 -0
- package/dist/authorization/trusted-local-authorizer.d.ts.map +1 -0
- package/dist/authorization/trusted-local-authorizer.js +70 -0
- package/dist/authorization/trusted-local-authorizer.js.map +1 -0
- package/dist/authorization/tuples.d.ts +12 -0
- package/dist/authorization/tuples.d.ts.map +1 -1
- package/dist/authorization/tuples.js +3 -0
- package/dist/authorization/tuples.js.map +1 -1
- package/dist/boot/compose.d.ts.map +1 -1
- package/dist/boot/compose.js +132 -43
- package/dist/boot/compose.js.map +1 -1
- package/dist/boot/config.d.ts +22 -7
- package/dist/boot/config.d.ts.map +1 -1
- package/dist/boot/config.js +2 -1
- package/dist/boot/config.js.map +1 -1
- package/dist/boot/inprocess.d.ts.map +1 -1
- package/dist/boot/inprocess.js +10 -4
- package/dist/boot/inprocess.js.map +1 -1
- package/dist/boot/list-indexes.d.ts.map +1 -1
- package/dist/boot/list-indexes.js +6 -1
- package/dist/boot/list-indexes.js.map +1 -1
- package/dist/boot/logger.d.ts +3 -1
- package/dist/boot/logger.d.ts.map +1 -1
- package/dist/boot/logger.js +3 -1
- package/dist/boot/logger.js.map +1 -1
- package/dist/boot/oauth-redirect-uri.d.ts +33 -12
- package/dist/boot/oauth-redirect-uri.d.ts.map +1 -1
- package/dist/boot/oauth-redirect-uri.js +43 -14
- package/dist/boot/oauth-redirect-uri.js.map +1 -1
- package/dist/boot/skill-transfer-origin.d.ts +46 -14
- package/dist/boot/skill-transfer-origin.d.ts.map +1 -1
- package/dist/boot/skill-transfer-origin.js +53 -13
- package/dist/boot/skill-transfer-origin.js.map +1 -1
- package/dist/domain/agentchannel/steps.d.ts +8 -6
- package/dist/domain/agentchannel/steps.d.ts.map +1 -1
- package/dist/domain/agentchannel/steps.js +9 -7
- package/dist/domain/agentchannel/steps.js.map +1 -1
- package/dist/domain/agentexecution/controller.d.ts +7 -0
- package/dist/domain/agentexecution/controller.d.ts.map +1 -1
- package/dist/domain/agentexecution/controller.js +1 -1
- package/dist/domain/agentexecution/controller.js.map +1 -1
- package/dist/domain/agentexecution/create-steps.d.ts +26 -12
- package/dist/domain/agentexecution/create-steps.d.ts.map +1 -1
- package/dist/domain/agentexecution/create-steps.js +61 -43
- package/dist/domain/agentexecution/create-steps.js.map +1 -1
- package/dist/domain/agentexecution/submit-approval.d.ts.map +1 -1
- package/dist/domain/agentexecution/submit-approval.js +9 -6
- package/dist/domain/agentexecution/submit-approval.js.map +1 -1
- package/dist/domain/agentexecution/submit-file-decision.d.ts.map +1 -1
- package/dist/domain/agentexecution/submit-file-decision.js +5 -4
- package/dist/domain/agentexecution/submit-file-decision.js.map +1 -1
- package/dist/domain/agentshare/steps.d.ts +5 -3
- package/dist/domain/agentshare/steps.d.ts.map +1 -1
- package/dist/domain/agentshare/steps.js +6 -4
- package/dist/domain/agentshare/steps.js.map +1 -1
- package/dist/domain/apikey/verifier.d.ts +7 -0
- package/dist/domain/apikey/verifier.d.ts.map +1 -1
- package/dist/domain/apikey/verifier.js +34 -1
- package/dist/domain/apikey/verifier.js.map +1 -1
- package/dist/domain/channelapp/controller.d.ts +4 -3
- package/dist/domain/channelapp/controller.d.ts.map +1 -1
- package/dist/domain/channelapp/controller.js.map +1 -1
- package/dist/domain/executioncontext/steps.d.ts +2 -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/iampolicy/access-lists.d.ts.map +1 -1
- package/dist/domain/iampolicy/access-lists.js +57 -2
- package/dist/domain/iampolicy/access-lists.js.map +1 -1
- package/dist/domain/iampolicy/change.d.ts +53 -0
- package/dist/domain/iampolicy/change.d.ts.map +1 -0
- package/dist/domain/iampolicy/change.js +44 -0
- package/dist/domain/iampolicy/change.js.map +1 -0
- package/dist/domain/iampolicy/constants.d.ts +6 -0
- package/dist/domain/iampolicy/constants.d.ts.map +1 -1
- package/dist/domain/iampolicy/constants.js +6 -0
- package/dist/domain/iampolicy/constants.js.map +1 -1
- package/dist/domain/iampolicy/controller.d.ts.map +1 -1
- package/dist/domain/iampolicy/controller.js +9 -5
- package/dist/domain/iampolicy/controller.js.map +1 -1
- package/dist/domain/iampolicy/grant-path.d.ts +31 -13
- package/dist/domain/iampolicy/grant-path.d.ts.map +1 -1
- package/dist/domain/iampolicy/grant-path.js +216 -19
- package/dist/domain/iampolicy/grant-path.js.map +1 -1
- package/dist/domain/iampolicy/membership.d.ts +11 -3
- package/dist/domain/iampolicy/membership.d.ts.map +1 -1
- package/dist/domain/iampolicy/membership.js +18 -13
- package/dist/domain/iampolicy/membership.js.map +1 -1
- package/dist/domain/iampolicy/resource-store.d.ts.map +1 -1
- package/dist/domain/iampolicy/resource-store.js +4 -0
- package/dist/domain/iampolicy/resource-store.js.map +1 -1
- package/dist/domain/iampolicy/role-lifecycle.d.ts.map +1 -1
- package/dist/domain/iampolicy/role-lifecycle.js +2 -2
- package/dist/domain/iampolicy/role-lifecycle.js.map +1 -1
- package/dist/domain/iampolicy/roles.d.ts.map +1 -1
- package/dist/domain/iampolicy/roles.js +7 -0
- package/dist/domain/iampolicy/roles.js.map +1 -1
- package/dist/domain/iampolicy/steps.d.ts +4 -3
- package/dist/domain/iampolicy/steps.d.ts.map +1 -1
- package/dist/domain/iampolicy/steps.js +7 -7
- package/dist/domain/iampolicy/steps.js.map +1 -1
- package/dist/domain/iampolicy/store-contract.d.ts.map +1 -1
- package/dist/domain/iampolicy/store-contract.js +22 -1
- package/dist/domain/iampolicy/store-contract.js.map +1 -1
- package/dist/domain/iampolicy/store.d.ts +18 -5
- package/dist/domain/iampolicy/store.d.ts.map +1 -1
- package/dist/domain/iampolicy/store.js.map +1 -1
- package/dist/domain/identityaccount/constants.d.ts +15 -0
- package/dist/domain/identityaccount/constants.d.ts.map +1 -1
- package/dist/domain/identityaccount/constants.js +17 -0
- package/dist/domain/identityaccount/constants.js.map +1 -1
- package/dist/domain/identityaccount/controller.d.ts.map +1 -1
- package/dist/domain/identityaccount/controller.js +17 -6
- package/dist/domain/identityaccount/controller.js.map +1 -1
- package/dist/domain/identityaccount/resolve.d.ts +47 -0
- package/dist/domain/identityaccount/resolve.d.ts.map +1 -1
- package/dist/domain/identityaccount/resolve.js +38 -1
- package/dist/domain/identityaccount/resolve.js.map +1 -1
- package/dist/domain/identityaccount/resource-store.d.ts.map +1 -1
- package/dist/domain/identityaccount/resource-store.js +11 -1
- package/dist/domain/identityaccount/resource-store.js.map +1 -1
- package/dist/domain/identityaccount/steps.d.ts +2 -1
- package/dist/domain/identityaccount/steps.d.ts.map +1 -1
- package/dist/domain/identityaccount/steps.js +4 -3
- package/dist/domain/identityaccount/steps.js.map +1 -1
- package/dist/domain/identityaccount/store-contract.js +2 -2
- package/dist/domain/identityaccount/store-contract.js.map +1 -1
- package/dist/domain/identityaccount/store.d.ts +6 -1
- package/dist/domain/identityaccount/store.d.ts.map +1 -1
- package/dist/domain/mcpserver/connect-sandbox.d.ts +67 -0
- package/dist/domain/mcpserver/connect-sandbox.d.ts.map +1 -0
- package/dist/domain/mcpserver/connect-sandbox.js +64 -0
- package/dist/domain/mcpserver/connect-sandbox.js.map +1 -0
- package/dist/domain/mcpserver/connect.d.ts +42 -10
- package/dist/domain/mcpserver/connect.d.ts.map +1 -1
- package/dist/domain/mcpserver/connect.js +147 -40
- package/dist/domain/mcpserver/connect.js.map +1 -1
- package/dist/domain/mcpserver/controller.js +4 -2
- package/dist/domain/mcpserver/controller.js.map +1 -1
- package/dist/domain/mcpserver/engine.d.ts +26 -7
- package/dist/domain/mcpserver/engine.d.ts.map +1 -1
- package/dist/domain/mcpserver/engine.js.map +1 -1
- package/dist/domain/mcpserver/start-connect.d.ts +5 -0
- package/dist/domain/mcpserver/start-connect.d.ts.map +1 -1
- package/dist/domain/mcpserver/start-connect.js +38 -15
- package/dist/domain/mcpserver/start-connect.js.map +1 -1
- package/dist/domain/memory/controller.js +2 -1
- package/dist/domain/memory/controller.js.map +1 -1
- package/dist/domain/memory/list-index.d.ts +2 -0
- package/dist/domain/memory/list-index.d.ts.map +1 -0
- package/dist/domain/memory/list-index.js +31 -0
- package/dist/domain/memory/list-index.js.map +1 -0
- package/dist/domain/memory/queries.d.ts +10 -0
- package/dist/domain/memory/queries.d.ts.map +1 -0
- package/dist/domain/memory/queries.js +54 -0
- package/dist/domain/memory/queries.js.map +1 -0
- package/dist/domain/memory/steps.d.ts +13 -11
- package/dist/domain/memory/steps.d.ts.map +1 -1
- package/dist/domain/memory/steps.js +26 -57
- package/dist/domain/memory/steps.js.map +1 -1
- package/dist/domain/organization/steps.d.ts.map +1 -1
- package/dist/domain/organization/steps.js +1 -1
- package/dist/domain/organization/steps.js.map +1 -1
- package/dist/domain/platformclient/mint.d.ts.map +1 -1
- package/dist/domain/platformclient/mint.js +2 -2
- package/dist/domain/platformclient/mint.js.map +1 -1
- package/dist/domain/platformclient/verifier.d.ts.map +1 -1
- package/dist/domain/platformclient/verifier.js +6 -3
- package/dist/domain/platformclient/verifier.js.map +1 -1
- package/dist/domain/plugin/push.d.ts.map +1 -1
- package/dist/domain/plugin/push.js +1 -0
- package/dist/domain/plugin/push.js.map +1 -1
- package/dist/domain/schedule/steps.d.ts +3 -1
- package/dist/domain/schedule/steps.d.ts.map +1 -1
- package/dist/domain/schedule/steps.js +3 -1
- package/dist/domain/schedule/steps.js.map +1 -1
- package/dist/domain/skill/push.d.ts.map +1 -1
- package/dist/domain/skill/push.js +1 -0
- package/dist/domain/skill/push.js.map +1 -1
- package/dist/domain/workflow/registry/data/task-kind-registry.json +27 -1
- package/dist/domain/workflowexecution/submit-approval.d.ts +5 -2
- package/dist/domain/workflowexecution/submit-approval.d.ts.map +1 -1
- package/dist/domain/workflowexecution/submit-approval.js +1 -1
- package/dist/domain/workflowexecution/submit-approval.js.map +1 -1
- package/dist/domain/workflowexecution/submit-file-decision.d.ts +5 -2
- package/dist/domain/workflowexecution/submit-file-decision.d.ts.map +1 -1
- package/dist/domain/workflowexecution/submit-file-decision.js +1 -1
- package/dist/domain/workflowexecution/submit-file-decision.js.map +1 -1
- package/dist/domain/workflowexecution/submit-workflow-task-approval.d.ts.map +1 -1
- package/dist/domain/workflowexecution/submit-workflow-task-approval.js +12 -1
- package/dist/domain/workflowexecution/submit-workflow-task-approval.js.map +1 -1
- package/dist/domain/workflowinstance/controller.d.ts +6 -3
- package/dist/domain/workflowinstance/controller.d.ts.map +1 -1
- package/dist/domain/workflowinstance/controller.js +12 -7
- package/dist/domain/workflowinstance/controller.js.map +1 -1
- package/dist/domain/workflowinstance/steps.d.ts +31 -0
- package/dist/domain/workflowinstance/steps.d.ts.map +1 -1
- package/dist/domain/workflowinstance/steps.js +88 -1
- package/dist/domain/workflowinstance/steps.js.map +1 -1
- package/dist/extensions/composed-services.d.ts +56 -0
- package/dist/extensions/composed-services.d.ts.map +1 -0
- package/dist/extensions/composed-services.js +2 -0
- package/dist/extensions/composed-services.js.map +1 -0
- package/dist/extensions/drivers.d.ts +32 -1
- package/dist/extensions/drivers.d.ts.map +1 -1
- package/dist/extensions/identity.d.ts +4 -1
- package/dist/extensions/identity.d.ts.map +1 -1
- package/dist/extensions/identity.js +4 -1
- package/dist/extensions/identity.js.map +1 -1
- package/dist/extensions/registry.d.ts +37 -0
- package/dist/extensions/registry.d.ts.map +1 -1
- package/dist/extensions/registry.js +50 -0
- package/dist/extensions/registry.js.map +1 -1
- package/dist/extensions/resource-authorization.d.ts +78 -0
- package/dist/extensions/resource-authorization.d.ts.map +1 -1
- package/dist/extensions/resource-row-reader.d.ts +43 -0
- package/dist/extensions/resource-row-reader.d.ts.map +1 -0
- package/dist/extensions/resource-row-reader.js +2 -0
- package/dist/extensions/resource-row-reader.js.map +1 -0
- package/dist/extensions/visitor-classifier.d.ts +41 -0
- package/dist/extensions/visitor-classifier.d.ts.map +1 -0
- package/dist/extensions/visitor-classifier.js +2 -0
- package/dist/extensions/visitor-classifier.js.map +1 -0
- package/dist/identity/oidc-userinfo.d.ts +6 -1
- package/dist/identity/oidc-userinfo.d.ts.map +1 -1
- package/dist/identity/oidc-userinfo.js.map +1 -1
- package/dist/identity/oidc-verifier.d.ts.map +1 -1
- package/dist/identity/oidc-verifier.js +37 -8
- package/dist/identity/oidc-verifier.js.map +1 -1
- package/dist/index.d.ts +14 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +25 -9
- package/dist/index.js.map +1 -1
- package/dist/pipeline/errors.d.ts +8 -0
- package/dist/pipeline/errors.d.ts.map +1 -1
- package/dist/pipeline/errors.js +25 -16
- package/dist/pipeline/errors.js.map +1 -1
- package/dist/pipeline/interceptors/auth.d.ts +17 -9
- package/dist/pipeline/interceptors/auth.d.ts.map +1 -1
- package/dist/pipeline/interceptors/auth.js +17 -9
- package/dist/pipeline/interceptors/auth.js.map +1 -1
- package/dist/pipeline/steps/authorization-tuples.d.ts +23 -1
- package/dist/pipeline/steps/authorization-tuples.d.ts.map +1 -1
- package/dist/pipeline/steps/authorization-tuples.js +42 -0
- package/dist/pipeline/steps/authorization-tuples.js.map +1 -1
- package/dist/pipeline/steps/authorize.d.ts +6 -5
- package/dist/pipeline/steps/authorize.d.ts.map +1 -1
- package/dist/pipeline/steps/authorize.js +6 -5
- package/dist/pipeline/steps/authorize.js.map +1 -1
- package/dist/pipeline/steps/defaults.d.ts +12 -0
- package/dist/pipeline/steps/defaults.d.ts.map +1 -1
- package/dist/pipeline/steps/defaults.js +42 -7
- package/dist/pipeline/steps/defaults.js.map +1 -1
- package/dist/pipeline/steps/guard-memory-capture.d.ts +13 -15
- package/dist/pipeline/steps/guard-memory-capture.d.ts.map +1 -1
- package/dist/pipeline/steps/guard-memory-capture.js +2 -3
- package/dist/pipeline/steps/guard-memory-capture.js.map +1 -1
- package/dist/runnerauth/built-in-runner-credential-provider.d.ts +0 -2
- package/dist/runnerauth/built-in-runner-credential-provider.d.ts.map +1 -1
- package/dist/runnerauth/built-in-runner-credential-provider.js +8 -17
- package/dist/runnerauth/built-in-runner-credential-provider.js.map +1 -1
- package/dist/runnerauth/runner-credential-provider.d.ts +17 -7
- package/dist/runnerauth/runner-credential-provider.d.ts.map +1 -1
- package/dist/runnerauth/runner-credential-provider.js.map +1 -1
- package/dist/sandbox/docker.d.ts.map +1 -1
- package/dist/sandbox/docker.js +3 -0
- package/dist/sandbox/docker.js.map +1 -1
- package/dist/sandbox/kubernetes.d.ts.map +1 -1
- package/dist/sandbox/kubernetes.js +3 -0
- package/dist/sandbox/kubernetes.js.map +1 -1
- package/dist/sandbox/local-process.d.ts.map +1 -1
- package/dist/sandbox/local-process.js +4 -0
- package/dist/sandbox/local-process.js.map +1 -1
- package/dist/sandbox/provisioner.d.ts +18 -6
- package/dist/sandbox/provisioner.d.ts.map +1 -1
- package/dist/sandbox/provisioner.js.map +1 -1
- package/dist/temporal/manager.d.ts +5 -0
- package/dist/temporal/manager.d.ts.map +1 -1
- package/dist/temporal/manager.js +9 -0
- package/dist/temporal/manager.js.map +1 -1
- package/dist/temporal/mcpserver/engine-client.d.ts +2 -2
- package/dist/temporal/mcpserver/engine-client.d.ts.map +1 -1
- package/dist/temporal/mcpserver/engine-client.js +6 -4
- package/dist/temporal/mcpserver/engine-client.js.map +1 -1
- package/dist/temporal/mcpserver/names.d.ts +13 -2
- package/dist/temporal/mcpserver/names.d.ts.map +1 -1
- package/dist/temporal/mcpserver/names.js +15 -2
- package/dist/temporal/mcpserver/names.js.map +1 -1
- package/dist/temporal/sdk-logger.d.ts +74 -0
- package/dist/temporal/sdk-logger.d.ts.map +1 -0
- package/dist/temporal/sdk-logger.js +143 -0
- package/dist/temporal/sdk-logger.js.map +1 -0
- package/package.json +6 -6
- package/src/authorization/README.md +18 -6
- package/src/authorization/__tests__/authorizer.test.ts +5 -1
- package/src/authorization/__tests__/derived-tuples.test.ts +26 -0
- package/src/authorization/__tests__/evaluator.test.ts +4 -0
- package/src/authorization/__tests__/list-read-scope.test.ts +11 -5
- package/src/authorization/__tests__/store-tests.test.ts +3 -1
- package/src/authorization/__tests__/trusted-local-authorizer.test.ts +155 -0
- package/src/authorization/__tests__/unit-owned-kinds.test.ts +420 -0
- package/src/authorization/__tests__/wire-permissions.test.ts +31 -2
- package/src/authorization/authorizer.ts +21 -10
- package/src/authorization/derived-tuples.ts +92 -18
- package/src/authorization/evaluator.ts +30 -15
- package/src/authorization/list-read-scope.ts +4 -0
- package/src/authorization/model/__tests__/registry.test.ts +23 -0
- package/src/authorization/model/data/authorization-model.json +830 -67
- package/src/authorization/model/execution-viewer.ts +32 -27
- package/src/authorization/model/index.ts +4 -1
- package/src/authorization/model/rewrite.ts +5 -3
- package/src/authorization/organization-directory.ts +4 -0
- package/src/authorization/person.ts +32 -1
- package/src/authorization/policy-check.ts +105 -0
- package/src/authorization/posture.ts +45 -4
- package/src/authorization/resource-creators.ts +48 -0
- package/src/authorization/trusted-local-authorizer.ts +91 -0
- package/src/authorization/tuples.ts +17 -0
- package/src/boot/__tests__/compose.test.ts +120 -4
- package/src/boot/__tests__/list-indexes.test.ts +4 -0
- package/src/boot/__tests__/oauth-redirect-uri.test.ts +121 -10
- package/src/boot/__tests__/skill-transfer-origin.test.ts +96 -25
- package/src/boot/compose.ts +153 -61
- package/src/boot/config.ts +28 -12
- package/src/boot/inprocess.ts +18 -4
- package/src/boot/list-indexes.ts +6 -1
- package/src/boot/logger.ts +3 -1
- package/src/boot/oauth-redirect-uri.ts +62 -17
- package/src/boot/skill-transfer-origin.ts +71 -16
- package/src/domain/agent/__tests__/agent.test.ts +42 -1
- package/src/domain/agentchannel/__tests__/agentchannel.test.ts +9 -0
- package/src/domain/agentchannel/__tests__/channel-runtime.test.ts +2 -0
- package/src/domain/agentchannel/__tests__/create-authorization.test.ts +7 -6
- package/src/domain/agentchannel/steps.ts +9 -7
- package/src/domain/agentexecution/__tests__/agentexecution.test.ts +148 -56
- package/src/domain/agentexecution/__tests__/create-steps.test.ts +175 -12
- package/src/domain/agentexecution/__tests__/file-review-seed.ts +91 -0
- package/src/domain/agentexecution/controller.ts +8 -0
- package/src/domain/agentexecution/create-steps.ts +74 -44
- package/src/domain/agentexecution/submit-approval.ts +9 -6
- package/src/domain/agentexecution/submit-file-decision.ts +5 -4
- package/src/domain/agentinstance/__tests__/agentinstance.test.ts +2 -0
- package/src/domain/agentshare/__tests__/agentshare.test.ts +17 -0
- package/src/domain/agentshare/__tests__/create-authorization.test.ts +5 -4
- package/src/domain/agentshare/steps.ts +6 -4
- package/src/domain/apikey/__tests__/verifier.test.ts +73 -1
- package/src/domain/apikey/verifier.ts +45 -1
- package/src/domain/artifact/__tests__/artifact.test.ts +13 -24
- package/src/domain/channelapp/__tests__/channelapp.test.ts +7 -0
- package/src/domain/channelapp/controller.ts +4 -3
- package/src/domain/environment/__tests__/environment.test.ts +13 -0
- package/src/domain/executioncontext/__tests__/executioncontext.test.ts +2 -0
- package/src/domain/executioncontext/steps.ts +2 -1
- package/src/domain/iampolicy/__tests__/access-lists.test.ts +79 -0
- package/src/domain/iampolicy/__tests__/change.test.ts +63 -0
- package/src/domain/iampolicy/__tests__/controller.test.ts +39 -3
- package/src/domain/iampolicy/__tests__/grant-path.test.ts +595 -27
- package/src/domain/iampolicy/__tests__/iampolicy.test.ts +33 -2
- package/src/domain/iampolicy/__tests__/membership.test.ts +47 -5
- package/src/domain/iampolicy/__tests__/resource-store.test.ts +1 -0
- package/src/domain/iampolicy/__tests__/role-lifecycle.test.ts +41 -8
- package/src/domain/iampolicy/__tests__/roles.test.ts +3 -2
- package/src/domain/iampolicy/__tests__/steps.test.ts +75 -6
- package/src/domain/iampolicy/__tests__/support.ts +68 -4
- package/src/domain/iampolicy/access-lists.ts +70 -2
- package/src/domain/iampolicy/change.ts +109 -0
- package/src/domain/iampolicy/constants.ts +8 -0
- package/src/domain/iampolicy/controller.ts +17 -3
- package/src/domain/iampolicy/grant-path.ts +349 -31
- package/src/domain/iampolicy/membership.ts +32 -12
- package/src/domain/iampolicy/resource-store.ts +4 -0
- package/src/domain/iampolicy/role-lifecycle.ts +2 -0
- package/src/domain/iampolicy/roles.ts +8 -0
- package/src/domain/iampolicy/steps.ts +15 -5
- package/src/domain/iampolicy/store-contract.ts +37 -1
- package/src/domain/iampolicy/store.ts +19 -5
- package/src/domain/identityaccount/__tests__/resolve.test.ts +246 -2
- package/src/domain/identityaccount/__tests__/resource-store.test.ts +1 -1
- package/src/domain/identityaccount/constants.ts +20 -0
- package/src/domain/identityaccount/controller.ts +20 -5
- package/src/domain/identityaccount/resolve.ts +80 -1
- package/src/domain/identityaccount/resource-store.ts +14 -1
- package/src/domain/identityaccount/steps.ts +4 -3
- package/src/domain/identityaccount/store-contract.ts +4 -4
- package/src/domain/identityaccount/store.ts +6 -1
- package/src/domain/mcpserver/__tests__/connect-authorization.test.ts +1 -0
- package/src/domain/mcpserver/__tests__/connect.test.ts +358 -15
- package/src/domain/mcpserver/__tests__/mcpserver.test.ts +2 -0
- package/src/domain/mcpserver/__tests__/oauth-handshake.test.ts +2 -0
- package/src/domain/mcpserver/__tests__/store-faults.test.ts +2 -0
- package/src/domain/mcpserver/connect-sandbox.ts +135 -0
- package/src/domain/mcpserver/connect.ts +226 -56
- package/src/domain/mcpserver/controller.ts +8 -2
- package/src/domain/mcpserver/engine.ts +24 -6
- package/src/domain/mcpserver/start-connect.ts +49 -10
- package/src/domain/memory/__tests__/memory.test.ts +92 -22
- package/src/domain/memory/__tests__/queries.test.ts +173 -0
- package/src/domain/memory/controller.ts +2 -1
- package/src/domain/memory/list-index.ts +32 -0
- package/src/domain/memory/queries.ts +72 -0
- package/src/domain/memory/steps.ts +26 -63
- package/src/domain/oauthapp/__tests__/oauthapp.test.ts +14 -0
- package/src/domain/organization/__tests__/support.ts +41 -0
- package/src/domain/organization/steps.ts +1 -0
- package/src/domain/platformclient/mint.ts +6 -2
- package/src/domain/platformclient/verifier.ts +6 -3
- package/src/domain/plugin/__tests__/plugin.test.ts +11 -24
- package/src/domain/plugin/push.ts +1 -0
- package/src/domain/schedule/__tests__/schedule.composed.test.ts +2 -0
- package/src/domain/schedule/steps.ts +3 -1
- package/src/domain/session/__tests__/session.test.ts +2 -0
- package/src/domain/skill/__tests__/skill.test.ts +7 -25
- package/src/domain/skill/push.ts +1 -0
- package/src/domain/workflow/__tests__/workflow.test.ts +2 -0
- package/src/domain/workflow/registry/data/task-kind-registry.json +27 -1
- package/src/domain/workflowexecution/__tests__/forward-attribution-composed.test.ts +270 -0
- package/src/domain/workflowexecution/__tests__/submit-workflow-task-approval.test.ts +196 -0
- package/src/domain/workflowexecution/__tests__/workflowexecution.test.ts +3 -57
- package/src/domain/workflowexecution/submit-approval.ts +9 -2
- package/src/domain/workflowexecution/submit-file-decision.ts +6 -1
- package/src/domain/workflowexecution/submit-workflow-task-approval.ts +23 -5
- package/src/domain/workflowinstance/controller.ts +27 -9
- package/src/domain/workflowinstance/steps.ts +123 -1
- package/src/extensions/__tests__/apikey-before-sign-in-composed.test.ts +172 -0
- package/src/extensions/__tests__/built-in-authorization-composed.test.ts +80 -1
- package/src/extensions/__tests__/composed-services-composed.test.ts +236 -0
- package/src/extensions/__tests__/extension-composition.test.ts +229 -16
- package/src/extensions/__tests__/identity-account-composed.test.ts +84 -4
- package/src/extensions/__tests__/list-read-scope-composed.test.ts +2 -0
- package/src/extensions/__tests__/registry.test.ts +147 -1
- package/src/extensions/__tests__/secret-cleanup-composed.test.ts +2 -0
- package/src/extensions/__tests__/visitor-classifier-points.test.ts +42 -0
- package/src/extensions/composed-services.ts +61 -0
- package/src/extensions/drivers.ts +33 -1
- package/src/extensions/identity.ts +4 -1
- package/src/extensions/registry.ts +105 -0
- package/src/extensions/resource-authorization.ts +87 -0
- package/src/extensions/resource-row-reader.ts +43 -0
- package/src/extensions/visitor-classifier.ts +41 -0
- package/src/identity/__tests__/oidc-verifier.test.ts +38 -12
- package/src/identity/oidc-userinfo.ts +6 -1
- package/src/identity/oidc-verifier.ts +42 -8
- package/src/index.ts +61 -6
- package/src/pipeline/__tests__/steps.test.ts +31 -4
- package/src/pipeline/errors.ts +30 -16
- package/src/pipeline/interceptors/auth.ts +17 -9
- package/src/pipeline/steps/__tests__/authorization-tuples.test.ts +20 -0
- package/src/pipeline/steps/__tests__/guard-memory-capture.test.ts +72 -15
- package/src/pipeline/steps/authorization-tuples.ts +54 -0
- package/src/pipeline/steps/authorize.ts +6 -5
- package/src/pipeline/steps/defaults.ts +52 -7
- package/src/pipeline/steps/guard-memory-capture.ts +15 -20
- package/src/runnerauth/__tests__/built-in-runner-credential-provider.test.ts +1 -1
- package/src/runnerauth/__tests__/runner-subject-composed.test.ts +13 -0
- package/src/runnerauth/bound-execution.ts +2 -2
- package/src/runnerauth/built-in-runner-credential-provider.ts +8 -21
- package/src/runnerauth/runner-credential-provider.ts +17 -7
- package/src/sandbox/__tests__/docker.integration.test.ts +4 -0
- package/src/sandbox/__tests__/kubernetes.test.ts +18 -1
- package/src/sandbox/__tests__/local-process.integration.test.ts +4 -0
- package/src/sandbox/__tests__/provisioner.test.ts +1 -0
- package/src/sandbox/docker.ts +3 -0
- package/src/sandbox/kubernetes.ts +3 -0
- package/src/sandbox/local-process.ts +4 -0
- package/src/sandbox/provisioner.ts +18 -6
- package/src/store/postgres/__tests__/support.ts +11 -2
- package/src/temporal/README.md +1 -0
- package/src/temporal/__tests__/manager.test.ts +56 -4
- package/src/temporal/__tests__/sdk-log-workflows.ts +26 -0
- package/src/temporal/__tests__/sdk-logger.e2e.test.ts +150 -0
- package/src/temporal/__tests__/sdk-logger.test.ts +238 -0
- package/src/temporal/manager.ts +9 -0
- package/src/temporal/mcpserver/engine-client.ts +8 -3
- package/src/temporal/mcpserver/names.ts +16 -2
- package/src/temporal/sdk-logger.ts +173 -0
- package/dist/authorization/lane-admission.d.ts +0 -50
- package/dist/authorization/lane-admission.d.ts.map +0 -1
- package/dist/authorization/lane-admission.js +0 -13
- package/dist/authorization/lane-admission.js.map +0 -1
- package/src/authorization/__tests__/lane-admission.test.ts +0 -115
- package/src/authorization/lane-admission.ts +0 -73
|
@@ -0,0 +1,236 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Pins the two unit points and the edition's sign-in rule on real boots
|
|
3
|
+
* (extensions/composed-services.ts, boot/compose.ts):
|
|
4
|
+
*
|
|
5
|
+
* - `onComposed` hands every unit the composition's own instances before
|
|
6
|
+
* `composeServer` returns: the very Authorizer a unit registered, its
|
|
7
|
+
* list scope, its engine's check and its lifecycle, and the one
|
|
8
|
+
* in-process transport; under open source's own authorization, the
|
|
9
|
+
* built-in Authorizer, list scope and policy check.
|
|
10
|
+
* - `start` runs in unit order, first in `start()`, before the server
|
|
11
|
+
* reports SERVING; a failing start fails `start()`, naming its unit.
|
|
12
|
+
* - An edition above open source with no sign-in is refused at boot,
|
|
13
|
+
* whichever authorizer it runs.
|
|
14
|
+
*/
|
|
15
|
+
import { generateKeyPairSync } from "node:crypto";
|
|
16
|
+
import { mkdtempSync, rmSync } from "node:fs";
|
|
17
|
+
import { tmpdir } from "node:os";
|
|
18
|
+
import path from "node:path";
|
|
19
|
+
|
|
20
|
+
import { afterEach, describe, expect, it } from "vitest";
|
|
21
|
+
|
|
22
|
+
import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
|
|
23
|
+
import { HealthCheckResponse_ServingStatus } from "@stigmer/protos/grpc/health/v1/health_pb";
|
|
24
|
+
import { ServerEdition } from "@stigmer/protos/ai/stigmer/platform/v1/server_info_pb";
|
|
25
|
+
|
|
26
|
+
import { loadConfig } from "../../boot/config.js";
|
|
27
|
+
import { composeServer } from "../../boot/compose.js";
|
|
28
|
+
import type { ComposedServer } from "../../boot/compose.js";
|
|
29
|
+
import { createLogger } from "../../boot/logger.js";
|
|
30
|
+
import { newPermissiveSingleTeamAuthorizer } from "../../pipeline/steps/authorize.js";
|
|
31
|
+
import { platformTokenKeyRingFromPem } from "../../platformtoken/key-ring.js";
|
|
32
|
+
import type { AuthorizationQueryEngine } from "../authorization-queries.js";
|
|
33
|
+
import type { ComposedServices } from "../composed-services.js";
|
|
34
|
+
import type { IdentityVerifier } from "../identity.js";
|
|
35
|
+
import type { ListReadScope } from "../list-read-scope.js";
|
|
36
|
+
import type { ServerExtension } from "../registry.js";
|
|
37
|
+
import type { ResourceAuthorizationLifecycle } from "../resource-authorization.js";
|
|
38
|
+
import type { ResourceRowReader } from "../resource-row-reader.js";
|
|
39
|
+
|
|
40
|
+
const silentLogger = createLogger({
|
|
41
|
+
level: "error",
|
|
42
|
+
pretty: false,
|
|
43
|
+
write: () => {},
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
const verifier: IdentityVerifier = {
|
|
47
|
+
name: "fixture-verifier",
|
|
48
|
+
verify: () => Promise.resolve(null),
|
|
49
|
+
};
|
|
50
|
+
const ringKeys = generateKeyPairSync("rsa", { modulusLength: 2048 });
|
|
51
|
+
const RING = platformTokenKeyRingFromPem({
|
|
52
|
+
privateKeyPem: ringKeys.privateKey
|
|
53
|
+
.export({ format: "pem", type: "pkcs8" })
|
|
54
|
+
.toString(),
|
|
55
|
+
publicKeyPems: [
|
|
56
|
+
ringKeys.publicKey.export({ format: "pem", type: "spki" }).toString(),
|
|
57
|
+
],
|
|
58
|
+
});
|
|
59
|
+
const noRows: ResourceRowReader = {
|
|
60
|
+
findById: () => Promise.resolve(undefined),
|
|
61
|
+
};
|
|
62
|
+
|
|
63
|
+
/** An Enterprise unit on open source's own authorization: sign-in, a key ring, a reader per kind. */
|
|
64
|
+
function enterpriseUnit(extra: Partial<ServerExtension> = {}): ServerExtension {
|
|
65
|
+
return {
|
|
66
|
+
name: "enterprise-fixture",
|
|
67
|
+
edition: ServerEdition.enterprise,
|
|
68
|
+
requireAuthentication: true,
|
|
69
|
+
identityVerifiers: [verifier],
|
|
70
|
+
drivers: {
|
|
71
|
+
platformTokenKeys: RING,
|
|
72
|
+
resourceRowReaders: new Map([
|
|
73
|
+
[ApiResourceKind.identity_provider, noRows],
|
|
74
|
+
[ApiResourceKind.invitation, noRows],
|
|
75
|
+
[ApiResourceKind.team, noRows],
|
|
76
|
+
]),
|
|
77
|
+
},
|
|
78
|
+
...extra,
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const dirs: string[] = [];
|
|
83
|
+
const servers: ComposedServer[] = [];
|
|
84
|
+
|
|
85
|
+
async function compose(
|
|
86
|
+
extensions: ReadonlyArray<ServerExtension>,
|
|
87
|
+
): Promise<ComposedServer> {
|
|
88
|
+
const dir = mkdtempSync(path.join(tmpdir(), "composed-services-"));
|
|
89
|
+
dirs.push(dir);
|
|
90
|
+
const server = await composeServer({
|
|
91
|
+
config: loadConfig({
|
|
92
|
+
STIGMER_MODEL_REGISTRY_REFRESH: "off",
|
|
93
|
+
DB_PATH: path.join(dir, "stigmer.db"),
|
|
94
|
+
ARTIFACT_LOCAL_BASE_PATH: path.join(dir, "artifacts"),
|
|
95
|
+
}),
|
|
96
|
+
logger: silentLogger,
|
|
97
|
+
extensions: [...extensions],
|
|
98
|
+
portOverride: 0,
|
|
99
|
+
host: "127.0.0.1",
|
|
100
|
+
});
|
|
101
|
+
servers.push(server);
|
|
102
|
+
return server;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
afterEach(async () => {
|
|
106
|
+
for (const server of servers.splice(0)) {
|
|
107
|
+
await server.shutdown();
|
|
108
|
+
}
|
|
109
|
+
for (const dir of dirs.splice(0)) {
|
|
110
|
+
rmSync(dir, { recursive: true, force: true });
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
|
|
114
|
+
describe("onComposed: a unit receives the composition's own instances", () => {
|
|
115
|
+
it("hands a unit the very Authorizer, list scope, check and lifecycle a unit registered, and the one in-process transport, before composeServer returns", async () => {
|
|
116
|
+
const authorizer = newPermissiveSingleTeamAuthorizer();
|
|
117
|
+
const listReadScope: ListReadScope = {
|
|
118
|
+
authorizedResourceIds: () => Promise.resolve(new Set()),
|
|
119
|
+
restrictListEntries: () => Promise.resolve(new Set()),
|
|
120
|
+
};
|
|
121
|
+
const queries: AuthorizationQueryEngine = {
|
|
122
|
+
check: () => Promise.resolve(true),
|
|
123
|
+
listResourceIds: () => Promise.resolve([]),
|
|
124
|
+
listPrincipalIds: () => Promise.resolve([]),
|
|
125
|
+
};
|
|
126
|
+
const lifecycle: ResourceAuthorizationLifecycle = {
|
|
127
|
+
onResourceCreated: () => Promise.resolve(),
|
|
128
|
+
onResourceDeleted: () => Promise.resolve(),
|
|
129
|
+
onVisibilityChanged: () => Promise.resolve(),
|
|
130
|
+
};
|
|
131
|
+
let received: ComposedServices | undefined;
|
|
132
|
+
const server = await compose([
|
|
133
|
+
{
|
|
134
|
+
name: "cloud-shaped",
|
|
135
|
+
edition: ServerEdition.cloud,
|
|
136
|
+
requireAuthentication: true,
|
|
137
|
+
identityVerifiers: [verifier],
|
|
138
|
+
authorizer,
|
|
139
|
+
drivers: {
|
|
140
|
+
platformTokenKeys: RING,
|
|
141
|
+
listReadScope,
|
|
142
|
+
authorizationQueries: queries,
|
|
143
|
+
resourceAuthorizationLifecycle: lifecycle,
|
|
144
|
+
},
|
|
145
|
+
},
|
|
146
|
+
{
|
|
147
|
+
name: "consumer",
|
|
148
|
+
onComposed: (composed) => {
|
|
149
|
+
received = composed;
|
|
150
|
+
},
|
|
151
|
+
},
|
|
152
|
+
]);
|
|
153
|
+
expect(received).toBeDefined();
|
|
154
|
+
expect(received?.authorizer).toBe(authorizer);
|
|
155
|
+
expect(received?.listReadScope).toBe(listReadScope);
|
|
156
|
+
expect(received?.authorizationQueries).toBe(queries);
|
|
157
|
+
expect(received?.resourceAuthorizationLifecycle).toBe(lifecycle);
|
|
158
|
+
expect(received?.inProcessTransport).toBe(server.inProcessTransport);
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
it("under open source's own authorization hands the built-in Authorizer, list scope and policy check, and no lifecycle", async () => {
|
|
162
|
+
let received: ComposedServices | undefined;
|
|
163
|
+
await compose([
|
|
164
|
+
enterpriseUnit({
|
|
165
|
+
onComposed: (composed) => {
|
|
166
|
+
received = composed;
|
|
167
|
+
},
|
|
168
|
+
}),
|
|
169
|
+
]);
|
|
170
|
+
expect(received?.authorizer).toBeDefined();
|
|
171
|
+
expect(received?.listReadScope).toBeDefined();
|
|
172
|
+
expect(received?.authorizationQueries).toBeDefined();
|
|
173
|
+
expect(received?.resourceAuthorizationLifecycle).toBeUndefined();
|
|
174
|
+
});
|
|
175
|
+
});
|
|
176
|
+
|
|
177
|
+
describe("start: a unit's boot work runs before anything serves", () => {
|
|
178
|
+
it("runs each unit's start in unit order, before the server reports SERVING", async () => {
|
|
179
|
+
const seen: string[] = [];
|
|
180
|
+
let server: ComposedServer | undefined;
|
|
181
|
+
const observe = (unit: string) => (): Promise<void> => {
|
|
182
|
+
seen.push(
|
|
183
|
+
`${unit}:${HealthCheckResponse_ServingStatus[server?.healthState.status("") ?? HealthCheckResponse_ServingStatus.UNKNOWN]}`,
|
|
184
|
+
);
|
|
185
|
+
return Promise.resolve();
|
|
186
|
+
};
|
|
187
|
+
server = await compose([
|
|
188
|
+
enterpriseUnit({ start: observe("first") }),
|
|
189
|
+
{ name: "second", start: observe("second") },
|
|
190
|
+
]);
|
|
191
|
+
await server.start();
|
|
192
|
+
expect(seen).toEqual(["first:NOT_SERVING", "second:NOT_SERVING"]);
|
|
193
|
+
expect(server.healthState.status("")).toBe(
|
|
194
|
+
HealthCheckResponse_ServingStatus.SERVING,
|
|
195
|
+
);
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
it("a failing start fails the server's start, naming its unit, and the server never reports SERVING", async () => {
|
|
199
|
+
const server = await compose([
|
|
200
|
+
enterpriseUnit({
|
|
201
|
+
start: () => Promise.reject(new Error("repair failed")),
|
|
202
|
+
}),
|
|
203
|
+
]);
|
|
204
|
+
await expect(server.start()).rejects.toThrowError(
|
|
205
|
+
"extension 'enterprise-fixture' failed to start: repair failed",
|
|
206
|
+
);
|
|
207
|
+
expect(server.healthState.status("")).toBe(
|
|
208
|
+
HealthCheckResponse_ServingStatus.NOT_SERVING,
|
|
209
|
+
);
|
|
210
|
+
});
|
|
211
|
+
});
|
|
212
|
+
|
|
213
|
+
describe("an edition above open source signs its callers in", () => {
|
|
214
|
+
it.each([
|
|
215
|
+
["on open source's own authorizer", {}],
|
|
216
|
+
[
|
|
217
|
+
"with its own Authorizer",
|
|
218
|
+
{ authorizer: newPermissiveSingleTeamAuthorizer() },
|
|
219
|
+
],
|
|
220
|
+
])(
|
|
221
|
+
"refuses to boot trusted-local %s",
|
|
222
|
+
async (_label, extra: Partial<ServerExtension>) => {
|
|
223
|
+
await expect(
|
|
224
|
+
compose([
|
|
225
|
+
{
|
|
226
|
+
name: "signed-out-enterprise",
|
|
227
|
+
edition: ServerEdition.enterprise,
|
|
228
|
+
...extra,
|
|
229
|
+
},
|
|
230
|
+
]),
|
|
231
|
+
).rejects.toThrowError(
|
|
232
|
+
"the composition serves edition 'enterprise' without the require-authentication posture — an edition above open source must sign its callers in: declare requireAuthentication on a unit that registers a verifier, or configure STIGMER_OIDC_ISSUER",
|
|
233
|
+
);
|
|
234
|
+
},
|
|
235
|
+
);
|
|
236
|
+
});
|
|
@@ -17,11 +17,12 @@
|
|
|
17
17
|
* to before the parameter existed — is pinned where it belongs: the
|
|
18
18
|
* platform domain suite (edition oss) and the four conformance rosters.
|
|
19
19
|
*/
|
|
20
|
+
import { generateKeyPairSync } from "node:crypto";
|
|
20
21
|
import { mkdtempSync, rmSync } from "node:fs";
|
|
21
22
|
import { tmpdir } from "node:os";
|
|
22
23
|
import path from "node:path";
|
|
23
24
|
|
|
24
|
-
import { create } from "@bufbuild/protobuf";
|
|
25
|
+
import { clone, create } from "@bufbuild/protobuf";
|
|
25
26
|
import type { DescMessage } from "@bufbuild/protobuf";
|
|
26
27
|
import { Code, ConnectError, createClient } from "@connectrpc/connect";
|
|
27
28
|
import type { Transport } from "@connectrpc/connect";
|
|
@@ -38,6 +39,12 @@ import {
|
|
|
38
39
|
ExecutionPhase,
|
|
39
40
|
} from "@stigmer/protos/ai/stigmer/agentic/agentexecution/v1/enum_pb";
|
|
40
41
|
import { SessionSchema } from "@stigmer/protos/ai/stigmer/agentic/session/v1/api_pb";
|
|
42
|
+
import { WorkflowSchema } from "@stigmer/protos/ai/stigmer/agentic/workflow/v1/api_pb";
|
|
43
|
+
import { WorkflowCommandController } from "@stigmer/protos/ai/stigmer/agentic/workflow/v1/command_pb";
|
|
44
|
+
import { WorkflowInstanceSchema } from "@stigmer/protos/ai/stigmer/agentic/workflowinstance/v1/api_pb";
|
|
45
|
+
import { WorkflowInstanceCommandController } from "@stigmer/protos/ai/stigmer/agentic/workflowinstance/v1/command_pb";
|
|
46
|
+
import { WorkflowInstanceQueryController } from "@stigmer/protos/ai/stigmer/agentic/workflowinstance/v1/query_pb";
|
|
47
|
+
import { WorkflowExecutionVisibility } from "@stigmer/protos/ai/stigmer/agentic/workflowinstance/v1/spec_pb";
|
|
41
48
|
import { SessionCommandController } from "@stigmer/protos/ai/stigmer/agentic/session/v1/command_pb";
|
|
42
49
|
import { SessionQueryController } from "@stigmer/protos/ai/stigmer/agentic/session/v1/query_pb";
|
|
43
50
|
import { BillingQueryController } from "@stigmer/protos/ai/stigmer/billing/v1/query_pb";
|
|
@@ -66,10 +73,13 @@ import type { ComposedServer } from "../../boot/compose.js";
|
|
|
66
73
|
import { createLogger } from "../../boot/logger.js";
|
|
67
74
|
import { AUTHENTICATION_TOKEN_MISSING_MESSAGE } from "../../pipeline/interceptors/auth.js";
|
|
68
75
|
import type { PipelineStep } from "../../pipeline/pipeline.js";
|
|
76
|
+
import { newPermissiveSingleTeamAuthorizer } from "../../pipeline/steps/authorize.js";
|
|
77
|
+
import { platformTokenKeyRingFromPem } from "../../platformtoken/key-ring.js";
|
|
69
78
|
import type { AuthzCheck } from "../authorizer.js";
|
|
70
79
|
import type { GateSlotName } from "../gate-slots.js";
|
|
71
80
|
import type { OrganizationDirectory } from "../organization-directory.js";
|
|
72
81
|
import type {
|
|
82
|
+
ExecutionVisibilityChangedEvent,
|
|
73
83
|
ResourceAuthorizationLifecycle,
|
|
74
84
|
ResourceCreatedEvent,
|
|
75
85
|
ResourceDeletedEvent,
|
|
@@ -77,6 +87,9 @@ import type {
|
|
|
77
87
|
} from "../resource-authorization.js";
|
|
78
88
|
import type { AgentExecutionStatusTransition } from "../status-hooks.js";
|
|
79
89
|
import type { ServerExtension } from "../registry.js";
|
|
90
|
+
import type { IdentityVerifier } from "../identity.js";
|
|
91
|
+
import type { ResourceRowReader } from "../resource-row-reader.js";
|
|
92
|
+
import { seedOrganizations } from "../../domain/organization/__tests__/support.js";
|
|
80
93
|
|
|
81
94
|
/** The refusal a call answered; a call that succeeds fails the case. */
|
|
82
95
|
async function refusalOf(work: Promise<unknown>): Promise<ConnectError> {
|
|
@@ -91,6 +104,50 @@ async function refusalOf(work: Promise<unknown>): Promise<ConnectError> {
|
|
|
91
104
|
const BILLING_PROCEDURE =
|
|
92
105
|
"/ai.stigmer.billing.v1.BillingQueryController/getBillingAccount";
|
|
93
106
|
|
|
107
|
+
/**
|
|
108
|
+
* What a composition serving an edition above open source must bring: its
|
|
109
|
+
* callers sign in (compose.ts refuses such an edition trusted-local), and
|
|
110
|
+
* it supplies its own platform-token key ring (platformtoken/key-ring.ts).
|
|
111
|
+
* One verifier claims the fixture token; the ring is generated per run.
|
|
112
|
+
*/
|
|
113
|
+
const EDITION_CALLER_TOKEN = "edition-fixture-caller";
|
|
114
|
+
const editionVerifier: IdentityVerifier = {
|
|
115
|
+
name: "edition-fixture-verifier",
|
|
116
|
+
verify: (token) =>
|
|
117
|
+
Promise.resolve(
|
|
118
|
+
token === EDITION_CALLER_TOKEN
|
|
119
|
+
? {
|
|
120
|
+
identityId: "ida_edition_fixture",
|
|
121
|
+
callerClass: "user",
|
|
122
|
+
issuer: "edition-fixture",
|
|
123
|
+
rawToken: token,
|
|
124
|
+
}
|
|
125
|
+
: null,
|
|
126
|
+
),
|
|
127
|
+
};
|
|
128
|
+
const editionKeys = generateKeyPairSync("rsa", { modulusLength: 2048 });
|
|
129
|
+
const EDITION_RING = platformTokenKeyRingFromPem({
|
|
130
|
+
privateKeyPem: editionKeys.privateKey
|
|
131
|
+
.export({ format: "pem", type: "pkcs8" })
|
|
132
|
+
.toString(),
|
|
133
|
+
publicKeyPems: [
|
|
134
|
+
editionKeys.publicKey.export({ format: "pem", type: "spki" }).toString(),
|
|
135
|
+
],
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
/** A client transport on the bound port presenting the fixture token. */
|
|
139
|
+
function editionCallerTransport(port: number): Transport {
|
|
140
|
+
return createGrpcTransport({
|
|
141
|
+
baseUrl: `http://127.0.0.1:${port}`,
|
|
142
|
+
interceptors: [
|
|
143
|
+
(next) => (request) => {
|
|
144
|
+
request.header.set("authorization", `Bearer ${EDITION_CALLER_TOKEN}`);
|
|
145
|
+
return next(request);
|
|
146
|
+
},
|
|
147
|
+
],
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
|
|
94
151
|
describe("extension composition (composed server)", () => {
|
|
95
152
|
let server: ComposedServer;
|
|
96
153
|
let dir: string;
|
|
@@ -98,9 +155,16 @@ describe("extension composition (composed server)", () => {
|
|
|
98
155
|
// Captured NDJSON log lines — the interceptor-chain proof reads them.
|
|
99
156
|
const logLines: string[] = [];
|
|
100
157
|
|
|
158
|
+
// A cloud-shaped unit: the cloud edition, its own sign-in, its own
|
|
159
|
+
// Authorizer (a permissive one; this suite pins service visibility and
|
|
160
|
+
// chain traversal, not authorization) and its own key ring.
|
|
101
161
|
const fakeBillingExtension: ServerExtension = {
|
|
102
162
|
name: "fake-billing",
|
|
103
163
|
edition: ServerEdition.cloud,
|
|
164
|
+
requireAuthentication: true,
|
|
165
|
+
identityVerifiers: [editionVerifier],
|
|
166
|
+
authorizer: newPermissiveSingleTeamAuthorizer(),
|
|
167
|
+
drivers: { platformTokenKeys: EDITION_RING },
|
|
104
168
|
services: [
|
|
105
169
|
(router): void => {
|
|
106
170
|
// Partial implementation is deliberate: the fake pins service
|
|
@@ -132,9 +196,7 @@ describe("extension composition (composed server)", () => {
|
|
|
132
196
|
host: "127.0.0.1",
|
|
133
197
|
});
|
|
134
198
|
const port = await server.start();
|
|
135
|
-
portTransport =
|
|
136
|
-
baseUrl: `http://127.0.0.1:${port}`,
|
|
137
|
-
});
|
|
199
|
+
portTransport = editionCallerTransport(port);
|
|
138
200
|
});
|
|
139
201
|
|
|
140
202
|
afterAll(async () => {
|
|
@@ -194,21 +256,35 @@ describe("extension composition (composed server)", () => {
|
|
|
194
256
|
});
|
|
195
257
|
|
|
196
258
|
/**
|
|
197
|
-
* The third edition on the wire
|
|
198
|
-
*
|
|
199
|
-
*
|
|
200
|
-
*
|
|
201
|
-
*
|
|
202
|
-
*
|
|
259
|
+
* The third edition on the wire, on open source's own authorizer: a unit
|
|
260
|
+
* declaring ServerEdition.enterprise, signing its callers in and
|
|
261
|
+
* registering a row reader for each kind the edition serves beyond open
|
|
262
|
+
* source, boots with no Authorizer of its own and is answered verbatim by
|
|
263
|
+
* getServerInfo. It pins the end-to-end path (declaration → resolved
|
|
264
|
+
* registry → the built-in posture's row rule → platform controller →
|
|
265
|
+
* wire) a self-hosted Enterprise composition takes.
|
|
203
266
|
*/
|
|
204
267
|
describe("extension composition (enterprise edition on the wire)", () => {
|
|
205
268
|
let server: ComposedServer;
|
|
206
269
|
let dir: string;
|
|
207
270
|
let portTransport: Transport;
|
|
208
271
|
|
|
272
|
+
const noRows: ResourceRowReader = {
|
|
273
|
+
findById: () => Promise.resolve(undefined),
|
|
274
|
+
};
|
|
209
275
|
const enterpriseUnit: ServerExtension = {
|
|
210
276
|
name: "fake-enterprise",
|
|
211
277
|
edition: ServerEdition.enterprise,
|
|
278
|
+
requireAuthentication: true,
|
|
279
|
+
identityVerifiers: [editionVerifier],
|
|
280
|
+
drivers: {
|
|
281
|
+
platformTokenKeys: EDITION_RING,
|
|
282
|
+
resourceRowReaders: new Map([
|
|
283
|
+
[ApiResourceKind.identity_provider, noRows],
|
|
284
|
+
[ApiResourceKind.invitation, noRows],
|
|
285
|
+
[ApiResourceKind.team, noRows],
|
|
286
|
+
]),
|
|
287
|
+
},
|
|
212
288
|
};
|
|
213
289
|
|
|
214
290
|
beforeAll(async () => {
|
|
@@ -225,9 +301,7 @@ describe("extension composition (enterprise edition on the wire)", () => {
|
|
|
225
301
|
host: "127.0.0.1",
|
|
226
302
|
});
|
|
227
303
|
const port = await server.start();
|
|
228
|
-
portTransport =
|
|
229
|
-
baseUrl: `http://127.0.0.1:${port}`,
|
|
230
|
-
});
|
|
304
|
+
portTransport = editionCallerTransport(port);
|
|
231
305
|
});
|
|
232
306
|
|
|
233
307
|
afterAll(async () => {
|
|
@@ -596,7 +670,7 @@ describe("extension composition (require-authentication posture)", () => {
|
|
|
596
670
|
}
|
|
597
671
|
});
|
|
598
672
|
|
|
599
|
-
it("a wider edition
|
|
673
|
+
it("a wider edition on the built-in authorizer with no row readers is a boot throw naming every kind it cannot read", async () => {
|
|
600
674
|
const enterpriseDir = mkdtempSync(
|
|
601
675
|
path.join(tmpdir(), "require-auth-edition-"),
|
|
602
676
|
);
|
|
@@ -616,15 +690,16 @@ describe("extension composition (require-authentication posture)", () => {
|
|
|
616
690
|
extensions: [
|
|
617
691
|
{
|
|
618
692
|
...requiringExtension,
|
|
619
|
-
name: "enterprise-without-
|
|
693
|
+
name: "enterprise-without-readers",
|
|
620
694
|
edition: ServerEdition.enterprise,
|
|
695
|
+
drivers: { platformTokenKeys: EDITION_RING },
|
|
621
696
|
},
|
|
622
697
|
],
|
|
623
698
|
portOverride: 0,
|
|
624
699
|
host: "127.0.0.1",
|
|
625
700
|
}),
|
|
626
701
|
).rejects.toThrowError(
|
|
627
|
-
/serves edition 'enterprise' under the
|
|
702
|
+
/serves edition 'enterprise' under the built-in authorizer but registers no row reader for 'identity_provider', 'invitation', 'team'/,
|
|
628
703
|
);
|
|
629
704
|
} finally {
|
|
630
705
|
rmSync(enterpriseDir, { recursive: true, force: true });
|
|
@@ -846,6 +921,7 @@ describe("extension composition (O4 gate slots + status hooks)", () => {
|
|
|
846
921
|
portTransport = createGrpcTransport({
|
|
847
922
|
baseUrl: `http://127.0.0.1:${port}`,
|
|
848
923
|
});
|
|
924
|
+
await seedOrganizations(portTransport, ["acme"]);
|
|
849
925
|
});
|
|
850
926
|
|
|
851
927
|
afterAll(async () => {
|
|
@@ -1010,8 +1086,10 @@ describe("extension composition (C2 tuple lifecycle + organization directory)",
|
|
|
1010
1086
|
const createdEvents: ResourceCreatedEvent[] = [];
|
|
1011
1087
|
const deletedEvents: ResourceDeletedEvent[] = [];
|
|
1012
1088
|
const visibilityEvents: VisibilityChangedEvent[] = [];
|
|
1089
|
+
const executionVisibilityEvents: ExecutionVisibilityChangedEvent[] = [];
|
|
1013
1090
|
let failCreates = false;
|
|
1014
1091
|
let failDeletes = false;
|
|
1092
|
+
let failExecutionVisibility = false;
|
|
1015
1093
|
|
|
1016
1094
|
const fakeLifecycle: ResourceAuthorizationLifecycle = {
|
|
1017
1095
|
async onResourceCreated(event): Promise<void> {
|
|
@@ -1029,6 +1107,12 @@ describe("extension composition (C2 tuple lifecycle + organization directory)",
|
|
|
1029
1107
|
async onVisibilityChanged(event): Promise<void> {
|
|
1030
1108
|
visibilityEvents.push(event);
|
|
1031
1109
|
},
|
|
1110
|
+
async onExecutionVisibilityChanged(event): Promise<void> {
|
|
1111
|
+
if (failExecutionVisibility) {
|
|
1112
|
+
throw new Error("fga is down");
|
|
1113
|
+
}
|
|
1114
|
+
executionVisibilityEvents.push(event);
|
|
1115
|
+
},
|
|
1032
1116
|
};
|
|
1033
1117
|
|
|
1034
1118
|
// The directory answers are test-mutable so each case can stage its
|
|
@@ -1330,4 +1414,133 @@ describe("extension composition (C2 tuple lifecycle + organization directory)",
|
|
|
1330
1414
|
expect(missing.rawMessage).toBe(`Organization not found: ${externalOrgId}`);
|
|
1331
1415
|
}
|
|
1332
1416
|
});
|
|
1417
|
+
|
|
1418
|
+
// The run audience of a workflow instance (`spec.execution_visibility`):
|
|
1419
|
+
// open source derives `execution_viewer` from the row when a check asks;
|
|
1420
|
+
// an edition that stores tuples hears it here (stigmer-cloud#720). The
|
|
1421
|
+
// event carries the audience the level now names — the whole target
|
|
1422
|
+
// state, so a retry or a repeat converges — and fires from the two doors
|
|
1423
|
+
// that may set the level: create, and the dedicated RPC. Update and Apply
|
|
1424
|
+
// ignore a request-carried level (the oss#573 rule for
|
|
1425
|
+
// metadata.visibility), so neither can silently narrow run access.
|
|
1426
|
+
describe("the run audience of a workflow instance", () => {
|
|
1427
|
+
const workflows = () => createClient(WorkflowCommandController, portTransport);
|
|
1428
|
+
const instances = () => createClient(WorkflowInstanceCommandController, portTransport);
|
|
1429
|
+
const instanceQuery = () => createClient(WorkflowInstanceQueryController, portTransport);
|
|
1430
|
+
let workflowId = "";
|
|
1431
|
+
|
|
1432
|
+
beforeAll(async () => {
|
|
1433
|
+
const workflow = await workflows().create(
|
|
1434
|
+
create(WorkflowSchema, {
|
|
1435
|
+
apiVersion: "agentic.stigmer.ai/v1",
|
|
1436
|
+
kind: "Workflow",
|
|
1437
|
+
metadata: { name: "c2-run-audience-workflow", org: "c2seededorg" },
|
|
1438
|
+
spec: {
|
|
1439
|
+
document: { dsl: "1.0.0", namespace: "tests", name: "c2-run-audience", version: "0.1.0" },
|
|
1440
|
+
tasks: [{ name: "seed", kind: 1, taskConfig: { variables: { greeting: "hello" } } }],
|
|
1441
|
+
},
|
|
1442
|
+
}),
|
|
1443
|
+
);
|
|
1444
|
+
workflowId = workflow.metadata?.id ?? "";
|
|
1445
|
+
});
|
|
1446
|
+
|
|
1447
|
+
function instanceInput(name: string, level: WorkflowExecutionVisibility) {
|
|
1448
|
+
return create(WorkflowInstanceSchema, {
|
|
1449
|
+
apiVersion: "agentic.stigmer.ai/v1",
|
|
1450
|
+
kind: "WorkflowInstance",
|
|
1451
|
+
metadata: { name, org: "c2seededorg" },
|
|
1452
|
+
spec: { workflowId, executionVisibility: level },
|
|
1453
|
+
});
|
|
1454
|
+
}
|
|
1455
|
+
|
|
1456
|
+
it("create at ORGANIZATION fires the audience once; the workflow's default instance and a private create fire nothing", async () => {
|
|
1457
|
+
// The workflow's in-process default instance was created in beforeAll
|
|
1458
|
+
// at the unset level, which names no audience.
|
|
1459
|
+
expect(executionVisibilityEvents).toEqual([]);
|
|
1460
|
+
const shared = await instances().create(
|
|
1461
|
+
instanceInput("c2-shared-runs", WorkflowExecutionVisibility.organization),
|
|
1462
|
+
);
|
|
1463
|
+
await instances().create(instanceInput("c2-private-runs", WorkflowExecutionVisibility.private));
|
|
1464
|
+
expect(executionVisibilityEvents).toEqual([
|
|
1465
|
+
{
|
|
1466
|
+
instanceKind: ApiResourceKind.workflow_instance,
|
|
1467
|
+
instanceId: shared.metadata?.id,
|
|
1468
|
+
orgId: "c2seededorg",
|
|
1469
|
+
shapes: ["org-viewer"],
|
|
1470
|
+
},
|
|
1471
|
+
]);
|
|
1472
|
+
});
|
|
1473
|
+
|
|
1474
|
+
it("updateExecutionVisibility fires the level's audience every time, the empty one included", async () => {
|
|
1475
|
+
const instance = await instances().create(
|
|
1476
|
+
instanceInput("c2-toggled-runs", WorkflowExecutionVisibility.private),
|
|
1477
|
+
);
|
|
1478
|
+
const id = instance.metadata?.id ?? "";
|
|
1479
|
+
executionVisibilityEvents.length = 0;
|
|
1480
|
+
await instances().updateExecutionVisibility({
|
|
1481
|
+
resourceId: id,
|
|
1482
|
+
executionVisibility: WorkflowExecutionVisibility.organization,
|
|
1483
|
+
});
|
|
1484
|
+
await instances().updateExecutionVisibility({
|
|
1485
|
+
resourceId: id,
|
|
1486
|
+
executionVisibility: WorkflowExecutionVisibility.private,
|
|
1487
|
+
});
|
|
1488
|
+
expect(executionVisibilityEvents.map((event) => [event.instanceId, event.shapes])).toEqual([
|
|
1489
|
+
[id, ["org-viewer"]],
|
|
1490
|
+
[id, []],
|
|
1491
|
+
]);
|
|
1492
|
+
});
|
|
1493
|
+
|
|
1494
|
+
it("update and apply keep the stored level whatever the request carries, and fire nothing", async () => {
|
|
1495
|
+
const instance = await instances().create(
|
|
1496
|
+
instanceInput("c2-kept-runs", WorkflowExecutionVisibility.organization),
|
|
1497
|
+
);
|
|
1498
|
+
const id = instance.metadata?.id ?? "";
|
|
1499
|
+
executionVisibilityEvents.length = 0;
|
|
1500
|
+
const lowered = clone(WorkflowInstanceSchema, instance);
|
|
1501
|
+
lowered.spec!.executionVisibility = WorkflowExecutionVisibility.private;
|
|
1502
|
+
lowered.spec!.description = "edited";
|
|
1503
|
+
const updated = await instances().update(lowered);
|
|
1504
|
+
expect(updated.spec?.description, "the update itself landed").toBe("edited");
|
|
1505
|
+
expect(updated.spec?.executionVisibility).toBe(WorkflowExecutionVisibility.organization);
|
|
1506
|
+
const reapplied = clone(WorkflowInstanceSchema, lowered);
|
|
1507
|
+
reapplied.spec!.executionVisibility = WorkflowExecutionVisibility.unspecified;
|
|
1508
|
+
const applied = await instances().apply(reapplied);
|
|
1509
|
+
expect(applied.spec?.executionVisibility).toBe(WorkflowExecutionVisibility.organization);
|
|
1510
|
+
const stored = await instanceQuery().get({ value: id });
|
|
1511
|
+
expect(stored.spec?.executionVisibility).toBe(WorkflowExecutionVisibility.organization);
|
|
1512
|
+
expect(executionVisibilityEvents).toEqual([]);
|
|
1513
|
+
});
|
|
1514
|
+
|
|
1515
|
+
it("a driver failure fails the RPC with the level already persisted; the retry converges", async () => {
|
|
1516
|
+
const instance = await instances().create(
|
|
1517
|
+
instanceInput("c2-retried-runs", WorkflowExecutionVisibility.private),
|
|
1518
|
+
);
|
|
1519
|
+
const id = instance.metadata?.id ?? "";
|
|
1520
|
+
failExecutionVisibility = true;
|
|
1521
|
+
let refused: ConnectError | undefined;
|
|
1522
|
+
try {
|
|
1523
|
+
await instances().updateExecutionVisibility({
|
|
1524
|
+
resourceId: id,
|
|
1525
|
+
executionVisibility: WorkflowExecutionVisibility.organization,
|
|
1526
|
+
});
|
|
1527
|
+
} catch (error) {
|
|
1528
|
+
refused = ConnectError.from(error);
|
|
1529
|
+
} finally {
|
|
1530
|
+
failExecutionVisibility = false;
|
|
1531
|
+
}
|
|
1532
|
+
expect(refused?.code).toBe(Code.Internal);
|
|
1533
|
+
expect(refused?.rawMessage).toBe("failed to update execution visibility tuples");
|
|
1534
|
+
const stored = await instanceQuery().get({ value: id });
|
|
1535
|
+
expect(stored.spec?.executionVisibility, "post-persist: the level landed").toBe(
|
|
1536
|
+
WorkflowExecutionVisibility.organization,
|
|
1537
|
+
);
|
|
1538
|
+
executionVisibilityEvents.length = 0;
|
|
1539
|
+
await instances().updateExecutionVisibility({
|
|
1540
|
+
resourceId: id,
|
|
1541
|
+
executionVisibility: WorkflowExecutionVisibility.organization,
|
|
1542
|
+
});
|
|
1543
|
+
expect(executionVisibilityEvents.map((event) => event.shapes)).toEqual([["org-viewer"]]);
|
|
1544
|
+
});
|
|
1545
|
+
});
|
|
1333
1546
|
});
|