@stigmer/server 3.15.3-dev.20260914100347 → 3.15.3-dev.20260916211208
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/archive/content-store.d.ts +35 -0
- package/dist/archive/content-store.d.ts.map +1 -0
- package/dist/archive/content-store.js +98 -0
- package/dist/archive/content-store.js.map +1 -0
- package/dist/archive/inflate.d.ts +22 -0
- package/dist/archive/inflate.d.ts.map +1 -0
- package/dist/archive/inflate.js +75 -0
- package/dist/archive/inflate.js.map +1 -0
- package/dist/archive/limits.d.ts +33 -0
- package/dist/archive/limits.d.ts.map +1 -0
- package/dist/archive/limits.js +31 -0
- package/dist/archive/limits.js.map +1 -0
- package/dist/archive/open.d.ts +24 -0
- package/dist/archive/open.d.ts.map +1 -0
- package/dist/archive/open.js +93 -0
- package/dist/archive/open.js.map +1 -0
- package/dist/{domain/skill/storage → archive}/prefilter.d.ts +5 -0
- package/dist/archive/prefilter.d.ts.map +1 -0
- package/dist/archive/prefilter.js.map +1 -0
- package/dist/archive/write.d.ts +8 -0
- package/dist/archive/write.d.ts.map +1 -0
- package/dist/archive/write.js +44 -0
- package/dist/archive/write.js.map +1 -0
- package/dist/authorization/authorizer.d.ts +98 -0
- package/dist/authorization/authorizer.d.ts.map +1 -0
- package/dist/authorization/authorizer.js +156 -0
- package/dist/authorization/authorizer.js.map +1 -0
- package/dist/authorization/derived-tuples.d.ts +42 -0
- package/dist/authorization/derived-tuples.d.ts.map +1 -0
- package/dist/authorization/derived-tuples.js +240 -0
- package/dist/authorization/derived-tuples.js.map +1 -0
- package/dist/authorization/evaluator.d.ts +66 -0
- package/dist/authorization/evaluator.d.ts.map +1 -0
- package/dist/authorization/evaluator.js +153 -0
- package/dist/authorization/evaluator.js.map +1 -0
- package/dist/authorization/facts.d.ts +29 -0
- package/dist/authorization/facts.d.ts.map +1 -0
- package/dist/authorization/facts.js +17 -0
- package/dist/authorization/facts.js.map +1 -0
- package/dist/authorization/list-read-scope.d.ts +18 -0
- package/dist/authorization/list-read-scope.d.ts.map +1 -0
- package/dist/authorization/list-read-scope.js +155 -0
- package/dist/authorization/list-read-scope.js.map +1 -0
- package/dist/authorization/model/agent.d.ts +2 -0
- package/dist/authorization/model/agent.d.ts.map +1 -0
- package/dist/authorization/model/agent.js +42 -0
- package/dist/authorization/model/agent.js.map +1 -0
- package/dist/authorization/model/agent_channel.d.ts +2 -0
- package/dist/authorization/model/agent_channel.d.ts.map +1 -0
- package/dist/authorization/model/agent_channel.js +38 -0
- package/dist/authorization/model/agent_channel.js.map +1 -0
- package/dist/authorization/model/agent_execution.d.ts +2 -0
- package/dist/authorization/model/agent_execution.d.ts.map +1 -0
- package/dist/authorization/model/agent_execution.js +25 -0
- package/dist/authorization/model/agent_execution.js.map +1 -0
- package/dist/authorization/model/agent_instance.d.ts +2 -0
- package/dist/authorization/model/agent_instance.d.ts.map +1 -0
- package/dist/authorization/model/agent_instance.js +47 -0
- package/dist/authorization/model/agent_instance.js.map +1 -0
- package/dist/authorization/model/agent_share.d.ts +2 -0
- package/dist/authorization/model/agent_share.d.ts.map +1 -0
- package/dist/authorization/model/agent_share.js +29 -0
- package/dist/authorization/model/agent_share.js.map +1 -0
- package/dist/authorization/model/api_key.d.ts +2 -0
- package/dist/authorization/model/api_key.d.ts.map +1 -0
- package/dist/authorization/model/api_key.js +27 -0
- package/dist/authorization/model/api_key.js.map +1 -0
- package/dist/authorization/model/artifact.d.ts +2 -0
- package/dist/authorization/model/artifact.d.ts.map +1 -0
- package/dist/authorization/model/artifact.js +27 -0
- package/dist/authorization/model/artifact.js.map +1 -0
- package/dist/authorization/model/channel_app.d.ts +2 -0
- package/dist/authorization/model/channel_app.d.ts.map +1 -0
- package/dist/authorization/model/channel_app.js +28 -0
- package/dist/authorization/model/channel_app.js.map +1 -0
- package/dist/authorization/model/default-of.d.ts +38 -0
- package/dist/authorization/model/default-of.d.ts.map +1 -0
- package/dist/authorization/model/default-of.js +39 -0
- package/dist/authorization/model/default-of.js.map +1 -0
- package/dist/authorization/model/environment.d.ts +2 -0
- package/dist/authorization/model/environment.d.ts.map +1 -0
- package/dist/authorization/model/environment.js +33 -0
- package/dist/authorization/model/environment.js.map +1 -0
- package/dist/authorization/model/execution_context.d.ts +2 -0
- package/dist/authorization/model/execution_context.d.ts.map +1 -0
- package/dist/authorization/model/execution_context.js +19 -0
- package/dist/authorization/model/execution_context.js.map +1 -0
- package/dist/authorization/model/iam_policy.d.ts +2 -0
- package/dist/authorization/model/iam_policy.d.ts.map +1 -0
- package/dist/authorization/model/iam_policy.js +31 -0
- package/dist/authorization/model/iam_policy.js.map +1 -0
- package/dist/authorization/model/identity_account.d.ts +2 -0
- package/dist/authorization/model/identity_account.d.ts.map +1 -0
- package/dist/authorization/model/identity_account.js +25 -0
- package/dist/authorization/model/identity_account.js.map +1 -0
- package/dist/authorization/model/index.d.ts +36 -0
- package/dist/authorization/model/index.d.ts.map +1 -0
- package/dist/authorization/model/index.js +72 -0
- package/dist/authorization/model/index.js.map +1 -0
- package/dist/authorization/model/mcp_server.d.ts +2 -0
- package/dist/authorization/model/mcp_server.d.ts.map +1 -0
- package/dist/authorization/model/mcp_server.js +37 -0
- package/dist/authorization/model/mcp_server.js.map +1 -0
- package/dist/authorization/model/memory.d.ts +2 -0
- package/dist/authorization/model/memory.d.ts.map +1 -0
- package/dist/authorization/model/memory.js +26 -0
- package/dist/authorization/model/memory.js.map +1 -0
- package/dist/authorization/model/oauth_app.d.ts +2 -0
- package/dist/authorization/model/oauth_app.d.ts.map +1 -0
- package/dist/authorization/model/oauth_app.js +30 -0
- package/dist/authorization/model/oauth_app.js.map +1 -0
- package/dist/authorization/model/organization.d.ts +2 -0
- package/dist/authorization/model/organization.d.ts.map +1 -0
- package/dist/authorization/model/organization.js +54 -0
- package/dist/authorization/model/organization.js.map +1 -0
- package/dist/authorization/model/plugin.d.ts +2 -0
- package/dist/authorization/model/plugin.d.ts.map +1 -0
- package/dist/authorization/model/plugin.js +44 -0
- package/dist/authorization/model/plugin.js.map +1 -0
- package/dist/authorization/model/project.d.ts +2 -0
- package/dist/authorization/model/project.d.ts.map +1 -0
- package/dist/authorization/model/project.js +32 -0
- package/dist/authorization/model/project.js.map +1 -0
- package/dist/authorization/model/rewrite.d.ts +127 -0
- package/dist/authorization/model/rewrite.d.ts.map +1 -0
- package/dist/authorization/model/rewrite.js +82 -0
- package/dist/authorization/model/rewrite.js.map +1 -0
- package/dist/authorization/model/schedule.d.ts +2 -0
- package/dist/authorization/model/schedule.d.ts.map +1 -0
- package/dist/authorization/model/schedule.js +29 -0
- package/dist/authorization/model/schedule.js.map +1 -0
- package/dist/authorization/model/session.d.ts +2 -0
- package/dist/authorization/model/session.d.ts.map +1 -0
- package/dist/authorization/model/session.js +38 -0
- package/dist/authorization/model/session.js.map +1 -0
- package/dist/authorization/model/skill.d.ts +2 -0
- package/dist/authorization/model/skill.d.ts.map +1 -0
- package/dist/authorization/model/skill.js +38 -0
- package/dist/authorization/model/skill.js.map +1 -0
- package/dist/authorization/model/workflow.d.ts +2 -0
- package/dist/authorization/model/workflow.d.ts.map +1 -0
- package/dist/authorization/model/workflow.js +38 -0
- package/dist/authorization/model/workflow.js.map +1 -0
- package/dist/authorization/model/workflow_execution.d.ts +2 -0
- package/dist/authorization/model/workflow_execution.d.ts.map +1 -0
- package/dist/authorization/model/workflow_execution.js +32 -0
- package/dist/authorization/model/workflow_execution.js.map +1 -0
- package/dist/authorization/model/workflow_instance.d.ts +2 -0
- package/dist/authorization/model/workflow_instance.d.ts.map +1 -0
- package/dist/authorization/model/workflow_instance.js +92 -0
- package/dist/authorization/model/workflow_instance.js.map +1 -0
- package/dist/authorization/organization-directory.d.ts +13 -0
- package/dist/authorization/organization-directory.d.ts.map +1 -0
- package/dist/authorization/organization-directory.js +83 -0
- package/dist/authorization/organization-directory.js.map +1 -0
- package/dist/authorization/person.d.ts +42 -0
- package/dist/authorization/person.d.ts.map +1 -0
- package/dist/authorization/person.js +19 -0
- package/dist/authorization/person.js.map +1 -0
- package/dist/authorization/posture.d.ts +38 -0
- package/dist/authorization/posture.d.ts.map +1 -0
- package/dist/authorization/posture.js +7 -0
- package/dist/authorization/posture.js.map +1 -0
- package/dist/authorization/schedule-fire-caller.d.ts +12 -0
- package/dist/authorization/schedule-fire-caller.d.ts.map +1 -0
- package/dist/authorization/schedule-fire-caller.js +67 -0
- package/dist/authorization/schedule-fire-caller.js.map +1 -0
- package/dist/authorization/store-test-kit.d.ts +68 -0
- package/dist/authorization/store-test-kit.d.ts.map +1 -0
- package/dist/authorization/store-test-kit.js +311 -0
- package/dist/authorization/store-test-kit.js.map +1 -0
- package/dist/authorization/tuples.d.ts +115 -0
- package/dist/authorization/tuples.d.ts.map +1 -0
- package/dist/authorization/tuples.js +83 -0
- package/dist/authorization/tuples.js.map +1 -0
- package/dist/boot/compose.d.ts.map +1 -1
- package/dist/boot/compose.js +157 -32
- package/dist/boot/compose.js.map +1 -1
- package/dist/boot/inprocess.d.ts +12 -0
- package/dist/boot/inprocess.d.ts.map +1 -1
- package/dist/boot/inprocess.js +62 -20
- package/dist/boot/inprocess.js.map +1 -1
- package/dist/domain/agent/controller.d.ts.map +1 -1
- package/dist/domain/agent/controller.js +9 -0
- package/dist/domain/agent/controller.js.map +1 -1
- package/dist/domain/iampolicy/constants.d.ts +11 -0
- package/dist/domain/iampolicy/constants.d.ts.map +1 -1
- package/dist/domain/iampolicy/constants.js +11 -0
- package/dist/domain/iampolicy/constants.js.map +1 -1
- package/dist/domain/iampolicy/membership.d.ts +72 -1
- package/dist/domain/iampolicy/membership.d.ts.map +1 -1
- package/dist/domain/iampolicy/membership.js +141 -56
- package/dist/domain/iampolicy/membership.js.map +1 -1
- package/dist/domain/identityaccount/actor.d.ts +26 -0
- package/dist/domain/identityaccount/actor.d.ts.map +1 -0
- package/dist/domain/identityaccount/actor.js +17 -0
- package/dist/domain/identityaccount/actor.js.map +1 -0
- package/dist/domain/mcpserver/controller.d.ts.map +1 -1
- package/dist/domain/mcpserver/controller.js +9 -0
- package/dist/domain/mcpserver/controller.js.map +1 -1
- package/dist/domain/plugin/archive.d.ts +37 -0
- package/dist/domain/plugin/archive.d.ts.map +1 -0
- package/dist/domain/plugin/archive.js +50 -0
- package/dist/domain/plugin/archive.js.map +1 -0
- package/dist/domain/plugin/constants.d.ts +38 -0
- package/dist/domain/plugin/constants.d.ts.map +1 -0
- package/dist/domain/plugin/constants.js +46 -0
- package/dist/domain/plugin/constants.js.map +1 -0
- package/dist/domain/plugin/controller.d.ts +25 -0
- package/dist/domain/plugin/controller.d.ts.map +1 -0
- package/dist/domain/plugin/controller.js +493 -0
- package/dist/domain/plugin/controller.js.map +1 -0
- package/dist/domain/plugin/materialize/agent.d.ts +13 -0
- package/dist/domain/plugin/materialize/agent.d.ts.map +1 -0
- package/dist/domain/plugin/materialize/agent.js +128 -0
- package/dist/domain/plugin/materialize/agent.js.map +1 -0
- package/dist/domain/plugin/materialize/default-agent-instructions.d.ts +22 -0
- package/dist/domain/plugin/materialize/default-agent-instructions.d.ts.map +1 -0
- package/dist/domain/plugin/materialize/default-agent-instructions.js +31 -0
- package/dist/domain/plugin/materialize/default-agent-instructions.js.map +1 -0
- package/dist/domain/plugin/materialize/identity.d.ts +28 -0
- package/dist/domain/plugin/materialize/identity.d.ts.map +1 -0
- package/dist/domain/plugin/materialize/identity.js +40 -0
- package/dist/domain/plugin/materialize/identity.js.map +1 -0
- package/dist/domain/plugin/materialize/mcp-servers.d.ts +15 -0
- package/dist/domain/plugin/materialize/mcp-servers.d.ts.map +1 -0
- package/dist/domain/plugin/materialize/mcp-servers.js +131 -0
- package/dist/domain/plugin/materialize/mcp-servers.js.map +1 -0
- package/dist/domain/plugin/materialize/plan.d.ts +24 -0
- package/dist/domain/plugin/materialize/plan.d.ts.map +1 -0
- package/dist/domain/plugin/materialize/plan.js +77 -0
- package/dist/domain/plugin/materialize/plan.js.map +1 -0
- package/dist/domain/plugin/materialize/ports.d.ts +42 -0
- package/dist/domain/plugin/materialize/ports.d.ts.map +1 -0
- package/dist/domain/plugin/materialize/ports.js +2 -0
- package/dist/domain/plugin/materialize/ports.js.map +1 -0
- package/dist/domain/plugin/materialize/skills.d.ts +12 -0
- package/dist/domain/plugin/materialize/skills.d.ts.map +1 -0
- package/dist/domain/plugin/materialize/skills.js +44 -0
- package/dist/domain/plugin/materialize/skills.js.map +1 -0
- package/dist/domain/plugin/materialize/workflows.d.ts +15 -0
- package/dist/domain/plugin/materialize/workflows.d.ts.map +1 -0
- package/dist/domain/plugin/materialize/workflows.js +31 -0
- package/dist/domain/plugin/materialize/workflows.js.map +1 -0
- package/dist/domain/plugin/members.d.ts +42 -0
- package/dist/domain/plugin/members.d.ts.map +1 -0
- package/dist/domain/plugin/members.js +97 -0
- package/dist/domain/plugin/members.js.map +1 -0
- package/dist/domain/plugin/overlay/documents.d.ts +31 -0
- package/dist/domain/plugin/overlay/documents.d.ts.map +1 -0
- package/dist/domain/plugin/overlay/documents.js +38 -0
- package/dist/domain/plugin/overlay/documents.js.map +1 -0
- package/dist/domain/plugin/overlay/parse.d.ts +16 -0
- package/dist/domain/plugin/overlay/parse.d.ts.map +1 -0
- package/dist/domain/plugin/overlay/parse.js +79 -0
- package/dist/domain/plugin/overlay/parse.js.map +1 -0
- package/dist/domain/plugin/overlay/sanitize.d.ts +10 -0
- package/dist/domain/plugin/overlay/sanitize.d.ts.map +1 -0
- package/dist/domain/plugin/overlay/sanitize.js +101 -0
- package/dist/domain/plugin/overlay/sanitize.js.map +1 -0
- package/dist/domain/plugin/push.d.ts +133 -0
- package/dist/domain/plugin/push.d.ts.map +1 -0
- package/dist/domain/plugin/push.js +800 -0
- package/dist/domain/plugin/push.js.map +1 -0
- package/dist/domain/plugin/search-extractor.d.ts +3 -0
- package/dist/domain/plugin/search-extractor.d.ts.map +1 -0
- package/dist/domain/plugin/search-extractor.js +41 -0
- package/dist/domain/plugin/search-extractor.js.map +1 -0
- package/dist/domain/skill/constants.d.ts +6 -11
- package/dist/domain/skill/constants.d.ts.map +1 -1
- package/dist/domain/skill/constants.js +6 -11
- package/dist/domain/skill/constants.js.map +1 -1
- package/dist/domain/skill/controller.d.ts.map +1 -1
- package/dist/domain/skill/controller.js +33 -30
- package/dist/domain/skill/controller.js.map +1 -1
- package/dist/domain/skill/push.d.ts +9 -10
- package/dist/domain/skill/push.d.ts.map +1 -1
- package/dist/domain/skill/push.js +53 -122
- package/dist/domain/skill/push.js.map +1 -1
- package/dist/domain/skill/search-extractor.d.ts.map +1 -1
- package/dist/domain/skill/search-extractor.js.map +1 -1
- package/dist/domain/skill/storage/artifact-storage.d.ts +26 -29
- package/dist/domain/skill/storage/artifact-storage.d.ts.map +1 -1
- package/dist/domain/skill/storage/artifact-storage.js +6 -103
- package/dist/domain/skill/storage/artifact-storage.js.map +1 -1
- package/dist/domain/skill/storage/zip-gate.d.ts +1 -2
- package/dist/domain/skill/storage/zip-gate.d.ts.map +1 -1
- package/dist/domain/skill/storage/zip-gate.js +56 -126
- package/dist/domain/skill/storage/zip-gate.js.map +1 -1
- package/dist/domain/skill/version-resolution.d.ts +5 -5
- package/dist/domain/skill/version-resolution.d.ts.map +1 -1
- package/dist/domain/skill/version-resolution.js +34 -216
- package/dist/domain/skill/version-resolution.js.map +1 -1
- package/dist/domain/workflow/controller.d.ts.map +1 -1
- package/dist/domain/workflow/controller.js +30 -3
- package/dist/domain/workflow/controller.js.map +1 -1
- package/dist/domain/workflow/registry/data/task-kind-registry.json +1 -0
- package/dist/extensions/authorizer.d.ts +10 -5
- package/dist/extensions/authorizer.d.ts.map +1 -1
- package/dist/extensions/drivers.d.ts +4 -1
- package/dist/extensions/drivers.d.ts.map +1 -1
- package/dist/extensions/list-read-scope.d.ts +75 -11
- package/dist/extensions/list-read-scope.d.ts.map +1 -1
- package/dist/extensions/list-read-scope.js +40 -7
- package/dist/extensions/list-read-scope.js.map +1 -1
- package/dist/extensions/organization-directory.d.ts +13 -9
- package/dist/extensions/organization-directory.d.ts.map +1 -1
- package/dist/extensions/organization-directory.js.map +1 -1
- package/dist/extensions/resource-authorization.d.ts +33 -0
- package/dist/extensions/resource-authorization.d.ts.map +1 -1
- package/dist/extensions/schedule-fire-caller.d.ts +45 -18
- package/dist/extensions/schedule-fire-caller.d.ts.map +1 -1
- package/dist/extensions/schedule-fire-caller.js +12 -1
- package/dist/extensions/schedule-fire-caller.js.map +1 -1
- package/dist/index.d.ts +10 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -1
- package/dist/pipeline/apiresource-labels.d.ts +23 -3
- package/dist/pipeline/apiresource-labels.d.ts.map +1 -1
- package/dist/pipeline/apiresource-labels.js +20 -0
- package/dist/pipeline/apiresource-labels.js.map +1 -1
- package/dist/pipeline/apiresource-meta.d.ts +21 -0
- package/dist/pipeline/apiresource-meta.d.ts.map +1 -1
- package/dist/pipeline/apiresource-meta.js +28 -0
- package/dist/pipeline/apiresource-meta.js.map +1 -1
- package/dist/pipeline/errors.d.ts.map +1 -1
- package/dist/pipeline/errors.js.map +1 -1
- package/dist/pipeline/steps/authorization-facts.d.ts +12 -0
- package/dist/pipeline/steps/authorization-facts.d.ts.map +1 -0
- package/dist/pipeline/steps/authorization-facts.js +100 -0
- package/dist/pipeline/steps/authorization-facts.js.map +1 -0
- package/dist/pipeline/steps/authorization-tuples.d.ts.map +1 -1
- package/dist/pipeline/steps/authorization-tuples.js +7 -26
- package/dist/pipeline/steps/authorization-tuples.js.map +1 -1
- package/dist/pipeline/steps/delete.d.ts.map +1 -1
- package/dist/pipeline/steps/delete.js +1 -1
- package/dist/pipeline/steps/delete.js.map +1 -1
- package/dist/pipeline/steps/duplicate.d.ts.map +1 -1
- package/dist/pipeline/steps/duplicate.js.map +1 -1
- package/dist/pipeline/steps/guard-plugin-managed.d.ts +12 -0
- package/dist/pipeline/steps/guard-plugin-managed.d.ts.map +1 -0
- package/dist/pipeline/steps/guard-plugin-managed.js +96 -0
- package/dist/pipeline/steps/guard-plugin-managed.js.map +1 -0
- package/dist/pipeline/steps/guard-reserved-labels.d.ts +16 -2
- package/dist/pipeline/steps/guard-reserved-labels.d.ts.map +1 -1
- package/dist/pipeline/steps/guard-reserved-labels.js +11 -7
- package/dist/pipeline/steps/guard-reserved-labels.js.map +1 -1
- package/dist/pipeline/steps/helpers.d.ts.map +1 -1
- package/dist/pipeline/steps/helpers.js.map +1 -1
- package/dist/pipeline/steps/index-search.d.ts.map +1 -1
- package/dist/pipeline/steps/index-search.js.map +1 -1
- package/dist/pipeline/steps/load-existing.d.ts.map +1 -1
- package/dist/pipeline/steps/load-existing.js +1 -1
- package/dist/pipeline/steps/load-existing.js.map +1 -1
- package/dist/pipeline/steps/references.d.ts +16 -0
- package/dist/pipeline/steps/references.d.ts.map +1 -1
- package/dist/pipeline/steps/references.js +18 -0
- package/dist/pipeline/steps/references.js.map +1 -1
- package/dist/pipeline/steps/resolve-artifact-source.d.ts +35 -0
- package/dist/pipeline/steps/resolve-artifact-source.d.ts.map +1 -0
- package/dist/pipeline/steps/resolve-artifact-source.js +27 -0
- package/dist/pipeline/steps/resolve-artifact-source.js.map +1 -0
- package/dist/pipeline/steps/server-stamped-reserved-labels.d.ts.map +1 -1
- package/dist/pipeline/steps/server-stamped-reserved-labels.js.map +1 -1
- package/dist/pipeline/steps/shapes.d.ts +18 -0
- package/dist/pipeline/steps/shapes.d.ts.map +1 -1
- package/dist/pipeline/steps/shapes.js +29 -0
- package/dist/pipeline/steps/shapes.js.map +1 -1
- package/dist/pipeline/steps/slug.d.ts.map +1 -1
- package/dist/pipeline/steps/slug.js.map +1 -1
- package/dist/pipeline/steps/validate-visibility.d.ts +9 -0
- package/dist/pipeline/steps/validate-visibility.d.ts.map +1 -1
- package/dist/pipeline/steps/validate-visibility.js +6 -1
- package/dist/pipeline/steps/validate-visibility.js.map +1 -1
- package/dist/pipeline/steps/validation.d.ts.map +1 -1
- package/dist/pipeline/steps/validation.js.map +1 -1
- package/dist/pipeline/steps/version-archive.d.ts +63 -0
- package/dist/pipeline/steps/version-archive.d.ts.map +1 -0
- package/dist/pipeline/steps/version-archive.js +129 -0
- package/dist/pipeline/steps/version-archive.js.map +1 -0
- package/dist/pipeline/steps/version-history.d.ts +49 -0
- package/dist/pipeline/steps/version-history.d.ts.map +1 -0
- package/dist/pipeline/steps/version-history.js +229 -0
- package/dist/pipeline/steps/version-history.js.map +1 -0
- package/dist/pipeline/steps/visibility-gates.d.ts +8 -0
- package/dist/pipeline/steps/visibility-gates.d.ts.map +1 -1
- package/dist/pipeline/steps/visibility-gates.js +7 -2
- package/dist/pipeline/steps/visibility-gates.js.map +1 -1
- package/dist/query/search/registry.d.ts.map +1 -1
- package/dist/query/search/registry.js +2 -0
- package/dist/query/search/registry.js.map +1 -1
- package/dist/temporal/schedule/run-starter.d.ts +1 -1
- package/dist/temporal/schedule/run-starter.d.ts.map +1 -1
- package/dist/temporal/schedule/run-starter.js +14 -1
- package/dist/temporal/schedule/run-starter.js.map +1 -1
- package/package.json +5 -4
- package/src/archive/__tests__/archive.test.ts +233 -0
- package/src/{domain/skill → archive}/__tests__/prefilter.test.ts +1 -1
- package/src/archive/content-store.ts +132 -0
- package/src/archive/inflate.ts +107 -0
- package/src/archive/limits.ts +42 -0
- package/src/archive/open.ts +131 -0
- package/src/{domain/skill/storage → archive}/prefilter.ts +5 -0
- package/src/archive/write.ts +54 -0
- package/src/authorization/README.md +124 -0
- package/src/authorization/__tests__/authorizer.test.ts +719 -0
- package/src/authorization/__tests__/derived-tuples.test.ts +802 -0
- package/src/authorization/__tests__/drivers.ts +70 -0
- package/src/authorization/__tests__/evaluator.test.ts +359 -0
- package/src/authorization/__tests__/facts.test.ts +155 -0
- package/src/authorization/__tests__/fixtures/fga/agent-channel-owner.fga.yaml +112 -0
- package/src/authorization/__tests__/fixtures/fga/agent-share-owner.fga.yaml +109 -0
- package/src/authorization/__tests__/fixtures/fga/artifact-org-and-owner.fga.yaml +128 -0
- package/src/authorization/__tests__/fixtures/fga/blueprint-private-visibility.fga.yaml +410 -0
- package/src/authorization/__tests__/fixtures/fga/channel-app-owner.fga.yaml +125 -0
- package/src/authorization/__tests__/fixtures/fga/channel-participation.fga.yaml +201 -0
- package/src/authorization/__tests__/fixtures/fga/channel-session-visibility.fga.yaml +187 -0
- package/src/authorization/__tests__/fixtures/fga/cross-org-share-creation.fga.yaml +98 -0
- package/src/authorization/__tests__/fixtures/fga/default-instance-inheritance.fga.yaml +271 -0
- package/src/authorization/__tests__/fixtures/fga/memory-subject-only.fga.yaml +72 -0
- package/src/authorization/__tests__/fixtures/fga/org-admin-owner-inheritance.fga.yaml +328 -0
- package/src/authorization/__tests__/fixtures/fga/org-shared-environment.fga.yaml +144 -0
- package/src/authorization/__tests__/fixtures/fga/platform-visibility.fga.yaml +223 -0
- package/src/authorization/__tests__/fixtures/fga/provider-standing-viewer.fga.yaml +40 -0
- package/src/authorization/__tests__/fixtures/fga/public-visibility-setter.fga.yaml +52 -0
- package/src/authorization/__tests__/fixtures/fga/reserved-label-writer.fga.yaml +41 -0
- package/src/authorization/__tests__/fixtures/fga/schedule-owner.fga.yaml +113 -0
- package/src/authorization/__tests__/fixtures/fga/schedule-session-visibility.fga.yaml +214 -0
- package/src/authorization/__tests__/fixtures/fga/session-personal-resource.fga.yaml +117 -0
- package/src/authorization/__tests__/fixtures/fga/workflow-execution-sharing.fga.yaml +192 -0
- package/src/authorization/__tests__/list-read-scope.measure.test.ts +317 -0
- package/src/authorization/__tests__/list-read-scope.test.ts +796 -0
- package/src/authorization/__tests__/organization-directory.test.ts +236 -0
- package/src/authorization/__tests__/person.test.ts +114 -0
- package/src/authorization/__tests__/posture.test.ts +25 -0
- package/src/authorization/__tests__/schedule-fire-caller.test.ts +134 -0
- package/src/authorization/__tests__/store-tests.test.ts +306 -0
- package/src/authorization/__tests__/support.ts +101 -0
- package/src/authorization/__tests__/tuples.test.ts +62 -0
- package/src/authorization/__tests__/wire-permissions.test.ts +154 -0
- package/src/authorization/authorizer.ts +208 -0
- package/src/authorization/derived-tuples.ts +384 -0
- package/src/authorization/evaluator.ts +283 -0
- package/src/authorization/facts.ts +47 -0
- package/src/authorization/list-read-scope.ts +216 -0
- package/src/authorization/model/__tests__/registry.test.ts +317 -0
- package/src/authorization/model/agent.ts +64 -0
- package/src/authorization/model/agent_channel.ts +49 -0
- package/src/authorization/model/agent_execution.ts +33 -0
- package/src/authorization/model/agent_instance.ts +66 -0
- package/src/authorization/model/agent_share.ts +40 -0
- package/src/authorization/model/api_key.ts +28 -0
- package/src/authorization/model/artifact.ts +38 -0
- package/src/authorization/model/channel_app.ts +39 -0
- package/src/authorization/model/default-of.ts +99 -0
- package/src/authorization/model/environment.ts +48 -0
- package/src/authorization/model/execution_context.ts +20 -0
- package/src/authorization/model/iam_policy.ts +42 -0
- package/src/authorization/model/identity_account.ts +26 -0
- package/src/authorization/model/index.ts +108 -0
- package/src/authorization/model/mcp_server.ts +59 -0
- package/src/authorization/model/memory.ts +27 -0
- package/src/authorization/model/oauth_app.ts +42 -0
- package/src/authorization/model/organization.ts +55 -0
- package/src/authorization/model/plugin.ts +66 -0
- package/src/authorization/model/project.ts +47 -0
- package/src/authorization/model/rewrite.ts +213 -0
- package/src/authorization/model/schedule.ts +40 -0
- package/src/authorization/model/session.ts +50 -0
- package/src/authorization/model/skill.ts +60 -0
- package/src/authorization/model/workflow.ts +60 -0
- package/src/authorization/model/workflow_execution.ts +44 -0
- package/src/authorization/model/workflow_instance.ts +122 -0
- package/src/authorization/organization-directory.ts +114 -0
- package/src/authorization/person.ts +68 -0
- package/src/authorization/posture.ts +49 -0
- package/src/authorization/schedule-fire-caller.ts +91 -0
- package/src/authorization/store-test-kit.ts +454 -0
- package/src/authorization/tuples.ts +190 -0
- package/src/boot/compose.ts +175 -38
- package/src/boot/inprocess.ts +108 -30
- package/src/domain/agent/controller.ts +11 -0
- package/src/domain/iampolicy/__tests__/membership.test.ts +357 -3
- package/src/domain/iampolicy/constants.ts +12 -0
- package/src/domain/iampolicy/membership.ts +221 -66
- package/src/domain/identityaccount/actor.ts +44 -0
- package/src/domain/mcpserver/controller.ts +11 -0
- package/src/domain/plugin/__tests__/materialize.test.ts +303 -0
- package/src/domain/plugin/__tests__/overlay-parse.test.ts +85 -0
- package/src/domain/plugin/__tests__/plugin.test.ts +681 -0
- package/src/domain/plugin/__tests__/sanitize.test.ts +174 -0
- package/src/domain/plugin/archive.ts +89 -0
- package/src/domain/plugin/constants.ts +53 -0
- package/src/domain/plugin/controller.ts +913 -0
- package/src/domain/plugin/materialize/agent.ts +186 -0
- package/src/domain/plugin/materialize/default-agent-instructions.ts +59 -0
- package/src/domain/plugin/materialize/identity.ts +67 -0
- package/src/domain/plugin/materialize/mcp-servers.ts +175 -0
- package/src/domain/plugin/materialize/plan.ts +124 -0
- package/src/domain/plugin/materialize/ports.ts +53 -0
- package/src/domain/plugin/materialize/skills.ts +68 -0
- package/src/domain/plugin/materialize/workflows.ts +51 -0
- package/src/domain/plugin/members.ts +180 -0
- package/src/domain/plugin/overlay/documents.ts +78 -0
- package/src/domain/plugin/overlay/parse.ts +115 -0
- package/src/domain/plugin/overlay/sanitize.ts +149 -0
- package/src/domain/plugin/push.ts +1062 -0
- package/src/domain/plugin/search-extractor.ts +60 -0
- package/src/domain/skill/constants.ts +11 -14
- package/src/domain/skill/controller.ts +44 -36
- package/src/domain/skill/push.ts +61 -156
- package/src/domain/skill/search-extractor.ts +3 -1
- package/src/domain/skill/storage/artifact-storage.ts +23 -124
- package/src/domain/skill/storage/zip-gate.ts +58 -154
- package/src/domain/skill/version-resolution.ts +67 -269
- package/src/domain/workflow/controller.ts +38 -4
- package/src/domain/workflow/registry/data/task-kind-registry.json +1 -0
- package/src/extensions/__tests__/built-in-authorization-composed.test.ts +835 -0
- package/src/extensions/__tests__/composed-support.ts +32 -1
- package/src/extensions/__tests__/extension-composition.test.ts +35 -0
- package/src/extensions/__tests__/list-read-scope.test.ts +245 -3
- package/src/extensions/__tests__/role-reconciliation-composed.test.ts +209 -0
- package/src/extensions/__tests__/tier-truthfulness.test.ts +6 -14
- package/src/extensions/authorizer.ts +10 -5
- package/src/extensions/drivers.ts +4 -1
- package/src/extensions/list-read-scope.ts +116 -16
- package/src/extensions/organization-directory.ts +13 -9
- package/src/extensions/resource-authorization.ts +34 -0
- package/src/extensions/schedule-fire-caller.ts +49 -18
- package/src/index.ts +51 -1
- package/src/pipeline/__tests__/inherited-authorization-parent.test.ts +51 -0
- package/src/pipeline/__tests__/router-transport.test.ts +1 -3
- package/src/pipeline/apiresource-labels.ts +31 -3
- package/src/pipeline/apiresource-meta.ts +37 -0
- package/src/pipeline/errors.ts +5 -5
- package/src/pipeline/steps/__tests__/authorize-annotation-completeness.test.ts +1 -20
- package/src/pipeline/steps/__tests__/guard-memory-capture.test.ts +3 -9
- package/src/pipeline/steps/__tests__/guard-plugin-managed.test.ts +151 -0
- package/src/pipeline/steps/__tests__/guard-reserved-labels.test.ts +83 -8
- package/src/pipeline/steps/authorization-facts.ts +131 -0
- package/src/pipeline/steps/authorization-tuples.ts +7 -28
- package/src/pipeline/steps/delete.ts +11 -3
- package/src/pipeline/steps/duplicate.ts +8 -2
- package/src/pipeline/steps/guard-plugin-managed.ts +133 -0
- package/src/pipeline/steps/guard-reserved-labels.ts +29 -8
- package/src/pipeline/steps/helpers.ts +4 -1
- package/src/pipeline/steps/index-search.ts +28 -15
- package/src/pipeline/steps/load-existing.ts +12 -3
- package/src/pipeline/steps/references.ts +36 -2
- package/src/pipeline/steps/resolve-artifact-source.ts +66 -0
- package/src/pipeline/steps/server-stamped-reserved-labels.ts +2 -1
- package/src/pipeline/steps/shapes.ts +31 -0
- package/src/pipeline/steps/slug.ts +7 -2
- package/src/pipeline/steps/validate-visibility.ts +9 -2
- package/src/pipeline/steps/validation.ts +3 -1
- package/src/pipeline/steps/version-archive.ts +225 -0
- package/src/pipeline/steps/version-history.ts +362 -0
- package/src/pipeline/steps/visibility-gates.ts +12 -9
- package/src/query/README.md +1 -1
- package/src/query/search/__tests__/criteria.test.ts +6 -7
- package/src/query/search/__tests__/query-store.test.ts +9 -2
- package/src/query/search/__tests__/registry.test.ts +6 -4
- package/src/query/search/registry.ts +6 -1
- package/src/temporal/schedule/__tests__/run-starter.test.ts +86 -24
- package/src/temporal/schedule/run-starter.ts +31 -8
- package/dist/domain/skill/storage/prefilter.d.ts.map +0 -1
- package/dist/domain/skill/storage/prefilter.js.map +0 -1
- /package/dist/{domain/skill/storage → archive}/prefilter.js +0 -0
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The built-in Authorizer — open source's driver for the one
|
|
3
|
+
* authorization decision seam (extensions/authorizer.ts), composed under
|
|
4
|
+
* the built-in posture (posture.ts): the cloud's model evaluated over the
|
|
5
|
+
* tuples this row would have had, derived on the fly (evaluator.ts over
|
|
6
|
+
* derived-tuples.ts). Every arm below mirrors the cloud's driver
|
|
7
|
+
* (stigmer-cloud src/authorizer/fga-authorizer.ts) by name and copy, so
|
|
8
|
+
* the two editions answer one question the same way and the drift test
|
|
9
|
+
* can pin the arms and not only the model.
|
|
10
|
+
*
|
|
11
|
+
* The arms, in order:
|
|
12
|
+
* 1. The cloud's four pre-checks with the Java service's copy, each a
|
|
13
|
+
* `deny` with the reason: an unspecified permission, an empty
|
|
14
|
+
* identity, an empty resource id, the unknown kind. No wire caller
|
|
15
|
+
* reaches the unknown kind since the kind refusals landed; the
|
|
16
|
+
* arm is the backstop, not a path.
|
|
17
|
+
* 2. A kind this edition does not serve is `deny` (`kindServedByEdition`,
|
|
18
|
+
* the predicate 2b's `checkMyPermission` arm 1 uses, so the console
|
|
19
|
+
* and the server agree by construction). `platform` is the one that
|
|
20
|
+
* arrives, through `can_set_public_visibility` — under the built-in
|
|
21
|
+
* posture nobody sets public visibility, the model's own reason for
|
|
22
|
+
* making it a platform operator's act.
|
|
23
|
+
* 3. The caller as a person (person.ts) and one derived tuple source for
|
|
24
|
+
* them; the target loaded ONCE through the source's memoised loader,
|
|
25
|
+
* so the read that decides not-found is the read the derivation
|
|
26
|
+
* uses.
|
|
27
|
+
* 4. A missing target is `not-found` — the Authorize step answers the
|
|
28
|
+
* load-first chain's NOT_FOUND (stigmer#224) — EXCEPT for the kinds
|
|
29
|
+
* the cloud never probes (NOT_FOUND_EXEMPT_KINDS): there a missing
|
|
30
|
+
* row is evaluated like any other and denies, so an authenticated
|
|
31
|
+
* member cannot learn which account ids exist. Present or exempt, the
|
|
32
|
+
* row is then evaluated: the cloud asks OpenFGA whether or not the row
|
|
33
|
+
* exists, and so does this driver.
|
|
34
|
+
* 5. `checkRelation` with the point-check context (`allow: true`: a
|
|
35
|
+
* public resource reads for any authenticated caller, the cloud's
|
|
36
|
+
* posture). True is `allow`; false is `deny` with an EMPTY reason, so
|
|
37
|
+
* the method annotation's byte-pinned `error_msg` wins on the wire,
|
|
38
|
+
* exactly the cloud's genuine-denial path.
|
|
39
|
+
*
|
|
40
|
+
* Faults. Everything past the pre-checks runs under one guard: a store
|
|
41
|
+
* fault, a person that names nobody (`personFor`), an evaluation fault
|
|
42
|
+
* (a cycle, the depth bound, an undeclared target — a registry gap the
|
|
43
|
+
* edition pin makes unreachable) all answer `unavailable` with the cause,
|
|
44
|
+
* which the Authorize step maps to INTERNAL. A denial is never a softened
|
|
45
|
+
* outage and an outage is never a denial; the driver itself never throws.
|
|
46
|
+
*
|
|
47
|
+
* Logging. One debug line per deny and per not-found, naming the person's
|
|
48
|
+
* account id, the permission and the object — what an operator needs to
|
|
49
|
+
* answer "why can Alice not see this" — and never the token. Allows are
|
|
50
|
+
* silent; they are the common case.
|
|
51
|
+
*
|
|
52
|
+
* Cost, per check (measured at slice 4): the target row (1), the caller's
|
|
53
|
+
* account (1 primary-key read; 2 for a caller a composition verifier left
|
|
54
|
+
* idp-shaped), the person's IamPolicy rows (1 scan of the port, once per
|
|
55
|
+
* source), and one row per parent hop the model walks.
|
|
56
|
+
*/
|
|
57
|
+
import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
|
|
58
|
+
import { IamPermission } from "@stigmer/protos/ai/stigmer/iam/v1/enum_pb";
|
|
59
|
+
import type { ServerEdition } from "@stigmer/protos/ai/stigmer/platform/v1/server_info_pb";
|
|
60
|
+
|
|
61
|
+
import type { Logger } from "../boot/logger.js";
|
|
62
|
+
import type { IamPolicyStore } from "../domain/iampolicy/store.js";
|
|
63
|
+
import type {
|
|
64
|
+
Authorizer,
|
|
65
|
+
AuthzCheck,
|
|
66
|
+
AuthzDecision,
|
|
67
|
+
} from "../extensions/authorizer.js";
|
|
68
|
+
import type { CallerIdentity } from "../extensions/identity.js";
|
|
69
|
+
import {
|
|
70
|
+
kindEnumName,
|
|
71
|
+
kindServedByEdition,
|
|
72
|
+
} from "../pipeline/apiresource-meta.js";
|
|
73
|
+
import type { Store } from "../store/interface.js";
|
|
74
|
+
import { newDerivedTupleSource } from "./derived-tuples.js";
|
|
75
|
+
import { checkRelation } from "./evaluator.js";
|
|
76
|
+
import type { Model } from "./model/index.js";
|
|
77
|
+
import { builtInModel } from "./model/index.js";
|
|
78
|
+
import type { AccountsByCaller } from "./person.js";
|
|
79
|
+
import { resolvePerson } from "./person.js";
|
|
80
|
+
import type { ObjectRef } from "./tuples.js";
|
|
81
|
+
import { formatObjectRef } from "./tuples.js";
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Kinds whose missing row is a denial, never `not-found` (arm 4): the
|
|
85
|
+
* cloud's `PROBE_EXEMPT_KINDS` restricted to the kinds this edition
|
|
86
|
+
* serves — `platform`, `identity_provider`, `platform_client` and
|
|
87
|
+
* `invitation` are refused by arm 2 before any row is asked about. The
|
|
88
|
+
* cloud's drift test pins the two sets equal over the open-source tier.
|
|
89
|
+
*
|
|
90
|
+
* `iam_policy` is reachable as a target through the IamPolicy RPCs' own
|
|
91
|
+
* `resource.kind` (a caller may name it); the grant scope refuses such a
|
|
92
|
+
* target after the Authorize step in both editions, and the arm here
|
|
93
|
+
* keeps the wire the same on the way there.
|
|
94
|
+
*/
|
|
95
|
+
export const NOT_FOUND_EXEMPT_KINDS: ReadonlySet<ApiResourceKind> = new Set([
|
|
96
|
+
ApiResourceKind.identity_account,
|
|
97
|
+
ApiResourceKind.iam_policy,
|
|
98
|
+
]);
|
|
99
|
+
|
|
100
|
+
/** The Java RequestAuthorizationService's pre-check copy, byte for byte (the cloud renders the same). */
|
|
101
|
+
export const UNKNOWN_PERMISSION_DENY_REASON =
|
|
102
|
+
"authorization cannot be performed with unknown permission";
|
|
103
|
+
export const EMPTY_IDENTITY_DENY_REASON =
|
|
104
|
+
"authorization cannot be performed on empty identity string";
|
|
105
|
+
export const EMPTY_RESOURCE_ID_DENY_REASON =
|
|
106
|
+
"authorization cannot be performed on empty api-resource-id";
|
|
107
|
+
export const UNKNOWN_KIND_DENY_REASON =
|
|
108
|
+
"authorization cannot be performed on unknown api-resource-kind";
|
|
109
|
+
/** This edition's own arm; the cloud has no unserved kind to deny. */
|
|
110
|
+
export const UNSERVED_KIND_DENY_REASON =
|
|
111
|
+
"authorization cannot be performed on a kind this edition does not serve";
|
|
112
|
+
|
|
113
|
+
export interface BuiltInAuthorizerDeps {
|
|
114
|
+
readonly store: Store;
|
|
115
|
+
/** The port the grant path writes through — the person's rows are read from the same instance. */
|
|
116
|
+
readonly policies: IamPolicyStore;
|
|
117
|
+
/** The account port: the caller's account, and identity_account targets. */
|
|
118
|
+
readonly accounts: AccountsByCaller;
|
|
119
|
+
/** The served edition (`extensions.edition`); the built-in posture pins it to `oss` at boot. */
|
|
120
|
+
readonly edition: ServerEdition;
|
|
121
|
+
readonly logger: Logger;
|
|
122
|
+
/** The declarations to evaluate; the built-in model unless a test says otherwise. */
|
|
123
|
+
readonly model?: Model;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
export function newBuiltInAuthorizer(deps: BuiltInAuthorizerDeps): Authorizer {
|
|
127
|
+
const model = deps.model ?? builtInModel;
|
|
128
|
+
return {
|
|
129
|
+
async authorize(
|
|
130
|
+
caller: CallerIdentity,
|
|
131
|
+
check: AuthzCheck,
|
|
132
|
+
): Promise<AuthzDecision> {
|
|
133
|
+
if (check.permission === IamPermission.unspecified) {
|
|
134
|
+
return deny(UNKNOWN_PERMISSION_DENY_REASON);
|
|
135
|
+
}
|
|
136
|
+
if (caller.identityId === "") {
|
|
137
|
+
return deny(EMPTY_IDENTITY_DENY_REASON);
|
|
138
|
+
}
|
|
139
|
+
if (check.resourceId === "") {
|
|
140
|
+
return deny(EMPTY_RESOURCE_ID_DENY_REASON);
|
|
141
|
+
}
|
|
142
|
+
if (check.resourceKind === ApiResourceKind.api_resource_kind_unknown) {
|
|
143
|
+
return deny(UNKNOWN_KIND_DENY_REASON);
|
|
144
|
+
}
|
|
145
|
+
if (!kindServedByEdition(check.resourceKind, deps.edition)) {
|
|
146
|
+
return deny(UNSERVED_KIND_DENY_REASON);
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
const object: ObjectRef = {
|
|
150
|
+
type: kindEnumName(check.resourceKind),
|
|
151
|
+
id: check.resourceId,
|
|
152
|
+
};
|
|
153
|
+
const relation = IamPermission[check.permission];
|
|
154
|
+
try {
|
|
155
|
+
const person = await resolvePerson(deps.accounts, caller);
|
|
156
|
+
const source = newDerivedTupleSource(
|
|
157
|
+
{
|
|
158
|
+
store: deps.store,
|
|
159
|
+
policies: deps.policies,
|
|
160
|
+
accounts: deps.accounts,
|
|
161
|
+
model,
|
|
162
|
+
},
|
|
163
|
+
person,
|
|
164
|
+
);
|
|
165
|
+
const row = await source.loader.load(object);
|
|
166
|
+
if (
|
|
167
|
+
row === undefined &&
|
|
168
|
+
!NOT_FOUND_EXEMPT_KINDS.has(check.resourceKind)
|
|
169
|
+
) {
|
|
170
|
+
deps.logger.debug("authorization target not found", {
|
|
171
|
+
account: person.accountId,
|
|
172
|
+
permission: relation,
|
|
173
|
+
object: formatObjectRef(object),
|
|
174
|
+
});
|
|
175
|
+
return { kind: "not-found" };
|
|
176
|
+
}
|
|
177
|
+
const allowed = await checkRelation(
|
|
178
|
+
{ model, source },
|
|
179
|
+
object,
|
|
180
|
+
relation,
|
|
181
|
+
person,
|
|
182
|
+
{ allow: true },
|
|
183
|
+
);
|
|
184
|
+
if (allowed) {
|
|
185
|
+
return { kind: "allow" };
|
|
186
|
+
}
|
|
187
|
+
deps.logger.debug("authorization denied", {
|
|
188
|
+
account: person.accountId,
|
|
189
|
+
permission: relation,
|
|
190
|
+
object: formatObjectRef(object),
|
|
191
|
+
});
|
|
192
|
+
// Empty on purpose: the Authorize step then surfaces the method
|
|
193
|
+
// annotation's byte-pinned error_msg (or its fallback copy), the
|
|
194
|
+
// cloud's genuine-denial path.
|
|
195
|
+
return deny("");
|
|
196
|
+
} catch (error) {
|
|
197
|
+
return {
|
|
198
|
+
kind: "unavailable",
|
|
199
|
+
cause: error instanceof Error ? error : new Error(String(error)),
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
},
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
function deny(reason: string): AuthzDecision {
|
|
207
|
+
return { kind: "deny", reason };
|
|
208
|
+
}
|
|
@@ -0,0 +1,384 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The derived tuple view — the ONE place the built-in authorizer knows
|
|
3
|
+
* what open source's tuples would have been. The cloud stores tuples its
|
|
4
|
+
* driver writes from every row's lifecycle (stigmer-cloud
|
|
5
|
+
* iam/tuple-lifecycle.ts); open source stores none and computes the same
|
|
6
|
+
* tuples from the row when a check asks ("derived state over stored
|
|
7
|
+
* state"). `deriveTuples` is that computation, pure over `RowFacts`, in
|
|
8
|
+
* the driver's own shapes:
|
|
9
|
+
*
|
|
10
|
+
* - parent links: <row>#<relation>@<parentKind>:<parentId> (the scope link, then the additional parents)
|
|
11
|
+
* - owner DIRECT: <row>#owner@identity_account:<creator stamp>
|
|
12
|
+
* - owner SELF: <row>#owner@identity_account:<row id>
|
|
13
|
+
* - creator: <row>#creator@identity_account:<creator stamp> (kinds flagged requires_creator_tuple)
|
|
14
|
+
* - org-viewer: <row>#viewer@organization:<org>#viewer (visibility_org; cloud#257's shape)
|
|
15
|
+
* - public-viewer: <row>#viewer@identity_account:* with allow_public
|
|
16
|
+
* - platform-viewer: none — it fans out over identity providers, a kind this edition does not serve
|
|
17
|
+
*
|
|
18
|
+
* Two facts are this edition's own and are stated here, nowhere else:
|
|
19
|
+
* - The ORGANIZATION's owner is a ROW, not a derivation. 2b's role
|
|
20
|
+
* lifecycle (domain/iampolicy/role-lifecycle.ts) writes the creator's
|
|
21
|
+
* `owner` row for exactly that kind, and the grant path writes every
|
|
22
|
+
* other role; deriving an owner tuple from the creator stamp as well
|
|
23
|
+
* would keep a revoked founder owner forever. ROW_RECORDED_OWNER_KINDS
|
|
24
|
+
* is the read side of the lifecycle's "only organization" guard.
|
|
25
|
+
* - A stamp that names no person becomes no tuple: `""` and the
|
|
26
|
+
* unconfigured laptop's `"system"` (`isPersonStamp`, the membership
|
|
27
|
+
* rules' one predicate). The person comparison itself is the
|
|
28
|
+
* evaluator's, over the aliases `Person` carries.
|
|
29
|
+
*
|
|
30
|
+
* The SOURCE joins two records per (object, relation): the person's own
|
|
31
|
+
* IamPolicy rows on the object (read ONCE per source through
|
|
32
|
+
* `findByPrincipal` — every row open source writes names an account id,
|
|
33
|
+
* so the person's account id is the whole key, and on the OSS adapter one
|
|
34
|
+
* read is one scan whatever the number of organizations walked) and the
|
|
35
|
+
* tuples derived from the object's row (loaded once per object through
|
|
36
|
+
* the loader, which a declaration's `derived` rule also reads related
|
|
37
|
+
* rows through). An absent row is no tuples — the target's own not-found
|
|
38
|
+
* is the driver's arm, and a parent that no longer exists simply grants
|
|
39
|
+
* nothing, as in the cloud; any other store fault propagates so the
|
|
40
|
+
* driver folds it to `unavailable`. One source per check (or per list
|
|
41
|
+
* call for the list scope): its memo is the check's.
|
|
42
|
+
*
|
|
43
|
+
* A source may be SEEDED with the facts of objects the caller already
|
|
44
|
+
* holds (the list scope's candidates, decoded by the lane and carried on
|
|
45
|
+
* every `ListEntryMeta`): a seeded object's tuples derive from those facts
|
|
46
|
+
* and its row is never read — the facts are exactly what the derivation
|
|
47
|
+
* reads (facts.ts). The seed stands in for the row only where the row
|
|
48
|
+
* would have been read for FACTS; a declaration's `derived` rule reads
|
|
49
|
+
* the row it needs through the loader as before (`default_of` reads the
|
|
50
|
+
* instance's blueprint pointer, `execution_viewer` the instance's level —
|
|
51
|
+
* spec fields the facts do not carry), so listing the two instance kinds
|
|
52
|
+
* costs one row read per candidate, stated in the scope's cost pins.
|
|
53
|
+
*
|
|
54
|
+
* Rows are read through the generic Store, with one exception: an
|
|
55
|
+
* `identity_account` object is read through the account PORT
|
|
56
|
+
* (`accounts.findById`), the binding every other reader of accounts —
|
|
57
|
+
* the verifiers, whoAmI, the create path — follows. A composition that
|
|
58
|
+
* registers its own account store and keeps the built-in authorizer
|
|
59
|
+
* therefore still lets a person read their own account (the derivation
|
|
60
|
+
* is `owner@self`); a generic read would miss and deny them their own
|
|
61
|
+
* row. IamPolicy rows are already the port's (`findByPrincipal`), so no
|
|
62
|
+
* second exception is needed for them.
|
|
63
|
+
*/
|
|
64
|
+
import type { Message } from "@bufbuild/protobuf";
|
|
65
|
+
|
|
66
|
+
import { ApiResourceKind } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/api_resource_kind_pb";
|
|
67
|
+
import { OwnerAttributionType } from "@stigmer/protos/ai/stigmer/commons/apiresource/apiresourcekind/authorization_config_pb";
|
|
68
|
+
import type { IamPolicy } from "@stigmer/protos/ai/stigmer/iam/iampolicy/v1/api_pb";
|
|
69
|
+
|
|
70
|
+
import { isPersonStamp } from "../domain/iampolicy/membership.js";
|
|
71
|
+
import type { IamPolicyStore } from "../domain/iampolicy/store.js";
|
|
72
|
+
import type { IdentityAccountStore } from "../domain/identityaccount/store.js";
|
|
73
|
+
import type { VisibilityTupleShape } from "../extensions/resource-authorization.js";
|
|
74
|
+
import {
|
|
75
|
+
getKindMeta,
|
|
76
|
+
kindByEnumName,
|
|
77
|
+
kindEnumName,
|
|
78
|
+
} from "../pipeline/apiresource-meta.js";
|
|
79
|
+
import { visibilityShapesFor } from "../pipeline/steps/authorization-tuples.js";
|
|
80
|
+
import type { Store } from "../store/interface.js";
|
|
81
|
+
import { ResourceNotFoundError } from "../store/interface.js";
|
|
82
|
+
import type { RowFacts } from "./facts.js";
|
|
83
|
+
import { rowFactsOf } from "./facts.js";
|
|
84
|
+
import type { Model } from "./model/index.js";
|
|
85
|
+
import { builtInModel } from "./model/index.js";
|
|
86
|
+
import type {
|
|
87
|
+
ObjectRef,
|
|
88
|
+
Person,
|
|
89
|
+
RowLoader,
|
|
90
|
+
Subject,
|
|
91
|
+
Tuple,
|
|
92
|
+
TupleSource,
|
|
93
|
+
} from "./tuples.js";
|
|
94
|
+
import {
|
|
95
|
+
ACCOUNT_TYPE,
|
|
96
|
+
ALLOW_PUBLIC_CONDITION,
|
|
97
|
+
formatObjectRef,
|
|
98
|
+
} from "./tuples.js";
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Kinds whose `[identity_account]` owner is recorded as an IamPolicy row
|
|
102
|
+
* by this edition (the module header): the derivation writes no owner
|
|
103
|
+
* tuple for them. Mirrors role-lifecycle.ts's create arm, which writes
|
|
104
|
+
* the row for `organization` and nothing else.
|
|
105
|
+
*/
|
|
106
|
+
export const ROW_RECORDED_OWNER_KINDS: ReadonlySet<ApiResourceKind> = new Set([
|
|
107
|
+
ApiResourceKind.organization,
|
|
108
|
+
]);
|
|
109
|
+
|
|
110
|
+
function account(id: string): Subject {
|
|
111
|
+
return { form: "object", object: { type: ACCOUNT_TYPE, id } };
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/** The tuples a row stands for, in the cloud driver's shapes and order. */
|
|
115
|
+
export function deriveTuples(facts: RowFacts): ReadonlyArray<Tuple> {
|
|
116
|
+
const object: ObjectRef = { type: kindEnumName(facts.kind), id: facts.id };
|
|
117
|
+
const config = getKindMeta(facts.kind).authorization;
|
|
118
|
+
if (config === undefined) {
|
|
119
|
+
return [];
|
|
120
|
+
}
|
|
121
|
+
const tuples: Tuple[] = [];
|
|
122
|
+
for (const link of facts.parentLinks) {
|
|
123
|
+
tuples.push({
|
|
124
|
+
object,
|
|
125
|
+
relation: link.relation,
|
|
126
|
+
subject: {
|
|
127
|
+
form: "object",
|
|
128
|
+
object: { type: kindEnumName(link.parentKind), id: link.parentId },
|
|
129
|
+
},
|
|
130
|
+
});
|
|
131
|
+
}
|
|
132
|
+
const stampIsPerson = isPersonStamp(facts.createdBy);
|
|
133
|
+
switch (config.ownerType) {
|
|
134
|
+
case OwnerAttributionType.DIRECT:
|
|
135
|
+
if (stampIsPerson && !ROW_RECORDED_OWNER_KINDS.has(facts.kind)) {
|
|
136
|
+
tuples.push({
|
|
137
|
+
object,
|
|
138
|
+
relation: "owner",
|
|
139
|
+
subject: account(facts.createdBy),
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
break;
|
|
143
|
+
case OwnerAttributionType.SELF:
|
|
144
|
+
tuples.push({ object, relation: "owner", subject: account(facts.id) });
|
|
145
|
+
break;
|
|
146
|
+
case OwnerAttributionType.INHERITED:
|
|
147
|
+
case OwnerAttributionType.NONE:
|
|
148
|
+
case OwnerAttributionType.UNSPECIFIED:
|
|
149
|
+
// Inherited: the model walks `owner from <parent>`; none: the kind has no owner.
|
|
150
|
+
break;
|
|
151
|
+
default: {
|
|
152
|
+
const exhaustive: never = config.ownerType;
|
|
153
|
+
throw new Error(`unknown owner attribution: ${String(exhaustive)}`);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
if (config.requiresCreatorTuple && stampIsPerson) {
|
|
157
|
+
tuples.push({
|
|
158
|
+
object,
|
|
159
|
+
relation: "creator",
|
|
160
|
+
subject: account(facts.createdBy),
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
for (const shape of visibilityShapesFor(facts.kind, facts.visibility)) {
|
|
164
|
+
const subject = visibilitySubject(shape, facts.org);
|
|
165
|
+
if (subject !== undefined) {
|
|
166
|
+
tuples.push({ object, relation: "viewer", subject });
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return tuples;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/** The driver's grant table for a visibility shape; undefined where this edition writes nothing. */
|
|
173
|
+
function visibilitySubject(
|
|
174
|
+
shape: VisibilityTupleShape,
|
|
175
|
+
org: string,
|
|
176
|
+
): Subject | undefined {
|
|
177
|
+
switch (shape) {
|
|
178
|
+
case "org-viewer":
|
|
179
|
+
// No organization to point at (a legacy row): no userset.
|
|
180
|
+
return org === ""
|
|
181
|
+
? undefined
|
|
182
|
+
: {
|
|
183
|
+
form: "userset",
|
|
184
|
+
object: { type: "organization", id: org },
|
|
185
|
+
relation: "viewer",
|
|
186
|
+
};
|
|
187
|
+
case "public-viewer":
|
|
188
|
+
return {
|
|
189
|
+
form: "wildcard",
|
|
190
|
+
type: ACCOUNT_TYPE,
|
|
191
|
+
condition: ALLOW_PUBLIC_CONDITION,
|
|
192
|
+
};
|
|
193
|
+
case "platform-viewer":
|
|
194
|
+
return undefined;
|
|
195
|
+
default: {
|
|
196
|
+
const exhaustive: never = shape;
|
|
197
|
+
throw new Error(`unknown visibility shape: ${String(exhaustive)}`);
|
|
198
|
+
}
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// ---------------------------------------------------------------------------
|
|
203
|
+
// The source.
|
|
204
|
+
// ---------------------------------------------------------------------------
|
|
205
|
+
|
|
206
|
+
export interface DerivedTupleSourceDeps {
|
|
207
|
+
readonly store: Store;
|
|
208
|
+
/** The port the grant path writes through — the rows are read from the same instance. */
|
|
209
|
+
readonly policies: IamPolicyStore;
|
|
210
|
+
/** The account port — an `identity_account` object is read through it, never the generic Store (the module header). */
|
|
211
|
+
readonly accounts: Pick<IdentityAccountStore, "findById">;
|
|
212
|
+
/** The declarations to derive with; the built-in model unless a test says otherwise. */
|
|
213
|
+
readonly model?: Model;
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
export interface DerivedTupleSource extends TupleSource {
|
|
217
|
+
/** The memoised row reads, exposed for a declaration's `derived` rules and for tests. */
|
|
218
|
+
readonly loader: RowLoader;
|
|
219
|
+
/**
|
|
220
|
+
* The person's own IamPolicy rows as tuples — the ONE read of them this
|
|
221
|
+
* source makes, shared with `tuplesOf`. A list-shaped consumer (the
|
|
222
|
+
* organization directory; the list scope) reads its candidate objects
|
|
223
|
+
* from here instead of scanning the port a second time.
|
|
224
|
+
*/
|
|
225
|
+
personTuples(): Promise<ReadonlyArray<Tuple>>;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
export interface DerivedTupleSourceSeed {
|
|
229
|
+
/** Objects whose facts the caller already holds; their rows are not read for derivation. */
|
|
230
|
+
readonly facts: ReadonlyArray<RowFacts>;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
export function newDerivedTupleSource(
|
|
234
|
+
deps: DerivedTupleSourceDeps,
|
|
235
|
+
person: Person,
|
|
236
|
+
seed?: DerivedTupleSourceSeed,
|
|
237
|
+
): DerivedTupleSource {
|
|
238
|
+
const model = deps.model ?? builtInModel;
|
|
239
|
+
const rows = new Map<string, Promise<Message | undefined>>();
|
|
240
|
+
const derived = new Map<string, Promise<ReadonlyArray<Tuple>>>();
|
|
241
|
+
const seeded = new Map<string, RowFacts>();
|
|
242
|
+
for (const facts of seed?.facts ?? []) {
|
|
243
|
+
seeded.set(
|
|
244
|
+
formatObjectRef({ type: kindEnumName(facts.kind), id: facts.id }),
|
|
245
|
+
facts,
|
|
246
|
+
);
|
|
247
|
+
}
|
|
248
|
+
let personRows: Promise<ReadonlyArray<Tuple>> | undefined;
|
|
249
|
+
|
|
250
|
+
const loader: RowLoader = {
|
|
251
|
+
load(object) {
|
|
252
|
+
const key = formatObjectRef(object);
|
|
253
|
+
const held = rows.get(key);
|
|
254
|
+
if (held !== undefined) {
|
|
255
|
+
return held;
|
|
256
|
+
}
|
|
257
|
+
const loading = loadRow(deps, model, object);
|
|
258
|
+
rows.set(key, loading);
|
|
259
|
+
return loading;
|
|
260
|
+
},
|
|
261
|
+
};
|
|
262
|
+
|
|
263
|
+
function derivedTuplesOf(object: ObjectRef): Promise<ReadonlyArray<Tuple>> {
|
|
264
|
+
const key = formatObjectRef(object);
|
|
265
|
+
const held = derived.get(key);
|
|
266
|
+
if (held !== undefined) {
|
|
267
|
+
return held;
|
|
268
|
+
}
|
|
269
|
+
const declaration = model.byType(object.type);
|
|
270
|
+
const known = seeded.get(key);
|
|
271
|
+
let deriving: Promise<ReadonlyArray<Tuple>>;
|
|
272
|
+
if (declaration === undefined) {
|
|
273
|
+
deriving = Promise.resolve([]);
|
|
274
|
+
} else if (known !== undefined) {
|
|
275
|
+
deriving = Promise.resolve(deriveTuples(known));
|
|
276
|
+
} else {
|
|
277
|
+
deriving = loader
|
|
278
|
+
.load(object)
|
|
279
|
+
.then((row) =>
|
|
280
|
+
row === undefined
|
|
281
|
+
? []
|
|
282
|
+
: deriveTuples(rowFactsOf(declaration.kind, row)),
|
|
283
|
+
);
|
|
284
|
+
}
|
|
285
|
+
derived.set(key, deriving);
|
|
286
|
+
return deriving;
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
function rowTuples(): Promise<ReadonlyArray<Tuple>> {
|
|
290
|
+
if (personRows === undefined) {
|
|
291
|
+
personRows = deps.policies
|
|
292
|
+
.findByPrincipal(ACCOUNT_TYPE, person.accountId)
|
|
293
|
+
.then((found) => found.map(tupleOfRow));
|
|
294
|
+
}
|
|
295
|
+
return personRows;
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
return {
|
|
299
|
+
loader,
|
|
300
|
+
personTuples: rowTuples,
|
|
301
|
+
async tuplesOf(object, relation) {
|
|
302
|
+
const onPair = (tuple: Tuple): boolean =>
|
|
303
|
+
tuple.relation === relation &&
|
|
304
|
+
tuple.object.type === object.type &&
|
|
305
|
+
tuple.object.id === object.id;
|
|
306
|
+
const fromRows = (await rowTuples()).filter(onPair);
|
|
307
|
+
const declaration = model.byType(object.type);
|
|
308
|
+
if (declaration === undefined) {
|
|
309
|
+
return fromRows;
|
|
310
|
+
}
|
|
311
|
+
const fromRow = (await derivedTuplesOf(object)).filter(onPair);
|
|
312
|
+
const rule = declaration.derived.get(relation);
|
|
313
|
+
if (rule === undefined) {
|
|
314
|
+
return [...fromRows, ...fromRow];
|
|
315
|
+
}
|
|
316
|
+
const row = await loader.load(object);
|
|
317
|
+
const fromRule = row === undefined ? [] : await rule(object, row, loader);
|
|
318
|
+
return [...fromRows, ...fromRow, ...fromRule];
|
|
319
|
+
},
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
/** The decoded row for an object, or undefined when the kind is not declared or the row does not exist. */
|
|
324
|
+
async function loadRow(
|
|
325
|
+
deps: Pick<DerivedTupleSourceDeps, "store" | "accounts">,
|
|
326
|
+
model: Model,
|
|
327
|
+
object: ObjectRef,
|
|
328
|
+
): Promise<Message | undefined> {
|
|
329
|
+
const declaration = model.byType(object.type);
|
|
330
|
+
const kind = kindByEnumName(object.type);
|
|
331
|
+
if (
|
|
332
|
+
declaration === undefined ||
|
|
333
|
+
kind === ApiResourceKind.api_resource_kind_unknown ||
|
|
334
|
+
object.id === ""
|
|
335
|
+
) {
|
|
336
|
+
return undefined;
|
|
337
|
+
}
|
|
338
|
+
if (kind === ApiResourceKind.identity_account) {
|
|
339
|
+
return deps.accounts.findById(object.id);
|
|
340
|
+
}
|
|
341
|
+
try {
|
|
342
|
+
return await deps.store.getResource(kind, object.id, declaration.schema);
|
|
343
|
+
} catch (error) {
|
|
344
|
+
if (error instanceof ResourceNotFoundError) {
|
|
345
|
+
return undefined;
|
|
346
|
+
}
|
|
347
|
+
throw error;
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/** An IamPolicy row as the tuple it records: `resource#relation@principal`. */
|
|
352
|
+
function tupleOfRow(row: IamPolicy): Tuple {
|
|
353
|
+
const spec = row.spec;
|
|
354
|
+
const principal = spec?.principal;
|
|
355
|
+
const resource = spec?.resource;
|
|
356
|
+
const object: ObjectRef = {
|
|
357
|
+
type: resource?.kind ?? "",
|
|
358
|
+
id: resource?.id ?? "",
|
|
359
|
+
};
|
|
360
|
+
const principalObject: ObjectRef = {
|
|
361
|
+
type: principal?.kind ?? "",
|
|
362
|
+
id: principal?.id ?? "",
|
|
363
|
+
};
|
|
364
|
+
let subject: Subject;
|
|
365
|
+
if (principal !== undefined && principal.relation !== "") {
|
|
366
|
+
subject = {
|
|
367
|
+
form: "userset",
|
|
368
|
+
object: principalObject,
|
|
369
|
+
relation: principal.relation,
|
|
370
|
+
};
|
|
371
|
+
} else if (principalObject.id === "*") {
|
|
372
|
+
// A wildcard row carries no condition of its own; the evaluator
|
|
373
|
+
// honours it only where a line admits an unconditioned wildcard,
|
|
374
|
+
// which no line in the model does.
|
|
375
|
+
subject = {
|
|
376
|
+
form: "wildcard",
|
|
377
|
+
type: principalObject.type,
|
|
378
|
+
condition: undefined,
|
|
379
|
+
};
|
|
380
|
+
} else {
|
|
381
|
+
subject = { form: "object", object: principalObject };
|
|
382
|
+
}
|
|
383
|
+
return { object, relation: spec?.relation ?? "", subject };
|
|
384
|
+
}
|