@sixb/core 0.1.20 → 0.1.21
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/actions/execution.d.ts.map +1 -1
- package/dist/actions/index.js +54 -47
- package/dist/actions/index.js.map +1 -1
- package/dist/actions/request.d.ts.map +1 -1
- package/dist/actions/run-authorization.d.ts +9 -0
- package/dist/actions/run-authorization.d.ts.map +1 -1
- package/dist/activity/connection.d.ts +62 -0
- package/dist/activity/connection.d.ts.map +1 -0
- package/dist/activity/device.d.ts +8 -0
- package/dist/activity/device.d.ts.map +1 -0
- package/dist/activity/execution.d.ts +48 -0
- package/dist/activity/execution.d.ts.map +1 -0
- package/dist/activity/service.d.ts +79 -0
- package/dist/activity/service.d.ts.map +1 -0
- package/dist/activity/shares.d.ts +24 -0
- package/dist/activity/shares.d.ts.map +1 -0
- package/dist/activity/timeline.d.ts +96 -0
- package/dist/activity/timeline.d.ts.map +1 -0
- package/dist/agents/index.d.ts +2 -1
- package/dist/agents/index.d.ts.map +1 -1
- package/dist/agents/index.js +63 -50
- package/dist/agents/index.js.map +1 -1
- package/dist/agents/request.d.ts.map +1 -1
- package/dist/agents/skills.d.ts.map +1 -1
- package/dist/agents/streams/index.js +3 -3
- package/dist/agents/streams/internal.js +3 -3
- package/dist/agents/types.d.ts +8 -8
- package/dist/agents/types.d.ts.map +1 -1
- package/dist/agents/validation.d.ts +1 -1
- package/dist/agents/validation.d.ts.map +1 -1
- package/dist/artifacts/address.d.ts +48 -0
- package/dist/artifacts/address.d.ts.map +1 -0
- package/dist/artifacts/csv.d.ts +22 -0
- package/dist/artifacts/csv.d.ts.map +1 -0
- package/dist/artifacts/errors.d.ts +11 -0
- package/dist/artifacts/errors.d.ts.map +1 -0
- package/dist/artifacts/execution.d.ts +43 -0
- package/dist/artifacts/execution.d.ts.map +1 -0
- package/dist/artifacts/frames/assets.d.ts +28 -0
- package/dist/artifacts/frames/assets.d.ts.map +1 -0
- package/dist/artifacts/frames/grants.d.ts +37 -0
- package/dist/artifacts/frames/grants.d.ts.map +1 -0
- package/dist/artifacts/frames/index.d.ts +10 -0
- package/dist/artifacts/frames/index.d.ts.map +1 -0
- package/dist/artifacts/frames/index.js +892 -0
- package/dist/artifacts/frames/index.js.map +14 -0
- package/dist/artifacts/frames/kit.d.ts +66 -0
- package/dist/artifacts/frames/kit.d.ts.map +1 -0
- package/dist/artifacts/frames/probe.d.ts +41 -0
- package/dist/artifacts/frames/probe.d.ts.map +1 -0
- package/dist/artifacts/frames/protocol.d.ts +98 -0
- package/dist/artifacts/frames/protocol.d.ts.map +1 -0
- package/dist/artifacts/frames/runtime.d.ts +13 -0
- package/dist/artifacts/frames/runtime.d.ts.map +1 -0
- package/dist/artifacts/html.d.ts +6 -0
- package/dist/artifacts/html.d.ts.map +1 -0
- package/dist/artifacts/ids.d.ts +5 -0
- package/dist/artifacts/ids.d.ts.map +1 -0
- package/dist/artifacts/index.d.ts +16 -0
- package/dist/artifacts/index.d.ts.map +1 -0
- package/dist/artifacts/index.js +125 -0
- package/dist/artifacts/index.js.map +10 -0
- package/dist/artifacts/kinds.d.ts +5 -0
- package/dist/artifacts/kinds.d.ts.map +1 -0
- package/dist/artifacts/limits.d.ts +28 -0
- package/dist/artifacts/limits.d.ts.map +1 -0
- package/dist/artifacts/outline.d.ts +44 -0
- package/dist/artifacts/outline.d.ts.map +1 -0
- package/dist/artifacts/publish/files.d.ts +15 -0
- package/dist/artifacts/publish/files.d.ts.map +1 -0
- package/dist/artifacts/publish/index.d.ts +5 -0
- package/dist/artifacts/publish/index.d.ts.map +1 -0
- package/dist/artifacts/publish/index.js +36 -0
- package/dist/artifacts/publish/index.js.map +9 -0
- package/dist/artifacts/publish/publish.d.ts +52 -0
- package/dist/artifacts/publish/publish.d.ts.map +1 -0
- package/dist/artifacts/publish/references.d.ts +27 -0
- package/dist/artifacts/publish/references.d.ts.map +1 -0
- package/dist/artifacts/publish/validate/document.d.ts +17 -0
- package/dist/artifacts/publish/validate/document.d.ts.map +1 -0
- package/dist/artifacts/publish/validate/file.d.ts +8 -0
- package/dist/artifacts/publish/validate/file.d.ts.map +1 -0
- package/dist/artifacts/publish/validate/sheet.d.ts +15 -0
- package/dist/artifacts/publish/validate/sheet.d.ts.map +1 -0
- package/dist/artifacts/publish/validate/slides.d.ts +21 -0
- package/dist/artifacts/publish/validate/slides.d.ts.map +1 -0
- package/dist/artifacts/references.d.ts +12 -0
- package/dist/artifacts/references.d.ts.map +1 -0
- package/dist/artifacts/resolve.d.ts +41 -0
- package/dist/artifacts/resolve.d.ts.map +1 -0
- package/dist/artifacts/theme.d.ts +19 -0
- package/dist/artifacts/theme.d.ts.map +1 -0
- package/dist/artifacts/warnings.d.ts +11 -0
- package/dist/artifacts/warnings.d.ts.map +1 -0
- package/dist/artifacts/workbook.d.ts +64 -0
- package/dist/artifacts/workbook.d.ts.map +1 -0
- package/dist/auth/index.js +10 -10
- package/dist/authorization/decision.d.ts +2 -0
- package/dist/authorization/decision.d.ts.map +1 -1
- package/dist/authorization/grant-kinds.d.ts +2 -2
- package/dist/authorization/grant-kinds.d.ts.map +1 -1
- package/dist/authorization/index.js +6 -6
- package/dist/blob-storage/browser.js +1 -1
- package/dist/blob-storage/index.js +2 -2
- package/dist/blob-storage/internal.d.ts +1 -1
- package/dist/blob-storage/internal.d.ts.map +1 -1
- package/dist/blob-storage/internal.js +11 -5
- package/dist/blob-storage/internal.js.map +1 -1
- package/dist/blob-storage/media-type.d.ts +12 -0
- package/dist/blob-storage/media-type.d.ts.map +1 -1
- package/dist/bootstrap/index.js +53 -47
- package/dist/bootstrap/index.js.map +2 -2
- package/dist/{chunk-xfs8x8m9.js → chunk-0bphap9y.js} +5 -5
- package/dist/{chunk-1zq2p6g0.js → chunk-1cc1xaf3.js} +3 -3
- package/dist/chunk-3jms7je7.js +14 -0
- package/dist/chunk-3jms7je7.js.map +10 -0
- package/dist/{chunk-s54c868q.js → chunk-3qct2mdc.js} +3 -13
- package/dist/chunk-3qct2mdc.js.map +12 -0
- package/dist/{chunk-t7x8dmn0.js → chunk-431pyp2c.js} +3 -3
- package/dist/{chunk-c85m1hyj.js → chunk-447a5c0p.js} +2 -2
- package/dist/chunk-48qjhh6v.js +185 -0
- package/dist/chunk-48qjhh6v.js.map +13 -0
- package/dist/{chunk-ren4kg2j.js → chunk-561r0yc9.js} +8 -8
- package/dist/{chunk-5e43w60z.js → chunk-5948n82c.js} +2 -2
- package/dist/{chunk-yzwja0mj.js → chunk-5hx48dnn.js} +2 -2
- package/dist/{chunk-x6m907x7.js → chunk-5vems3nx.js} +5 -6
- package/dist/{chunk-x6m907x7.js.map → chunk-5vems3nx.js.map} +3 -3
- package/dist/{chunk-0rbyz4qy.js → chunk-61y5xs4p.js} +560 -164
- package/dist/{chunk-0rbyz4qy.js.map → chunk-61y5xs4p.js.map} +12 -9
- package/dist/chunk-65abf64x.js +13 -0
- package/dist/chunk-65abf64x.js.map +10 -0
- package/dist/{chunk-z3y5kg1x.js → chunk-6eqsgvxk.js} +3 -3
- package/dist/{chunk-z3y5kg1x.js.map → chunk-6eqsgvxk.js.map} +2 -2
- package/dist/chunk-6rqgmkde.js +2028 -0
- package/dist/chunk-6rqgmkde.js.map +29 -0
- package/dist/{chunk-d0bqz29d.js → chunk-6vb4st8k.js} +8 -4
- package/dist/{chunk-d0bqz29d.js.map → chunk-6vb4st8k.js.map} +3 -3
- package/dist/chunk-7q8t23v4.js +467 -0
- package/dist/chunk-7q8t23v4.js.map +14 -0
- package/dist/{chunk-5j58wjct.js → chunk-858emn8m.js} +6 -6
- package/dist/{chunk-hvsb78a1.js → chunk-8frc8a4j.js} +26 -26
- package/dist/{chunk-hvsb78a1.js.map → chunk-8frc8a4j.js.map} +2 -2
- package/dist/{chunk-3zxk45er.js → chunk-8ncg20rd.js} +3 -68
- package/dist/{chunk-3zxk45er.js.map → chunk-8ncg20rd.js.map} +4 -5
- package/dist/{chunk-n33z5bjw.js → chunk-918wwnaa.js} +490 -24
- package/dist/{chunk-n33z5bjw.js.map → chunk-918wwnaa.js.map} +13 -11
- package/dist/{chunk-rrzt8jdy.js → chunk-9j4jw7as.js} +103 -110
- package/dist/chunk-9j4jw7as.js.map +14 -0
- package/dist/chunk-9kgkfg6v.js +502 -0
- package/dist/chunk-9kgkfg6v.js.map +14 -0
- package/dist/chunk-a3faa34j.js +74 -0
- package/dist/chunk-a3faa34j.js.map +10 -0
- package/dist/{chunk-6c6sn0bh.js → chunk-akzryx9h.js} +335 -1167
- package/dist/{chunk-6c6sn0bh.js.map → chunk-akzryx9h.js.map} +18 -24
- package/dist/chunk-arns890k.js +10 -0
- package/dist/chunk-arns890k.js.map +10 -0
- package/dist/{chunk-hjzdd750.js → chunk-bk9svbcq.js} +11 -11
- package/dist/{chunk-hjzdd750.js.map → chunk-bk9svbcq.js.map} +2 -2
- package/dist/{chunk-hkc3jct7.js → chunk-c06hmxyy.js} +2 -10
- package/dist/chunk-c06hmxyy.js.map +10 -0
- package/dist/{chunk-6p49a5cq.js → chunk-c1rxbz5y.js} +3 -3
- package/dist/chunk-cfj9dfbb.js +288 -0
- package/dist/chunk-cfj9dfbb.js.map +12 -0
- package/dist/{chunk-bx9q3cwv.js → chunk-cn0fwwhy.js} +7 -7
- package/dist/{chunk-bx9q3cwv.js.map → chunk-cn0fwwhy.js.map} +1 -1
- package/dist/{chunk-gc4ntf7d.js → chunk-cwdzcv37.js} +1 -1
- package/dist/{chunk-fa02jy15.js → chunk-cy4mbddw.js} +1 -1
- package/dist/{chunk-9w055r5b.js → chunk-d09e3rax.js} +1 -1
- package/dist/chunk-d5rjr8c0.js +176 -0
- package/dist/chunk-d5rjr8c0.js.map +12 -0
- package/dist/{chunk-dk8tkk5f.js → chunk-d7dnxdep.js} +3 -3
- package/dist/{chunk-b38szspf.js → chunk-dhcv7yxc.js} +1 -1
- package/dist/{chunk-b38szspf.js.map → chunk-dhcv7yxc.js.map} +1 -1
- package/dist/{chunk-gsjm1wms.js → chunk-dhdha526.js} +8 -2
- package/dist/chunk-dhdha526.js.map +10 -0
- package/dist/{chunk-8mx7qw3y.js → chunk-dvd2fp9q.js} +2 -2
- package/dist/{chunk-8mx7qw3y.js.map → chunk-dvd2fp9q.js.map} +3 -3
- package/dist/{chunk-way52z4h.js → chunk-e17zdm62.js} +6 -12
- package/dist/{chunk-way52z4h.js.map → chunk-e17zdm62.js.map} +3 -4
- package/dist/{chunk-tpn40322.js → chunk-e6k4thh5.js} +11 -10
- package/dist/{chunk-tpn40322.js.map → chunk-e6k4thh5.js.map} +3 -3
- package/dist/{chunk-tw03bsmb.js → chunk-eptrvnby.js} +224 -3
- package/dist/chunk-eptrvnby.js.map +12 -0
- package/dist/{chunk-es1gxsbf.js → chunk-f4pamkt9.js} +8 -10
- package/dist/chunk-f4pamkt9.js.map +12 -0
- package/dist/chunk-ff5xkv0p.js +211 -0
- package/dist/chunk-ff5xkv0p.js.map +10 -0
- package/dist/{chunk-d09tj99x.js → chunk-g257jwnc.js} +10 -4
- package/dist/{chunk-d09tj99x.js.map → chunk-g257jwnc.js.map} +3 -3
- package/dist/chunk-g5bvzyyr.js +32 -0
- package/dist/chunk-g5bvzyyr.js.map +10 -0
- package/dist/chunk-hke9aeen.js +9 -0
- package/dist/chunk-hke9aeen.js.map +10 -0
- package/dist/{chunk-1sr8ryzk.js → chunk-hwksyjks.js} +122 -1
- package/dist/{chunk-1sr8ryzk.js.map → chunk-hwksyjks.js.map} +3 -3
- package/dist/chunk-jcfw4h7m.js +9 -0
- package/dist/chunk-jcfw4h7m.js.map +10 -0
- package/dist/{chunk-k6q3n2sc.js → chunk-k43ct2ke.js} +20 -11
- package/dist/chunk-k43ct2ke.js.map +12 -0
- package/dist/{chunk-3t2hgbgd.js → chunk-kge7k6ey.js} +40 -8
- package/dist/chunk-kge7k6ey.js.map +15 -0
- package/dist/{chunk-tg2cw67r.js → chunk-ky3j490c.js} +2 -2
- package/dist/chunk-mjddfa7k.js +129 -0
- package/dist/chunk-mjddfa7k.js.map +12 -0
- package/dist/{chunk-vpq4shxz.js → chunk-nn5xnx3s.js} +45 -10
- package/dist/{chunk-vpq4shxz.js.map → chunk-nn5xnx3s.js.map} +7 -6
- package/dist/{chunk-0yh890a4.js → chunk-q5e5tv4b.js} +35 -7
- package/dist/{chunk-0yh890a4.js.map → chunk-q5e5tv4b.js.map} +3 -3
- package/dist/{chunk-vyf9kfqf.js → chunk-q7gn29y3.js} +1 -1
- package/dist/{chunk-yevzdx4y.js → chunk-rmakanzx.js} +10 -12
- package/dist/{chunk-yevzdx4y.js.map → chunk-rmakanzx.js.map} +3 -4
- package/dist/{chunk-v9xd5wzd.js → chunk-s7jg7pmn.js} +1 -1
- package/dist/chunk-tbc1ngpd.js +642 -0
- package/dist/chunk-tbc1ngpd.js.map +18 -0
- package/dist/chunk-twe4dx8p.js +676 -0
- package/dist/chunk-twe4dx8p.js.map +15 -0
- package/dist/{chunk-9dmt152s.js → chunk-vf57cr4t.js} +2 -2
- package/dist/{chunk-9ybhtmg4.js → chunk-vvxtn22d.js} +1 -1
- package/dist/{chunk-jhm3zsa7.js → chunk-wkv3h3q7.js} +64 -2
- package/dist/{chunk-jhm3zsa7.js.map → chunk-wkv3h3q7.js.map} +3 -3
- package/dist/chunk-x0v3jd47.js +124 -0
- package/dist/chunk-x0v3jd47.js.map +10 -0
- package/dist/{chunk-7t429e3f.js → chunk-xvsc5m8n.js} +1 -1
- package/dist/{chunk-z4m0yz8c.js → chunk-y5tah2kf.js} +1 -1
- package/dist/{chunk-fkgc1wt8.js → chunk-z58tm0hm.js} +2 -2
- package/dist/datasets/builders.d.ts +15 -2
- package/dist/datasets/builders.d.ts.map +1 -1
- package/dist/datasets/column-index.d.ts +7 -0
- package/dist/datasets/column-index.d.ts.map +1 -0
- package/dist/datasets/execution.d.ts +3 -2
- package/dist/datasets/execution.d.ts.map +1 -1
- package/dist/datasets/write.js +8 -8
- package/dist/error-reporting/internal.js +4 -4
- package/dist/errors/internal.d.ts +1 -0
- package/dist/errors/internal.d.ts.map +1 -1
- package/dist/errors/internal.js +7 -4
- package/dist/errors/internal.js.map +1 -1
- package/dist/events/execution.d.ts +12 -2
- package/dist/events/execution.d.ts.map +1 -1
- package/dist/events/index.js +4 -4
- package/dist/execution/agent.js +56 -49
- package/dist/execution/agent.js.map +1 -1
- package/dist/execution/authorized-object-reader.d.ts +52 -11
- package/dist/execution/authorized-object-reader.d.ts.map +1 -1
- package/dist/execution/object-reader-clearance.d.ts +41 -0
- package/dist/execution/object-reader-clearance.d.ts.map +1 -0
- package/dist/execution/object-reader-ontology.d.ts +12 -0
- package/dist/execution/object-reader-ontology.d.ts.map +1 -0
- package/dist/execution/object-reader-security.d.ts +45 -0
- package/dist/execution/object-reader-security.d.ts.map +1 -0
- package/dist/execution/primitive.js +54 -47
- package/dist/execution/primitive.js.map +1 -1
- package/dist/execution/request.js +48 -41
- package/dist/execution/request.js.map +2 -2
- package/dist/http/api-routes.d.ts.map +1 -1
- package/dist/http/index.js +1 -1
- package/dist/index.d.ts +20 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +112 -97
- package/dist/index.js.map +1 -1
- package/dist/lake-storage/in-memory.d.ts +1 -0
- package/dist/lake-storage/in-memory.d.ts.map +1 -1
- package/dist/lake-storage/index.d.ts +6 -3
- package/dist/lake-storage/index.d.ts.map +1 -1
- package/dist/lake-storage/index.js +21 -13
- package/dist/lake-storage/index.js.map +1 -1
- package/dist/lake-storage/lineage.d.ts +94 -0
- package/dist/lake-storage/lineage.d.ts.map +1 -0
- package/dist/lake-storage/sql-transforms.d.ts +45 -0
- package/dist/lake-storage/sql-transforms.d.ts.map +1 -1
- package/dist/lake-storage/types.d.ts +55 -1
- package/dist/lake-storage/types.d.ts.map +1 -1
- package/dist/lake-storage/version-inputs.d.ts +14 -3
- package/dist/lake-storage/version-inputs.d.ts.map +1 -1
- package/dist/maintenance/ontology-maintenance.d.ts.map +1 -1
- package/dist/materializer/index.js +31 -30
- package/dist/materializer/index.js.map +1 -1
- package/dist/models/execution/index.js +25 -24
- package/dist/models/execution/index.js.map +1 -1
- package/dist/objects/clearance-redaction.d.ts +27 -0
- package/dist/objects/clearance-redaction.d.ts.map +1 -0
- package/dist/objects/index.js +54 -47
- package/dist/objects/index.js.map +1 -1
- package/dist/objects/link/authorization.d.ts +8 -5
- package/dist/objects/link/authorization.d.ts.map +1 -1
- package/dist/objects/link/upsert-batch.d.ts.map +1 -1
- package/dist/objects/object/delete.d.ts.map +1 -1
- package/dist/objects/object/upsert-batch.d.ts.map +1 -1
- package/dist/objects/object/upsert.d.ts.map +1 -1
- package/dist/objects/property-clearance.d.ts +47 -24
- package/dist/objects/property-clearance.d.ts.map +1 -1
- package/dist/objects/query/clearance-admission.d.ts +10 -0
- package/dist/objects/query/clearance-admission.d.ts.map +1 -0
- package/dist/objects/query/index.js +29 -28
- package/dist/objects/query/index.js.map +1 -1
- package/dist/objects/query/link-query-clearance.d.ts +21 -0
- package/dist/objects/query/link-query-clearance.d.ts.map +1 -0
- package/dist/ontology/builders.d.ts.map +1 -1
- package/dist/ontology/docs-markdown.d.ts +1 -1
- package/dist/ontology/docs-markdown.d.ts.map +1 -1
- package/dist/ontology/index.js +7 -7
- package/dist/ontology/internal.js +4 -4
- package/dist/ontology/internal.js.map +1 -1
- package/dist/pipelines/index.d.ts +2 -0
- package/dist/pipelines/index.d.ts.map +1 -1
- package/dist/pipelines/index.js +47 -35
- package/dist/pipelines/index.js.map +1 -1
- package/dist/pipelines/lineage.d.ts +17 -0
- package/dist/pipelines/lineage.d.ts.map +1 -0
- package/dist/projections/internal.d.ts +2 -2
- package/dist/projections/internal.js +30 -29
- package/dist/projections/internal.js.map +1 -1
- package/dist/runtime/create.d.ts +3 -0
- package/dist/runtime/create.d.ts.map +1 -1
- package/dist/runtime/host.d.ts +6 -0
- package/dist/runtime/host.d.ts.map +1 -1
- package/dist/runtime/internal.d.ts +2 -0
- package/dist/runtime/internal.d.ts.map +1 -1
- package/dist/runtime/internal.js +46 -42
- package/dist/runtime/internal.js.map +1 -1
- package/dist/runtime/ontology-mutations.d.ts +2 -0
- package/dist/runtime/ontology-mutations.d.ts.map +1 -1
- package/dist/runtime/resolve-definitions.d.ts.map +1 -1
- package/dist/runtime/sixb.d.ts +8 -0
- package/dist/runtime/sixb.d.ts.map +1 -1
- package/dist/sandboxes/auth.d.ts +16 -0
- package/dist/sandboxes/auth.d.ts.map +1 -1
- package/dist/sandboxes/config.d.ts.map +1 -1
- package/dist/sandboxes/configuration.d.ts +26 -0
- package/dist/sandboxes/configuration.d.ts.map +1 -1
- package/dist/sandboxes/index.d.ts +1 -1
- package/dist/sandboxes/index.d.ts.map +1 -1
- package/dist/sandboxes/index.js +14 -13
- package/dist/sandboxes/index.js.map +1 -1
- package/dist/sandboxes/sandbox.d.ts +28 -5
- package/dist/sandboxes/sandbox.d.ts.map +1 -1
- package/dist/security/applied-markings-contribution.d.ts +58 -0
- package/dist/security/applied-markings-contribution.d.ts.map +1 -0
- package/dist/security/applied-markings-host.d.ts +10 -0
- package/dist/security/applied-markings-host.d.ts.map +1 -0
- package/dist/security/applied-markings-snapshot.d.ts +67 -0
- package/dist/security/applied-markings-snapshot.d.ts.map +1 -0
- package/dist/security/applied-markings.d.ts +73 -0
- package/dist/security/applied-markings.d.ts.map +1 -0
- package/dist/security/dataset-version-markings.d.ts +47 -0
- package/dist/security/dataset-version-markings.d.ts.map +1 -0
- package/dist/security/grants.d.ts +3 -2
- package/dist/security/grants.d.ts.map +1 -1
- package/dist/security/index.d.ts +2 -1
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/internal.d.ts +15 -0
- package/dist/security/internal.d.ts.map +1 -0
- package/dist/security/internal.js +135 -0
- package/dist/security/internal.js.map +10 -0
- package/dist/security/marking-propagation.d.ts +62 -0
- package/dist/security/marking-propagation.d.ts.map +1 -0
- package/dist/security/marking-sets.d.ts +14 -0
- package/dist/security/marking-sets.d.ts.map +1 -0
- package/dist/security/markings.d.ts +6 -3
- package/dist/security/markings.d.ts.map +1 -1
- package/dist/security/pipeline-markings.d.ts +20 -0
- package/dist/security/pipeline-markings.d.ts.map +1 -0
- package/dist/security/project.d.ts +4 -0
- package/dist/security/project.d.ts.map +1 -0
- package/dist/security/projection-markings.d.ts +71 -0
- package/dist/security/projection-markings.d.ts.map +1 -0
- package/dist/security/public.js +2 -2
- package/dist/security/redactions.d.ts +4 -1
- package/dist/security/redactions.d.ts.map +1 -1
- package/dist/security/types.d.ts +22 -2
- package/dist/security/types.d.ts.map +1 -1
- package/dist/security/validation.d.ts.map +1 -1
- package/dist/shares/internal.js +24 -23
- package/dist/shares/internal.js.map +2 -2
- package/dist/storage/action-runs/failure.js +3 -3
- package/dist/storage/action-runs/in-memory.d.ts +4 -0
- package/dist/storage/action-runs/in-memory.d.ts.map +1 -1
- package/dist/storage/action-runs/types.d.ts +8 -0
- package/dist/storage/action-runs/types.d.ts.map +1 -1
- package/dist/storage/activity/in-memory.d.ts +55 -0
- package/dist/storage/activity/in-memory.d.ts.map +1 -0
- package/dist/storage/activity/index.d.ts +3 -0
- package/dist/storage/activity/index.d.ts.map +1 -0
- package/dist/storage/activity/policy.d.ts +96 -0
- package/dist/storage/activity/policy.d.ts.map +1 -0
- package/dist/storage/activity/types.d.ts +191 -0
- package/dist/storage/activity/types.d.ts.map +1 -0
- package/dist/storage/agents/in-memory.d.ts +4 -0
- package/dist/storage/agents/in-memory.d.ts.map +1 -1
- package/dist/storage/agents/provider.d.ts.map +1 -1
- package/dist/storage/agents/provider.js +2 -5
- package/dist/storage/agents/provider.js.map +1 -1
- package/dist/storage/agents/types.d.ts +9 -8
- package/dist/storage/agents/types.d.ts.map +1 -1
- package/dist/storage/ai-limits/enforcement.js +3 -3
- package/dist/storage/artifacts/errors.d.ts +8 -0
- package/dist/storage/artifacts/errors.d.ts.map +1 -0
- package/dist/storage/artifacts/in-memory.d.ts +34 -0
- package/dist/storage/artifacts/in-memory.d.ts.map +1 -0
- package/dist/storage/artifacts/index.d.ts +5 -0
- package/dist/storage/artifacts/index.d.ts.map +1 -0
- package/dist/storage/artifacts/record.d.ts +17 -0
- package/dist/storage/artifacts/record.d.ts.map +1 -0
- package/dist/storage/artifacts/types.d.ts +184 -0
- package/dist/storage/artifacts/types.d.ts.map +1 -0
- package/dist/storage/auth/in-memory/sessions.d.ts +2 -1
- package/dist/storage/auth/in-memory/sessions.d.ts.map +1 -1
- package/dist/storage/auth/index.d.ts +1 -1
- package/dist/storage/auth/index.d.ts.map +1 -1
- package/dist/storage/auth/types.d.ts +19 -0
- package/dist/storage/auth/types.d.ts.map +1 -1
- package/dist/storage/connector-connections/provider.js +2 -2
- package/dist/storage/executions/in-memory.d.ts +2 -1
- package/dist/storage/executions/in-memory.d.ts.map +1 -1
- package/dist/storage/executions/index.d.ts +1 -1
- package/dist/storage/executions/index.d.ts.map +1 -1
- package/dist/storage/executions/provider.d.ts +2 -0
- package/dist/storage/executions/provider.d.ts.map +1 -1
- package/dist/storage/executions/provider.js +9 -223
- package/dist/storage/executions/provider.js.map +3 -4
- package/dist/storage/executions/types.d.ts +31 -0
- package/dist/storage/executions/types.d.ts.map +1 -1
- package/dist/storage/file-upload-sessions/provider.js +11 -11
- package/dist/storage/in-memory/index.d.ts +8 -0
- package/dist/storage/in-memory/index.d.ts.map +1 -1
- package/dist/storage/index.d.ts +6 -4
- package/dist/storage/index.d.ts.map +1 -1
- package/dist/storage/index.js +54 -53
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/internal.d.ts +3 -0
- package/dist/storage/internal.d.ts.map +1 -1
- package/dist/storage/internal.js +66 -16
- package/dist/storage/internal.js.map +1 -1
- package/dist/storage/ontology/in-memory/sources.d.ts +2 -1
- package/dist/storage/ontology/in-memory/sources.d.ts.map +1 -1
- package/dist/storage/ontology/index.d.ts +1 -1
- package/dist/storage/ontology/index.d.ts.map +1 -1
- package/dist/storage/ontology/sources.d.ts +15 -0
- package/dist/storage/ontology/sources.d.ts.map +1 -1
- package/dist/storage/projection-runs/provider.js +3 -3
- package/dist/storage/share-grants/in-memory.d.ts +2 -1
- package/dist/storage/share-grants/in-memory.d.ts.map +1 -1
- package/dist/storage/share-grants/index.d.ts +1 -1
- package/dist/storage/share-grants/index.d.ts.map +1 -1
- package/dist/storage/share-grants/types.d.ts +6 -0
- package/dist/storage/share-grants/types.d.ts.map +1 -1
- package/dist/storage/types.d.ts +4 -0
- package/dist/storage/types.d.ts.map +1 -1
- package/dist/storage/workflow-runs/in-memory.d.ts +4 -0
- package/dist/storage/workflow-runs/in-memory.d.ts.map +1 -1
- package/dist/storage/workflow-runs/provider.js +13 -12
- package/dist/storage/workflow-runs/provider.js.map +1 -1
- package/dist/storage/workflow-runs/types.d.ts +5 -0
- package/dist/storage/workflow-runs/types.d.ts.map +1 -1
- package/dist/syncs/index.js +35 -34
- package/dist/syncs/index.js.map +1 -1
- package/dist/testing/action-run-storage-contract.d.ts.map +1 -1
- package/dist/testing/activity-storage-contract.d.ts +14 -0
- package/dist/testing/activity-storage-contract.d.ts.map +1 -0
- package/dist/testing/agent-storage-contract.d.ts.map +1 -1
- package/dist/testing/artifact-storage-contract.d.ts +13 -0
- package/dist/testing/artifact-storage-contract.d.ts.map +1 -0
- package/dist/testing/auth-storage-contract.d.ts.map +1 -1
- package/dist/testing/execution-storage-contract.d.ts.map +1 -1
- package/dist/testing/index.d.ts +2 -0
- package/dist/testing/index.d.ts.map +1 -1
- package/dist/testing/index.js +4488 -3137
- package/dist/testing/index.js.map +14 -12
- package/dist/testing/lake-merge-storage-contract.d.ts.map +1 -1
- package/dist/testing/lake-storage-contract.d.ts +2 -0
- package/dist/testing/lake-storage-contract.d.ts.map +1 -1
- package/dist/testing/ontology-storage-contract.d.ts.map +1 -1
- package/dist/testing/share-grant-storage-contract.d.ts.map +1 -1
- package/dist/webhooks/internal.js +27 -26
- package/dist/webhooks/internal.js.map +2 -2
- package/dist/workers/index.js +2 -2
- package/dist/workflows/builders.d.ts.map +1 -1
- package/dist/workflows/index.js +57 -51
- package/dist/workflows/index.js.map +1 -1
- package/dist/workflows/types.d.ts +9 -0
- package/dist/workflows/types.d.ts.map +1 -1
- package/dist/workflows/validation.d.ts +7 -0
- package/dist/workflows/validation.d.ts.map +1 -1
- package/package.json +25 -1
- package/src/actions/execution.ts +18 -13
- package/src/actions/request.ts +18 -3
- package/src/actions/run-authorization.ts +23 -0
- package/src/activity/README.md +155 -0
- package/src/activity/connection.ts +217 -0
- package/src/activity/device.ts +41 -0
- package/src/activity/execution.ts +210 -0
- package/src/activity/service.ts +274 -0
- package/src/activity/shares.ts +62 -0
- package/src/activity/timeline.ts +424 -0
- package/src/agents/index.ts +8 -3
- package/src/agents/request.ts +5 -0
- package/src/agents/skills.ts +6 -0
- package/src/agents/types.ts +8 -8
- package/src/agents/validation.ts +2 -0
- package/src/artifacts/address.ts +132 -0
- package/src/artifacts/csv.ts +108 -0
- package/src/artifacts/errors.ts +21 -0
- package/src/artifacts/execution.ts +153 -0
- package/src/artifacts/frames/assets.ts +88 -0
- package/src/artifacts/frames/grants.ts +124 -0
- package/src/artifacts/frames/index.ts +15 -0
- package/src/artifacts/frames/kit.ts +392 -0
- package/src/artifacts/frames/probe.ts +309 -0
- package/src/artifacts/frames/protocol.ts +174 -0
- package/src/artifacts/frames/runtime.ts +213 -0
- package/src/artifacts/html.ts +25 -0
- package/src/artifacts/ids.ts +18 -0
- package/src/artifacts/index.ts +61 -0
- package/src/artifacts/kinds.ts +8 -0
- package/src/artifacts/limits.ts +27 -0
- package/src/artifacts/outline.ts +62 -0
- package/src/artifacts/publish/files.ts +87 -0
- package/src/artifacts/publish/index.ts +12 -0
- package/src/artifacts/publish/publish.ts +250 -0
- package/src/artifacts/publish/references.ts +130 -0
- package/src/artifacts/publish/validate/document.ts +114 -0
- package/src/artifacts/publish/validate/file.ts +19 -0
- package/src/artifacts/publish/validate/sheet.ts +251 -0
- package/src/artifacts/publish/validate/slides.ts +134 -0
- package/src/artifacts/references.ts +11 -0
- package/src/artifacts/resolve.ts +97 -0
- package/src/artifacts/theme.ts +116 -0
- package/src/artifacts/warnings.ts +10 -0
- package/src/artifacts/workbook.ts +315 -0
- package/src/authorization/decision.ts +5 -0
- package/src/authorization/grant-kinds.ts +14 -2
- package/src/blob-storage/internal.ts +1 -1
- package/src/blob-storage/media-type.ts +69 -0
- package/src/datasets/builders.ts +66 -2
- package/src/datasets/column-index.ts +19 -0
- package/src/datasets/execution.ts +23 -9
- package/src/errors/internal.ts +1 -0
- package/src/events/execution.ts +134 -21
- package/src/execution/authorized-object-reader.ts +270 -256
- package/src/execution/object-reader-clearance.ts +91 -0
- package/src/execution/object-reader-ontology.ts +63 -0
- package/src/execution/object-reader-security.ts +146 -0
- package/src/http/api-routes.ts +125 -0
- package/src/index.ts +71 -3
- package/src/lake-storage/in-memory.ts +26 -3
- package/src/lake-storage/index.ts +13 -1
- package/src/lake-storage/lineage.ts +385 -0
- package/src/lake-storage/sql-transforms.ts +45 -0
- package/src/lake-storage/types.ts +59 -1
- package/src/lake-storage/version-inputs.ts +35 -6
- package/src/maintenance/ontology-maintenance.ts +15 -0
- package/src/objects/clearance-redaction.ts +138 -0
- package/src/objects/link/authorization.ts +27 -7
- package/src/objects/link/remove.ts +2 -2
- package/src/objects/link/upsert-batch.ts +7 -5
- package/src/objects/link/upsert.ts +2 -2
- package/src/objects/object/delete.ts +2 -0
- package/src/objects/object/upsert-batch.ts +2 -4
- package/src/objects/object/upsert.ts +2 -3
- package/src/objects/property-clearance.ts +171 -152
- package/src/objects/query/clearance-admission.ts +112 -0
- package/src/objects/query/link-query-clearance.ts +73 -0
- package/src/ontology/builders.ts +12 -1
- package/src/ontology/docs-markdown.ts +1 -1
- package/src/pipelines/index.ts +2 -0
- package/src/pipelines/lineage.ts +45 -0
- package/src/projections/internal.ts +2 -2
- package/src/runtime/create.ts +4 -0
- package/src/runtime/host.ts +55 -0
- package/src/runtime/internal.ts +2 -0
- package/src/runtime/ontology-mutations.ts +19 -4
- package/src/runtime/resolve-definitions.ts +66 -3
- package/src/runtime/sixb.ts +18 -1
- package/src/sandboxes/README.md +29 -7
- package/src/sandboxes/auth.ts +16 -0
- package/src/sandboxes/config.ts +2 -7
- package/src/sandboxes/configuration.ts +61 -7
- package/src/sandboxes/index.ts +1 -0
- package/src/sandboxes/sandbox.ts +27 -5
- package/src/security/applied-markings-contribution.ts +277 -0
- package/src/security/applied-markings-host.ts +41 -0
- package/src/security/applied-markings-snapshot.ts +235 -0
- package/src/security/applied-markings.ts +405 -0
- package/src/security/dataset-version-markings.ts +163 -0
- package/src/security/grants.ts +39 -4
- package/src/security/index.ts +3 -0
- package/src/security/internal.ts +18 -0
- package/src/security/marking-propagation.ts +255 -0
- package/src/security/marking-sets.ts +42 -0
- package/src/security/markings.ts +29 -178
- package/src/security/pipeline-markings.ts +175 -0
- package/src/security/project.ts +8 -0
- package/src/security/projection-markings.ts +421 -0
- package/src/security/redactions.ts +7 -2
- package/src/security/types.ts +20 -2
- package/src/security/validation.ts +11 -4
- package/src/storage/action-runs/in-memory.ts +18 -0
- package/src/storage/action-runs/types.ts +8 -0
- package/src/storage/activity/in-memory.ts +374 -0
- package/src/storage/activity/index.ts +27 -0
- package/src/storage/activity/policy.ts +430 -0
- package/src/storage/activity/types.ts +211 -0
- package/src/storage/agents/in-memory.ts +10 -0
- package/src/storage/agents/provider.ts +2 -13
- package/src/storage/agents/types.ts +9 -16
- package/src/storage/artifacts/errors.ts +16 -0
- package/src/storage/artifacts/in-memory.ts +240 -0
- package/src/storage/artifacts/index.ts +30 -0
- package/src/storage/artifacts/record.ts +200 -0
- package/src/storage/artifacts/types.ts +209 -0
- package/src/storage/auth/in-memory/sessions.ts +21 -0
- package/src/storage/auth/index.ts +2 -0
- package/src/storage/auth/types.ts +18 -0
- package/src/storage/executions/in-memory.ts +61 -1
- package/src/storage/executions/index.ts +3 -0
- package/src/storage/executions/provider.ts +12 -0
- package/src/storage/executions/types.ts +30 -0
- package/src/storage/in-memory/index.ts +16 -0
- package/src/storage/index.ts +63 -0
- package/src/storage/internal.ts +30 -0
- package/src/storage/ontology/in-memory/sources.ts +23 -0
- package/src/storage/ontology/index.ts +2 -0
- package/src/storage/ontology/sources.ts +17 -0
- package/src/storage/share-grants/in-memory.ts +8 -0
- package/src/storage/share-grants/index.ts +1 -0
- package/src/storage/share-grants/types.ts +8 -0
- package/src/storage/types.ts +4 -0
- package/src/storage/workflow-runs/in-memory.ts +16 -0
- package/src/storage/workflow-runs/types.ts +5 -0
- package/src/testing/action-run-storage-contract.ts +25 -0
- package/src/testing/activity-storage-contract.ts +840 -0
- package/src/testing/agent-storage-contract.ts +22 -21
- package/src/testing/artifact-storage-contract.ts +517 -0
- package/src/testing/auth-storage-contract.ts +47 -0
- package/src/testing/execution-storage-contract.ts +147 -1
- package/src/testing/index.ts +9 -0
- package/src/testing/lake-merge-storage-contract.ts +38 -0
- package/src/testing/lake-storage-contract.ts +247 -2
- package/src/testing/materializer-storage-contract.ts +1 -0
- package/src/testing/ontology-storage-contract.ts +57 -2
- package/src/testing/share-grant-storage-contract.ts +15 -0
- package/src/workflows/builders.ts +14 -0
- package/src/workflows/types.ts +9 -0
- package/src/workflows/validation.ts +72 -0
- package/dist/chunk-1k89ecfr.js +0 -85
- package/dist/chunk-1k89ecfr.js.map +0 -10
- package/dist/chunk-3t2hgbgd.js.map +0 -15
- package/dist/chunk-4vyr1j8f.js +0 -128
- package/dist/chunk-4vyr1j8f.js.map +0 -11
- package/dist/chunk-9gyp8hg1.js +0 -363
- package/dist/chunk-9gyp8hg1.js.map +0 -14
- package/dist/chunk-es1gxsbf.js.map +0 -13
- package/dist/chunk-gsjm1wms.js.map +0 -10
- package/dist/chunk-hkc3jct7.js.map +0 -10
- package/dist/chunk-k6q3n2sc.js.map +0 -12
- package/dist/chunk-rrzt8jdy.js.map +0 -14
- package/dist/chunk-s16apyk9.js +0 -256
- package/dist/chunk-s16apyk9.js.map +0 -16
- package/dist/chunk-s54c868q.js.map +0 -12
- package/dist/chunk-tw03bsmb.js.map +0 -11
- /package/dist/{chunk-xfs8x8m9.js.map → chunk-0bphap9y.js.map} +0 -0
- /package/dist/{chunk-1zq2p6g0.js.map → chunk-1cc1xaf3.js.map} +0 -0
- /package/dist/{chunk-t7x8dmn0.js.map → chunk-431pyp2c.js.map} +0 -0
- /package/dist/{chunk-c85m1hyj.js.map → chunk-447a5c0p.js.map} +0 -0
- /package/dist/{chunk-ren4kg2j.js.map → chunk-561r0yc9.js.map} +0 -0
- /package/dist/{chunk-5e43w60z.js.map → chunk-5948n82c.js.map} +0 -0
- /package/dist/{chunk-yzwja0mj.js.map → chunk-5hx48dnn.js.map} +0 -0
- /package/dist/{chunk-5j58wjct.js.map → chunk-858emn8m.js.map} +0 -0
- /package/dist/{chunk-6p49a5cq.js.map → chunk-c1rxbz5y.js.map} +0 -0
- /package/dist/{chunk-gc4ntf7d.js.map → chunk-cwdzcv37.js.map} +0 -0
- /package/dist/{chunk-fa02jy15.js.map → chunk-cy4mbddw.js.map} +0 -0
- /package/dist/{chunk-9w055r5b.js.map → chunk-d09e3rax.js.map} +0 -0
- /package/dist/{chunk-dk8tkk5f.js.map → chunk-d7dnxdep.js.map} +0 -0
- /package/dist/{chunk-tg2cw67r.js.map → chunk-ky3j490c.js.map} +0 -0
- /package/dist/{chunk-vyf9kfqf.js.map → chunk-q7gn29y3.js.map} +0 -0
- /package/dist/{chunk-v9xd5wzd.js.map → chunk-s7jg7pmn.js.map} +0 -0
- /package/dist/{chunk-9dmt152s.js.map → chunk-vf57cr4t.js.map} +0 -0
- /package/dist/{chunk-9ybhtmg4.js.map → chunk-vvxtn22d.js.map} +0 -0
- /package/dist/{chunk-7t429e3f.js.map → chunk-xvsc5m8n.js.map} +0 -0
- /package/dist/{chunk-z4m0yz8c.js.map → chunk-y5tah2kf.js.map} +0 -0
- /package/dist/{chunk-fkgc1wt8.js.map → chunk-z58tm0hm.js.map} +0 -0
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
import type { DatasetDefinition } from "../datasets/types"
|
|
2
|
+
import type {
|
|
3
|
+
LakeStorageWithSql,
|
|
4
|
+
SqlTransformAnalysis,
|
|
5
|
+
SqlTransformColumnRef,
|
|
6
|
+
} from "../lake-storage/sql-transforms"
|
|
7
|
+
import type { DatasetColumnLineage, DatasetColumnRef, LakeStorage } from "../lake-storage/types"
|
|
8
|
+
import { PipelineError } from "../pipelines/errors"
|
|
9
|
+
import { stepInputColumns, stepReadColumns } from "../pipelines/lineage"
|
|
10
|
+
import type { PipelineStepDefinition } from "../pipelines/types"
|
|
11
|
+
import type { SixbDefinitions } from "../runtime/definitions"
|
|
12
|
+
import { SecurityValidationError } from "./errors"
|
|
13
|
+
import {
|
|
14
|
+
type DatasetMarkings,
|
|
15
|
+
MarkingPropagation,
|
|
16
|
+
type RegisteredStep,
|
|
17
|
+
registeredSteps,
|
|
18
|
+
runStepLineages,
|
|
19
|
+
} from "./marking-propagation"
|
|
20
|
+
import { describeOrigins, validateProjectionMarkings } from "./projection-markings"
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Derive the markings SQL steps give their outputs and check every projection against them.
|
|
24
|
+
*
|
|
25
|
+
* Startup cannot see through SQL, so this preflight completes it before a host serves traffic. It
|
|
26
|
+
* is a diagnostic: each version records the lineage of the SQL that actually ran, and reads and
|
|
27
|
+
* projections enforce markings from that record whether or not this ran.
|
|
28
|
+
*
|
|
29
|
+
* Only steps that read a marked column are analyzed, each step once. Analyzing a step can mark
|
|
30
|
+
* the inputs of others, so steps are analyzed in waves, a few at a time within a wave. A step whose
|
|
31
|
+
* SQL cannot be analyzed, or a lake provider that cannot analyze SQL, is reported with the step
|
|
32
|
+
* and a marked column it reads.
|
|
33
|
+
*/
|
|
34
|
+
export async function checkPipelineMarkings(input: {
|
|
35
|
+
readonly definitions: Pick<SixbDefinitions, "ontology" | "datasets" | "pipelines" | "projections">
|
|
36
|
+
readonly lakeStorage: LakeStorage | LakeStorageWithSql
|
|
37
|
+
}): Promise<void> {
|
|
38
|
+
const { definitions, lakeStorage } = input
|
|
39
|
+
const datasetsById = new Map(definitions.datasets.list().map((dataset) => [dataset.id, dataset]))
|
|
40
|
+
const steps = registeredSteps(definitions.pipelines.list())
|
|
41
|
+
const runLineageOf = runStepLineages(datasetsById)
|
|
42
|
+
const analyzed = new Map<PipelineStepDefinition, DatasetColumnLineage>()
|
|
43
|
+
const lineageOf = (entry: RegisteredStep) =>
|
|
44
|
+
runLineageOf(entry) ?? analyzed.get(entry.step) ?? null
|
|
45
|
+
|
|
46
|
+
const markings = new MarkingPropagation(datasetsById, steps).derive(lineageOf)
|
|
47
|
+
|
|
48
|
+
for (;;) {
|
|
49
|
+
const wave = new Map<PipelineStepDefinition, RegisteredStep>()
|
|
50
|
+
for (const entry of steps) {
|
|
51
|
+
if (entry.step.executor.kind !== "sql" || analyzed.has(entry.step)) continue
|
|
52
|
+
if (stepReadColumns(entry.step).some((ref) => markings.of(ref).size > 0)) {
|
|
53
|
+
if (!wave.has(entry.step)) wave.set(entry.step, entry)
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
if (wave.size === 0) break
|
|
58
|
+
|
|
59
|
+
await forEachConcurrently([...wave], ANALYSIS_CONCURRENCY, async ([step, entry]) => {
|
|
60
|
+
analyzed.set(step, await analyzeSqlStep(entry, markings, datasetsById, lakeStorage))
|
|
61
|
+
})
|
|
62
|
+
markings.derive(lineageOf)
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
validateProjectionMarkings(definitions.projections, definitions.ontology, markings)
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/** Analyses run at once. A provider may open a database per analysis, so a wave is not unbounded. */
|
|
69
|
+
const ANALYSIS_CONCURRENCY = 8
|
|
70
|
+
|
|
71
|
+
/** Run `task` on each item, `limit` at a time. Stops starting new tasks once one fails. */
|
|
72
|
+
async function forEachConcurrently<TItem>(
|
|
73
|
+
items: readonly TItem[],
|
|
74
|
+
limit: number,
|
|
75
|
+
task: (item: TItem) => Promise<void>
|
|
76
|
+
): Promise<void> {
|
|
77
|
+
const pending = items.values()
|
|
78
|
+
let failed = false
|
|
79
|
+
|
|
80
|
+
const worker = async () => {
|
|
81
|
+
for (const item of pending) {
|
|
82
|
+
if (failed) return
|
|
83
|
+
|
|
84
|
+
try {
|
|
85
|
+
await task(item)
|
|
86
|
+
} catch (error) {
|
|
87
|
+
failed = true
|
|
88
|
+
throw error
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
await Promise.all(Array.from({ length: Math.min(limit, items.length) }, worker))
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
async function analyzeSqlStep(
|
|
97
|
+
entry: RegisteredStep,
|
|
98
|
+
markings: DatasetMarkings,
|
|
99
|
+
datasetsById: ReadonlyMap<string, DatasetDefinition>,
|
|
100
|
+
lakeStorage: LakeStorage | LakeStorageWithSql
|
|
101
|
+
): Promise<DatasetColumnLineage> {
|
|
102
|
+
const { step } = entry
|
|
103
|
+
const subject = `[Sixb] Pipeline '${entry.pipelineId}' step '${step.id}'`
|
|
104
|
+
|
|
105
|
+
if (step.executor.kind !== "sql") throw new PipelineError(`${subject} is not a SQL step.`)
|
|
106
|
+
|
|
107
|
+
const sql = "sql" in lakeStorage ? lakeStorage.sql : undefined
|
|
108
|
+
if (!sql?.analyze) {
|
|
109
|
+
throw new SecurityValidationError(
|
|
110
|
+
`${subject} reads ${describeMarkedRead(step, markings)}, but the lake provider cannot analyze SQL to derive the markings of its output. Use a lake provider that analyzes SQL, or pick only unmarked columns.`
|
|
111
|
+
)
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const inputs = Object.entries(step.inputs)
|
|
115
|
+
let analysis: SqlTransformAnalysis
|
|
116
|
+
try {
|
|
117
|
+
analysis = await sql.analyze({
|
|
118
|
+
sql: step.executor.sql,
|
|
119
|
+
sources: Object.fromEntries(
|
|
120
|
+
inputs.map(([name, dataset]) => [
|
|
121
|
+
name,
|
|
122
|
+
{
|
|
123
|
+
dataset: registeredDataset(datasetsById, dataset.id, subject),
|
|
124
|
+
columns: stepInputColumns(dataset),
|
|
125
|
+
},
|
|
126
|
+
])
|
|
127
|
+
),
|
|
128
|
+
})
|
|
129
|
+
} catch (error) {
|
|
130
|
+
const reason = error instanceof Error ? error.message : String(error)
|
|
131
|
+
throw new PipelineError(`${subject} could not be analyzed: ${reason}`, { cause: error })
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
if (!analysis.supported) {
|
|
135
|
+
throw new SecurityValidationError(
|
|
136
|
+
`${subject} reads ${describeMarkedRead(step, markings)}, but its SQL cannot be analyzed: ${analysis.reason}. Rewrite that part of the query, or pick only unmarked columns.`
|
|
137
|
+
)
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
const datasetIdBySource = new Map(inputs.map(([name, dataset]) => [name, dataset.id]))
|
|
141
|
+
const toRef = (ref: SqlTransformColumnRef): DatasetColumnRef => {
|
|
142
|
+
const datasetId = datasetIdBySource.get(ref.source)
|
|
143
|
+
if (datasetId === undefined) {
|
|
144
|
+
throw new PipelineError(`${subject} analysis references unknown source '${ref.source}'.`)
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
return { datasetId, column: ref.column }
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
return {
|
|
151
|
+
rows: analysis.lineage.rows.map(toRef),
|
|
152
|
+
columns: Object.fromEntries(
|
|
153
|
+
Object.entries(analysis.lineage.columns).map(([column, refs]) => [column, refs.map(toRef)])
|
|
154
|
+
),
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
/** A marked column the step reads, for messages. */
|
|
159
|
+
function describeMarkedRead(step: PipelineStepDefinition, markings: DatasetMarkings): string {
|
|
160
|
+
const ref = stepReadColumns(step).find((candidate) => markings.of(candidate).size > 0)
|
|
161
|
+
if (!ref) return "no marked column"
|
|
162
|
+
|
|
163
|
+
const path = `${ref.datasetId}.${ref.column}`
|
|
164
|
+
return `column '${path}', which carries ${describeOrigins(markings.of(ref), path)}`
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
function registeredDataset(
|
|
168
|
+
datasetsById: ReadonlyMap<string, DatasetDefinition>,
|
|
169
|
+
datasetId: string,
|
|
170
|
+
subject: string
|
|
171
|
+
): DatasetDefinition {
|
|
172
|
+
const dataset = datasetsById.get(datasetId)
|
|
173
|
+
if (!dataset) throw new PipelineError(`${subject} reads unregistered dataset '${datasetId}'.`)
|
|
174
|
+
return dataset
|
|
175
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { ProjectReference } from "./types"
|
|
2
|
+
|
|
3
|
+
/** Project-wide surfaces used in security grants such as `can.observe(project.logs)`. */
|
|
4
|
+
export const project: ProjectReference = Object.freeze({
|
|
5
|
+
kind: "project",
|
|
6
|
+
logs: Object.freeze({ kind: "logs" }),
|
|
7
|
+
activity: Object.freeze({ kind: "activity" }),
|
|
8
|
+
})
|
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
import type { DatasetVersion } from "../lake-storage/types"
|
|
2
|
+
import type { OntologyDefinitionCatalog } from "../ontology/registry"
|
|
3
|
+
import type { ObjectType } from "../ontology/types"
|
|
4
|
+
import type { ProjectionDefinitionCatalog } from "../projections/registry"
|
|
5
|
+
import type {
|
|
6
|
+
LinkProjectionDefinition,
|
|
7
|
+
ObjectProjectionDefinition,
|
|
8
|
+
ProjectionDefinition,
|
|
9
|
+
TelemetryProjectionDefinition,
|
|
10
|
+
} from "../projections/types"
|
|
11
|
+
import type { VersionClassification } from "./dataset-version-markings"
|
|
12
|
+
import { SecurityValidationError } from "./errors"
|
|
13
|
+
import type { ColumnMarkingOrigins, DatasetMarkings, MarkingOrigin } from "./marking-propagation"
|
|
14
|
+
|
|
15
|
+
type OntologyLookup = Pick<OntologyDefinitionCatalog, "getObjectTypeById">
|
|
16
|
+
|
|
17
|
+
/** Markings of one column of the projection's dataset. */
|
|
18
|
+
type ColumnMarkingsLookup = (column: string) => readonly string[]
|
|
19
|
+
|
|
20
|
+
/** What a marked key column makes unreadable: the objects it identifies, or the link it keys. */
|
|
21
|
+
export type ProjectionKeyTarget =
|
|
22
|
+
| { readonly kind: "type"; readonly objectTypeId: string }
|
|
23
|
+
| {
|
|
24
|
+
readonly kind: "link"
|
|
25
|
+
readonly objectTypeId: string
|
|
26
|
+
readonly linkId: string
|
|
27
|
+
readonly targetObjectTypeId: string
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/** A marking rule a projection breaks. */
|
|
31
|
+
type ProjectionMarkingViolation =
|
|
32
|
+
| {
|
|
33
|
+
readonly kind: "undeclared"
|
|
34
|
+
readonly property: string
|
|
35
|
+
readonly objectTypeId: string
|
|
36
|
+
readonly propertyId: string
|
|
37
|
+
readonly column: string
|
|
38
|
+
readonly missing: readonly string[]
|
|
39
|
+
}
|
|
40
|
+
| {
|
|
41
|
+
readonly kind: "markedKeyColumn"
|
|
42
|
+
readonly column: string
|
|
43
|
+
readonly role: string
|
|
44
|
+
readonly targets: readonly ProjectionKeyTarget[]
|
|
45
|
+
/** The property the column fills, when the key is a property. */
|
|
46
|
+
readonly property?: { readonly objectTypeId: string; readonly propertyId: string }
|
|
47
|
+
}
|
|
48
|
+
| { readonly kind: "markedKeyProperty"; readonly property: string; readonly role: string }
|
|
49
|
+
| { readonly kind: "telemetry"; readonly column: string }
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Objects are read through the ontology, so each projected property declares the markings of its
|
|
53
|
+
* column: the ontology stays the reviewed contract of what each reader receives. Values that
|
|
54
|
+
* identify objects or key links are returned wherever the object or link is, and telemetry does
|
|
55
|
+
* not enforce markings yet, so those columns cannot carry markings.
|
|
56
|
+
*
|
|
57
|
+
* Startup checks it with the markings columns declare or inherit through `run` steps, and the
|
|
58
|
+
* pipeline preflight with the markings SQL steps derive as well.
|
|
59
|
+
*/
|
|
60
|
+
export function validateProjectionMarkings(
|
|
61
|
+
projections: ProjectionDefinitionCatalog,
|
|
62
|
+
ontology: OntologyLookup,
|
|
63
|
+
markings: DatasetMarkings
|
|
64
|
+
): void {
|
|
65
|
+
const all = [
|
|
66
|
+
...projections.listObjects(),
|
|
67
|
+
...projections.listLinks(),
|
|
68
|
+
...projections.listTelemetry(),
|
|
69
|
+
]
|
|
70
|
+
|
|
71
|
+
for (const projection of all) {
|
|
72
|
+
const originsOf = (column: string) => markings.of({ datasetId: projection.datasetId, column })
|
|
73
|
+
const violation = firstViolation(projection, ontology, (column) => [
|
|
74
|
+
...originsOf(column).keys(),
|
|
75
|
+
])
|
|
76
|
+
if (!violation) continue
|
|
77
|
+
|
|
78
|
+
const carries = (column: string): CarriedMarkings => {
|
|
79
|
+
const origins = originsOf(column)
|
|
80
|
+
return {
|
|
81
|
+
text: describeOrigins(origins, `${projection.datasetId}.${column}`),
|
|
82
|
+
inherited: [...origins.values()].some((origin) => origin.steps.length > 0),
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
throw new SecurityValidationError(
|
|
87
|
+
violationMessage(
|
|
88
|
+
`[Sixb] Projection '${projection.id}'`,
|
|
89
|
+
projection.datasetId,
|
|
90
|
+
violation,
|
|
91
|
+
carries
|
|
92
|
+
)
|
|
93
|
+
)
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
/**
|
|
98
|
+
* Refuse to project a dataset version whose columns carry more markings than the projection
|
|
99
|
+
* allows. A version keeps the markings of the code that produced it, so a version written before
|
|
100
|
+
* the current code can carry markings startup did not see. Call it once per version, before
|
|
101
|
+
* reading its rows; it reads nothing, so what it throws is a refusal that no retry changes.
|
|
102
|
+
*/
|
|
103
|
+
export function assertProjectionVersionMarkings(input: {
|
|
104
|
+
readonly projection: ProjectionDefinition
|
|
105
|
+
readonly ontology: OntologyLookup
|
|
106
|
+
readonly version: DatasetVersion
|
|
107
|
+
readonly classification: VersionClassification
|
|
108
|
+
}): void {
|
|
109
|
+
const { projection, version, classification } = input
|
|
110
|
+
const markingsOf = (column: string) => [...(classification.columns.get(column) ?? [])].sort()
|
|
111
|
+
const violation = firstViolation(projection, input.ontology, markingsOf)
|
|
112
|
+
if (!violation) return
|
|
113
|
+
|
|
114
|
+
const subject = `[Sixb] Projection '${projection.id}' cannot read version '${version.versionId}' of dataset '${version.datasetId}'`
|
|
115
|
+
const carries = (column: string): CarriedMarkings => ({
|
|
116
|
+
text: `${markingList(markingsOf(column))} in this version`,
|
|
117
|
+
inherited: true,
|
|
118
|
+
})
|
|
119
|
+
const conservative =
|
|
120
|
+
classification.conservative === undefined
|
|
121
|
+
? ""
|
|
122
|
+
: ` The version was classified with every marking its sources could hold, because ${classification.conservative}.`
|
|
123
|
+
const rerun = `If the code that writes '${version.datasetId}' no longer derives these markings, rerun its pipeline.`
|
|
124
|
+
|
|
125
|
+
throw new Error(
|
|
126
|
+
`${violationMessage(subject, version.datasetId, violation, carries)}${conservative} ${rerun}`
|
|
127
|
+
)
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/** Markings an applied version gives a projection's targets beyond what the ontology declares. */
|
|
131
|
+
export interface ProjectionSurplus {
|
|
132
|
+
/** Markings a mapped column carries that its property does not declare. */
|
|
133
|
+
readonly properties: readonly {
|
|
134
|
+
readonly objectTypeId: string
|
|
135
|
+
readonly propertyId: string
|
|
136
|
+
readonly column: string
|
|
137
|
+
readonly markings: readonly string[]
|
|
138
|
+
}[]
|
|
139
|
+
/** Marked key columns, with what each one makes unreadable and why. */
|
|
140
|
+
readonly keys: readonly {
|
|
141
|
+
readonly target: ProjectionKeyTarget
|
|
142
|
+
readonly column: string
|
|
143
|
+
readonly role: string
|
|
144
|
+
readonly markings: readonly string[]
|
|
145
|
+
}[]
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* What a projection's targets carry beyond their declarations when read from columns with these
|
|
150
|
+
* markings: every rule it breaks, as markings to add to properties and to key targets. A property
|
|
151
|
+
* that keys a link keeps its markings on the property as well.
|
|
152
|
+
*/
|
|
153
|
+
export function projectionSurplus(
|
|
154
|
+
projection: ProjectionDefinition,
|
|
155
|
+
ontology: OntologyLookup,
|
|
156
|
+
markingsOf: ColumnMarkingsLookup
|
|
157
|
+
): ProjectionSurplus {
|
|
158
|
+
const properties: ProjectionSurplus["properties"][number][] = []
|
|
159
|
+
const keys: ProjectionSurplus["keys"][number][] = []
|
|
160
|
+
|
|
161
|
+
for (const violation of projectionMarkingViolations(projection, ontology, markingsOf)) {
|
|
162
|
+
switch (violation.kind) {
|
|
163
|
+
case "undeclared":
|
|
164
|
+
properties.push({
|
|
165
|
+
objectTypeId: violation.objectTypeId,
|
|
166
|
+
propertyId: violation.propertyId,
|
|
167
|
+
column: violation.column,
|
|
168
|
+
markings: violation.missing,
|
|
169
|
+
})
|
|
170
|
+
break
|
|
171
|
+
case "markedKeyColumn": {
|
|
172
|
+
const markings = markingsOf(violation.column)
|
|
173
|
+
for (const target of violation.targets) {
|
|
174
|
+
keys.push({ target, column: violation.column, role: violation.role, markings })
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const property = violation.property
|
|
178
|
+
if (property && violation.targets.some((target) => target.kind === "link")) {
|
|
179
|
+
properties.push({ ...property, column: violation.column, markings })
|
|
180
|
+
}
|
|
181
|
+
break
|
|
182
|
+
}
|
|
183
|
+
// Startup refuses a marked key property and a marked telemetry column from the code alone.
|
|
184
|
+
case "markedKeyProperty":
|
|
185
|
+
case "telemetry":
|
|
186
|
+
break
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
return { properties, keys }
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
// ── Rules ───────────────────────────────────────────────────
|
|
194
|
+
|
|
195
|
+
function firstViolation(
|
|
196
|
+
projection: ProjectionDefinition,
|
|
197
|
+
ontology: OntologyLookup,
|
|
198
|
+
markingsOf: ColumnMarkingsLookup
|
|
199
|
+
): ProjectionMarkingViolation | null {
|
|
200
|
+
const first = projectionMarkingViolations(projection, ontology, markingsOf).next()
|
|
201
|
+
return first.done ? null : first.value
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
/** Every marking rule the projection breaks, the first one being the one messages report. */
|
|
205
|
+
function* projectionMarkingViolations(
|
|
206
|
+
projection: ProjectionDefinition,
|
|
207
|
+
ontology: OntologyLookup,
|
|
208
|
+
markingsOf: ColumnMarkingsLookup
|
|
209
|
+
): Generator<ProjectionMarkingViolation> {
|
|
210
|
+
switch (projection._tag) {
|
|
211
|
+
case "ObjectProjectionDefinition": {
|
|
212
|
+
const objectType = ontology.getObjectTypeById(projection.objectTypeId)
|
|
213
|
+
if (objectType) yield* objectProjectionViolations(projection, objectType, markingsOf)
|
|
214
|
+
return
|
|
215
|
+
}
|
|
216
|
+
case "LinkProjectionDefinition":
|
|
217
|
+
yield* linkProjectionViolations(projection, markingsOf)
|
|
218
|
+
return
|
|
219
|
+
case "TelemetryProjectionDefinition":
|
|
220
|
+
yield* telemetryProjectionViolations(projection, markingsOf)
|
|
221
|
+
return
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function* objectProjectionViolations(
|
|
226
|
+
projection: ObjectProjectionDefinition,
|
|
227
|
+
objectType: ObjectType,
|
|
228
|
+
markingsOf: ColumnMarkingsLookup
|
|
229
|
+
): Generator<ProjectionMarkingViolation> {
|
|
230
|
+
const keyRoles = objectProjectionKeyRoles(projection, objectType)
|
|
231
|
+
|
|
232
|
+
for (const [propertyId, column] of Object.entries(projection.properties)) {
|
|
233
|
+
const property = objectType.properties.find((candidate) => candidate.id === propertyId)
|
|
234
|
+
const path = `${objectType.id}.${propertyId}`
|
|
235
|
+
const keyRole = keyRoles.get(propertyId)
|
|
236
|
+
|
|
237
|
+
if (keyRole) {
|
|
238
|
+
if (markingsOf(column).length > 0) {
|
|
239
|
+
yield {
|
|
240
|
+
kind: "markedKeyColumn",
|
|
241
|
+
column,
|
|
242
|
+
role: keyRole.role,
|
|
243
|
+
targets: keyRole.targets,
|
|
244
|
+
property: { objectTypeId: objectType.id, propertyId },
|
|
245
|
+
}
|
|
246
|
+
} else if (property?.markings) {
|
|
247
|
+
yield { kind: "markedKeyProperty", property: path, role: keyRole.role }
|
|
248
|
+
}
|
|
249
|
+
continue
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
const declared = new Set(property?.markings ?? [])
|
|
253
|
+
const missing = markingsOf(column).filter((markingId) => !declared.has(markingId))
|
|
254
|
+
if (missing.length > 0) {
|
|
255
|
+
yield {
|
|
256
|
+
kind: "undeclared",
|
|
257
|
+
property: path,
|
|
258
|
+
objectTypeId: objectType.id,
|
|
259
|
+
propertyId,
|
|
260
|
+
column,
|
|
261
|
+
missing,
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
for (const [linkId, link] of Object.entries(projection.links)) {
|
|
267
|
+
if (link.sourceField === undefined) continue
|
|
268
|
+
|
|
269
|
+
const role = `keys link '${objectType.id}.${linkId}'`
|
|
270
|
+
const target = linkTarget(objectType.id, linkId, link.targetObjectTypeId)
|
|
271
|
+
yield* markedKeyColumn(link.sourceField, role, [target], markingsOf)
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
// The timestamp decides whether the source value or an app edit wins, which reveals how they
|
|
275
|
+
// compare.
|
|
276
|
+
const conflictResolution = projection.conflictResolution
|
|
277
|
+
if (conflictResolution?.strategy === "mostRecent") {
|
|
278
|
+
const role = "decides which value wins under 'mostRecent'"
|
|
279
|
+
const target: ProjectionKeyTarget = { kind: "type", objectTypeId: objectType.id }
|
|
280
|
+
yield* markedKeyColumn(conflictResolution.sourceTimestamp, role, [target], markingsOf)
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
function* linkProjectionViolations(
|
|
285
|
+
projection: LinkProjectionDefinition,
|
|
286
|
+
markingsOf: ColumnMarkingsLookup
|
|
287
|
+
): Generator<ProjectionMarkingViolation> {
|
|
288
|
+
const role = `keys link '${projection.sourceObjectTypeId}.${projection.linkId}'`
|
|
289
|
+
const targets = [
|
|
290
|
+
linkTarget(projection.sourceObjectTypeId, projection.linkId, projection.targetObjectTypeId),
|
|
291
|
+
]
|
|
292
|
+
yield* markedKeyColumn(projection.sourceField, role, targets, markingsOf)
|
|
293
|
+
yield* markedKeyColumn(projection.targetField, role, targets, markingsOf)
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
function* telemetryProjectionViolations(
|
|
297
|
+
projection: TelemetryProjectionDefinition,
|
|
298
|
+
markingsOf: ColumnMarkingsLookup
|
|
299
|
+
): Generator<ProjectionMarkingViolation> {
|
|
300
|
+
const columns = [
|
|
301
|
+
projection.objectIdField,
|
|
302
|
+
projection.atField,
|
|
303
|
+
...Object.values(projection.properties).flatMap((mapping) =>
|
|
304
|
+
mapping.unitField === undefined
|
|
305
|
+
? [mapping.valueField]
|
|
306
|
+
: [mapping.valueField, mapping.unitField]
|
|
307
|
+
),
|
|
308
|
+
]
|
|
309
|
+
|
|
310
|
+
for (const column of columns) {
|
|
311
|
+
if (markingsOf(column).length > 0) yield { kind: "telemetry", column }
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
interface KeyRole {
|
|
316
|
+
readonly role: string
|
|
317
|
+
readonly targets: readonly ProjectionKeyTarget[]
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/** Properties whose value becomes an object id or a link key, with the role they play. */
|
|
321
|
+
function objectProjectionKeyRoles(
|
|
322
|
+
projection: ObjectProjectionDefinition,
|
|
323
|
+
objectType: ObjectType
|
|
324
|
+
): ReadonlyMap<string, KeyRole> {
|
|
325
|
+
const roles = new Map<string, KeyRole>()
|
|
326
|
+
|
|
327
|
+
for (const property of objectType.properties) {
|
|
328
|
+
if (!property.primary) continue
|
|
329
|
+
roles.set(property.id, {
|
|
330
|
+
role: `becomes the id of '${objectType.id}'`,
|
|
331
|
+
targets: [{ kind: "type", objectTypeId: objectType.id }],
|
|
332
|
+
})
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
for (const [linkId, link] of Object.entries(projection.links)) {
|
|
336
|
+
if (link.sourcePropertyId === undefined) continue
|
|
337
|
+
// An id that also keys a link plays both roles; messages name the link.
|
|
338
|
+
roles.set(link.sourcePropertyId, {
|
|
339
|
+
role: `keys link '${objectType.id}.${linkId}'`,
|
|
340
|
+
targets: [
|
|
341
|
+
...(roles.get(link.sourcePropertyId)?.targets ?? []),
|
|
342
|
+
linkTarget(objectType.id, linkId, link.targetObjectTypeId),
|
|
343
|
+
],
|
|
344
|
+
})
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
return roles
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
function linkTarget(
|
|
351
|
+
objectTypeId: string,
|
|
352
|
+
linkId: string,
|
|
353
|
+
targetObjectTypeId: string
|
|
354
|
+
): ProjectionKeyTarget {
|
|
355
|
+
return { kind: "link", objectTypeId, linkId, targetObjectTypeId }
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
function* markedKeyColumn(
|
|
359
|
+
column: string,
|
|
360
|
+
role: string,
|
|
361
|
+
targets: readonly ProjectionKeyTarget[],
|
|
362
|
+
markingsOf: ColumnMarkingsLookup
|
|
363
|
+
): Generator<ProjectionMarkingViolation> {
|
|
364
|
+
if (markingsOf(column).length > 0) yield { kind: "markedKeyColumn", column, role, targets }
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
// ── Messages ────────────────────────────────────────────────
|
|
368
|
+
|
|
369
|
+
/** What a column carries, for messages, and whether any of it comes from elsewhere. */
|
|
370
|
+
interface CarriedMarkings {
|
|
371
|
+
readonly text: string
|
|
372
|
+
readonly inherited: boolean
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
function violationMessage(
|
|
376
|
+
subject: string,
|
|
377
|
+
datasetId: string,
|
|
378
|
+
violation: ProjectionMarkingViolation,
|
|
379
|
+
carries: (column: string) => CarriedMarkings
|
|
380
|
+
): string {
|
|
381
|
+
const path = (column: string) => `${datasetId}.${column}`
|
|
382
|
+
|
|
383
|
+
switch (violation.kind) {
|
|
384
|
+
case "undeclared":
|
|
385
|
+
return `${subject}: property '${violation.property}' is projected from column '${path(violation.column)}', which carries ${carries(violation.column).text}. Add markings: ${markingList(violation.missing)} to the property.`
|
|
386
|
+
case "markedKeyColumn": {
|
|
387
|
+
const carried = carries(violation.column)
|
|
388
|
+
const inherited = carried.inherited ? `, but carries ${carried.text}` : ""
|
|
389
|
+
return `${subject}: column '${path(violation.column)}' ${violation.role} and cannot carry markings${inherited}.`
|
|
390
|
+
}
|
|
391
|
+
case "markedKeyProperty":
|
|
392
|
+
return `${subject}: property '${violation.property}' ${violation.role} and cannot carry markings.`
|
|
393
|
+
case "telemetry":
|
|
394
|
+
return `${subject}: column '${path(violation.column)}' carries ${carries(violation.column).text}, and telemetry projections cannot read marked columns yet.`
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* `[financial] from 'raw_invoices.amount' through step 'invoices/normalize'`: each marking with one
|
|
400
|
+
* path it arrived by. Markings the column declares itself have no path.
|
|
401
|
+
*/
|
|
402
|
+
export function describeOrigins(origins: ColumnMarkingOrigins, columnPath: string): string {
|
|
403
|
+
const groups = new Map<string, string[]>()
|
|
404
|
+
for (const [markingId, origin] of origins) {
|
|
405
|
+
const path = originPath(origin, columnPath)
|
|
406
|
+
groups.set(path, [...(groups.get(path) ?? []), markingId])
|
|
407
|
+
}
|
|
408
|
+
return [...groups].map(([path, markingIds]) => `${markingList(markingIds)}${path}`).join(" and ")
|
|
409
|
+
}
|
|
410
|
+
|
|
411
|
+
function originPath(origin: MarkingOrigin, columnPath: string): string {
|
|
412
|
+
const source = `${origin.column.datasetId}.${origin.column.column}`
|
|
413
|
+
if (origin.steps.length === 0 && source === columnPath) return ""
|
|
414
|
+
|
|
415
|
+
const steps = origin.steps.map((step) => `'${step}'`).join(", ")
|
|
416
|
+
return ` from '${source}' through ${origin.steps.length === 1 ? "step" : "steps"} ${steps}`
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
function markingList(markings: readonly string[]): string {
|
|
420
|
+
return `[${markings.join(", ")}]`
|
|
421
|
+
}
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import type { Redactions } from "./types"
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
const MISSING_CLEARANCE = Object.freeze({ reason: "missing_clearance" } as const)
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* List the values hidden from a reader that lacks a clearance for their markings. Deeply frozen,
|
|
7
|
+
* so every row and event redacted the same way can share it.
|
|
8
|
+
*/
|
|
4
9
|
export function missingClearanceRedactions(ids: Iterable<string>): Redactions {
|
|
5
|
-
return Object.fromEntries([...ids].map((id) => [id,
|
|
10
|
+
return Object.freeze(Object.fromEntries([...ids].map((id) => [id, MISSING_CLEARANCE] as const)))
|
|
6
11
|
}
|
package/src/security/types.ts
CHANGED
|
@@ -116,9 +116,27 @@ export interface AgentRunGrant {
|
|
|
116
116
|
readonly target: "agent"
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
-
export type ObserveGrantTarget = "logs" | "aiUsage"
|
|
119
|
+
export type ObserveGrantTarget = "logs" | "aiUsage" | "activity"
|
|
120
120
|
|
|
121
|
-
/**
|
|
121
|
+
/**
|
|
122
|
+
* Project-wide surfaces used in security grants such as `can.observe(project.logs)`. Each member's
|
|
123
|
+
* `kind` is the grant target it selects.
|
|
124
|
+
*/
|
|
125
|
+
export interface ProjectReference {
|
|
126
|
+
readonly kind: "project"
|
|
127
|
+
/** The project's captured logs. */
|
|
128
|
+
readonly logs: { readonly kind: "logs" }
|
|
129
|
+
/** Visits and page views recorded in the project's app. */
|
|
130
|
+
readonly activity: { readonly kind: "activity" }
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/** Any member of `project`, such as `project.logs`. */
|
|
134
|
+
export type ProjectSurfaceReference = ProjectReference[Exclude<keyof ProjectReference, "kind">]
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Read the project's logs, its AI usage or its app activity. Each is one surface, so there is
|
|
138
|
+
* nothing to select.
|
|
139
|
+
*/
|
|
122
140
|
export interface ObserveGrant {
|
|
123
141
|
readonly kind: "grant"
|
|
124
142
|
readonly capability: "observe"
|
|
@@ -251,16 +251,23 @@ export function assertGrantDefinition(
|
|
|
251
251
|
)
|
|
252
252
|
}
|
|
253
253
|
|
|
254
|
-
if (
|
|
255
|
-
|
|
254
|
+
if (
|
|
255
|
+
value.capability === "observe" &&
|
|
256
|
+
value.target !== "logs" &&
|
|
257
|
+
value.target !== "aiUsage" &&
|
|
258
|
+
value.target !== "activity"
|
|
259
|
+
) {
|
|
260
|
+
throw createError(
|
|
261
|
+
`[Sixb] ${field} observe grant target must be 'logs', 'aiUsage', or 'activity'.`
|
|
262
|
+
)
|
|
256
263
|
}
|
|
257
264
|
|
|
258
265
|
if (value.capability === "manage" && value.target !== "connector" && value.target !== "aiUsage") {
|
|
259
266
|
throw createError(`[Sixb] ${field} manage grant target must be 'connector' or 'aiUsage'.`)
|
|
260
267
|
}
|
|
261
268
|
|
|
262
|
-
// The agent, logs
|
|
263
|
-
// above settled the capability and target, so the kind is known.
|
|
269
|
+
// The agent, logs, AI usage and activity are one surface each, so their grants select nothing.
|
|
270
|
+
// The checks above settled the capability and target, so the kind is known.
|
|
264
271
|
if (isSingletonGrantKind(grantKindOf(value as unknown as GrantDefinition))) {
|
|
265
272
|
if (value.selection !== undefined) {
|
|
266
273
|
throw createError(
|