@sixb/core 0.1.19 → 0.1.20
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/index.js +24 -24
- package/dist/agents/index.js +25 -25
- package/dist/agents/index.js.map +1 -1
- package/dist/auth/cookies.d.ts +2 -4
- package/dist/auth/cookies.d.ts.map +1 -1
- package/dist/auth/index.d.ts +0 -2
- package/dist/auth/index.d.ts.map +1 -1
- package/dist/auth/index.js +8 -14
- package/dist/auth/index.js.map +1 -1
- package/dist/auth/runtime.d.ts +8 -10
- package/dist/auth/runtime.d.ts.map +1 -1
- package/dist/auth/session-cache.d.ts +1 -5
- package/dist/auth/session-cache.d.ts.map +1 -1
- package/dist/auth/strategy.js +1 -1
- package/dist/auth/types.d.ts +4 -8
- package/dist/auth/types.d.ts.map +1 -1
- package/dist/auth/validation.d.ts +0 -1
- package/dist/auth/validation.d.ts.map +1 -1
- package/dist/authorization/decision.d.ts +0 -4
- package/dist/authorization/decision.d.ts.map +1 -1
- package/dist/authorization/grant-kinds.d.ts +6 -8
- package/dist/authorization/grant-kinds.d.ts.map +1 -1
- package/dist/authorization/index.d.ts +0 -1
- package/dist/authorization/index.d.ts.map +1 -1
- package/dist/authorization/index.js +3 -7
- package/dist/authorization/index.js.map +1 -1
- package/dist/authorization/resolve.d.ts +1 -1
- package/dist/authorization/resolve.d.ts.map +1 -1
- package/dist/bootstrap/index.js +26 -26
- package/dist/{chunk-aff7cyea.js → chunk-0rbyz4qy.js} +21 -21
- package/dist/{chunk-aff7cyea.js.map → chunk-0rbyz4qy.js.map} +1 -1
- package/dist/{chunk-rz53yb4v.js → chunk-0yh890a4.js} +1 -1
- package/dist/{chunk-7mbzgd9m.js → chunk-1zq2p6g0.js} +1 -1
- package/dist/{chunk-dnmadg9k.js → chunk-3t2hgbgd.js} +2 -2
- package/dist/{chunk-wwdfe68s.js → chunk-4vyr1j8f.js} +2 -2
- package/dist/{chunk-kyzq4wy9.js → chunk-5j58wjct.js} +15 -15
- package/dist/chunk-5j58wjct.js.map +18 -0
- package/dist/{chunk-ey3pyej1.js → chunk-6c6sn0bh.js} +29 -24
- package/dist/{chunk-ey3pyej1.js.map → chunk-6c6sn0bh.js.map} +3 -3
- package/dist/{chunk-q1vkr2ys.js → chunk-6p49a5cq.js} +2 -2
- package/dist/{chunk-nre82s12.js → chunk-9dmt152s.js} +1 -1
- package/dist/{chunk-7kg3k1m9.js → chunk-9w055r5b.js} +1 -1
- package/dist/{chunk-4tcx876c.js → chunk-bx9q3cwv.js} +15 -15
- package/dist/{chunk-4tcx876c.js.map → chunk-bx9q3cwv.js.map} +1 -1
- package/dist/{chunk-bpgy64fw.js → chunk-d09tj99x.js} +1 -1
- package/dist/{chunk-y7rqfrgg.js → chunk-d0bqz29d.js} +23 -36
- package/dist/chunk-d0bqz29d.js.map +23 -0
- package/dist/{chunk-rhg02hxq.js → chunk-dk8tkk5f.js} +3 -3
- package/dist/{chunk-xt1zt7gv.js → chunk-es1gxsbf.js} +24 -15
- package/dist/chunk-es1gxsbf.js.map +13 -0
- package/dist/{chunk-52bk93x8.js → chunk-fkgc1wt8.js} +1 -1
- package/dist/{chunk-enpsx8k5.js → chunk-gsjm1wms.js} +16 -20
- package/dist/chunk-gsjm1wms.js.map +10 -0
- package/dist/{chunk-2jntasmh.js → chunk-hcbyfxbe.js} +25 -49
- package/dist/chunk-hcbyfxbe.js.map +12 -0
- package/dist/{chunk-zrmy8zvw.js → chunk-hjzdd750.js} +3 -3
- package/dist/chunk-hkc3jct7.js.map +1 -1
- package/dist/{chunk-85yvv5n0.js → chunk-k6q3n2sc.js} +3 -3
- package/dist/{chunk-j2bp5ryw.js → chunk-n33z5bjw.js} +11 -10
- package/dist/{chunk-j2bp5ryw.js.map → chunk-n33z5bjw.js.map} +3 -3
- package/dist/{chunk-80mc0971.js → chunk-ren4kg2j.js} +8 -8
- package/dist/{chunk-1f7wpmyp.js → chunk-rrzt8jdy.js} +2 -2
- package/dist/{chunk-6gmfggss.js → chunk-t7x8dmn0.js} +2 -2
- package/dist/{chunk-wz0xs816.js → chunk-tg2cw67r.js} +1 -1
- package/dist/{chunk-3gnrh4ve.js → chunk-vpq4shxz.js} +46 -106
- package/dist/chunk-vpq4shxz.js.map +39 -0
- package/dist/{chunk-bwjcehza.js → chunk-way52z4h.js} +1 -1
- package/dist/{chunk-tjb1mk5t.js → chunk-x6m907x7.js} +2 -2
- package/dist/{chunk-t6vq7bff.js → chunk-xfs8x8m9.js} +3 -3
- package/dist/{chunk-d2ync1v3.js → chunk-yevzdx4y.js} +3 -3
- package/dist/{chunk-kg5j6fct.js → chunk-z4m0yz8c.js} +1 -1
- package/dist/datasets/write.js +5 -5
- package/dist/deploy/internal.js +4 -3
- package/dist/deploy/internal.js.map +4 -4
- package/dist/deploy/services.d.ts.map +1 -1
- package/dist/deploy/types.d.ts +1 -2
- package/dist/deploy/types.d.ts.map +1 -1
- package/dist/execution/agent.js +24 -24
- package/dist/execution/authorization.d.ts.map +1 -1
- package/dist/execution/primitive.js +24 -24
- package/dist/execution/request.js +23 -23
- package/dist/index.d.ts +5 -5
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +33 -46
- package/dist/index.js.map +1 -1
- package/dist/lake-storage/index.js +5 -5
- package/dist/materializer/index.js +13 -13
- package/dist/models/execution/index.js +10 -10
- package/dist/objects/index.js +24 -24
- package/dist/objects/query/index.js +12 -12
- package/dist/objects/vectors/handle.d.ts.map +1 -1
- package/dist/objects/vectors/profile.d.ts +5 -0
- package/dist/objects/vectors/profile.d.ts.map +1 -1
- package/dist/ontology/index.js +3 -3
- package/dist/pipelines/index.js +15 -15
- package/dist/projections/internal.js +13 -13
- package/dist/runtime/internal.js +13 -13
- package/dist/security/builders.d.ts.map +1 -1
- package/dist/security/every.d.ts +1 -4
- package/dist/security/every.d.ts.map +1 -1
- package/dist/security/grants.d.ts +2 -4
- package/dist/security/grants.d.ts.map +1 -1
- package/dist/security/index.d.ts +1 -2
- package/dist/security/index.d.ts.map +1 -1
- package/dist/security/membership-policies.d.ts.map +1 -1
- package/dist/security/public.d.ts +10 -0
- package/dist/security/public.d.ts.map +1 -0
- package/dist/security/public.js +10 -0
- package/dist/security/public.js.map +9 -0
- package/dist/security/registry.d.ts +0 -1
- package/dist/security/registry.d.ts.map +1 -1
- package/dist/security/types.d.ts +13 -18
- package/dist/security/types.d.ts.map +1 -1
- package/dist/security/validation.d.ts +0 -6
- package/dist/security/validation.d.ts.map +1 -1
- package/dist/shares/internal.js +10 -10
- package/dist/storage/agents/types.d.ts +1 -1
- package/dist/storage/auth/in-memory/auth-storage.d.ts.map +1 -1
- package/dist/storage/auth/in-memory/magic-links.d.ts.map +1 -1
- package/dist/storage/auth/in-memory/oidc-attempts.d.ts.map +1 -1
- package/dist/storage/auth/in-memory/sessions.d.ts +0 -10
- package/dist/storage/auth/in-memory/sessions.d.ts.map +1 -1
- package/dist/storage/auth/in-memory/shared.d.ts +1 -2
- package/dist/storage/auth/in-memory/shared.d.ts.map +1 -1
- package/dist/storage/auth/types.d.ts +1 -17
- package/dist/storage/auth/types.d.ts.map +1 -1
- package/dist/storage/file-upload-sessions/provider.js +6 -6
- package/dist/storage/index.js +21 -21
- package/dist/storage/index.js.map +1 -1
- package/dist/storage/workflow-runs/provider.js +6 -6
- package/dist/syncs/index.js +16 -16
- package/dist/testing/auth-storage-contract.d.ts.map +1 -1
- package/dist/testing/index.js +41 -124
- package/dist/testing/index.js.map +4 -4
- package/dist/webhooks/internal.js +11 -11
- package/dist/workflows/index.js +25 -25
- package/package.json +8 -2
- package/src/auth/cookies.ts +3 -20
- package/src/auth/index.ts +0 -6
- package/src/auth/runtime.ts +59 -76
- package/src/auth/session-cache.ts +2 -9
- package/src/auth/types.ts +4 -8
- package/src/auth/validation.ts +0 -2
- package/src/authorization/decision.ts +8 -23
- package/src/authorization/grant-kinds.ts +20 -27
- package/src/authorization/index.ts +0 -1
- package/src/authorization/resolve.ts +10 -6
- package/src/deploy/services.ts +0 -1
- package/src/deploy/types.ts +1 -2
- package/src/deploy/validation.ts +3 -1
- package/src/execution/authorization.ts +11 -5
- package/src/index.ts +1 -14
- package/src/models/execution/embedding.ts +6 -6
- package/src/objects/vectors/README.md +4 -0
- package/src/objects/vectors/handle.ts +11 -2
- package/src/objects/vectors/indexing-generate.ts +2 -2
- package/src/objects/vectors/profile.ts +5 -0
- package/src/security/builders.ts +7 -2
- package/src/security/every.ts +0 -4
- package/src/security/grants.ts +5 -25
- package/src/security/index.ts +0 -3
- package/src/security/membership-policies.ts +3 -1
- package/src/security/public.ts +10 -0
- package/src/security/registry.ts +0 -8
- package/src/security/types.ts +19 -25
- package/src/security/validation.ts +19 -17
- package/src/storage/agents/types.ts +1 -1
- package/src/storage/auth/in-memory/auth-storage.ts +0 -18
- package/src/storage/auth/in-memory/magic-links.ts +0 -3
- package/src/storage/auth/in-memory/oidc-attempts.ts +0 -3
- package/src/storage/auth/in-memory/sessions.ts +1 -25
- package/src/storage/auth/in-memory/shared.ts +1 -10
- package/src/storage/auth/types.ts +2 -18
- package/src/testing/auth-storage-contract.ts +14 -107
- package/src/testing/execution-storage-contract.ts +0 -2
- package/dist/auth/audience.d.ts +0 -8
- package/dist/auth/audience.d.ts.map +0 -1
- package/dist/authorization/application-access.d.ts +0 -18
- package/dist/authorization/application-access.d.ts.map +0 -1
- package/dist/chunk-2jntasmh.js.map +0 -13
- package/dist/chunk-3gnrh4ve.js.map +0 -40
- package/dist/chunk-enpsx8k5.js.map +0 -10
- package/dist/chunk-kyzq4wy9.js.map +0 -18
- package/dist/chunk-xt1zt7gv.js.map +0 -13
- package/dist/chunk-y7rqfrgg.js.map +0 -24
- package/dist/security/applications.d.ts +0 -15
- package/dist/security/applications.d.ts.map +0 -1
- package/src/auth/audience.ts +0 -28
- package/src/authorization/application-access.ts +0 -34
- package/src/security/applications.ts +0 -11
- /package/dist/{chunk-rz53yb4v.js.map → chunk-0yh890a4.js.map} +0 -0
- /package/dist/{chunk-7mbzgd9m.js.map → chunk-1zq2p6g0.js.map} +0 -0
- /package/dist/{chunk-dnmadg9k.js.map → chunk-3t2hgbgd.js.map} +0 -0
- /package/dist/{chunk-wwdfe68s.js.map → chunk-4vyr1j8f.js.map} +0 -0
- /package/dist/{chunk-q1vkr2ys.js.map → chunk-6p49a5cq.js.map} +0 -0
- /package/dist/{chunk-nre82s12.js.map → chunk-9dmt152s.js.map} +0 -0
- /package/dist/{chunk-7kg3k1m9.js.map → chunk-9w055r5b.js.map} +0 -0
- /package/dist/{chunk-bpgy64fw.js.map → chunk-d09tj99x.js.map} +0 -0
- /package/dist/{chunk-rhg02hxq.js.map → chunk-dk8tkk5f.js.map} +0 -0
- /package/dist/{chunk-52bk93x8.js.map → chunk-fkgc1wt8.js.map} +0 -0
- /package/dist/{chunk-zrmy8zvw.js.map → chunk-hjzdd750.js.map} +0 -0
- /package/dist/{chunk-85yvv5n0.js.map → chunk-k6q3n2sc.js.map} +0 -0
- /package/dist/{chunk-80mc0971.js.map → chunk-ren4kg2j.js.map} +0 -0
- /package/dist/{chunk-1f7wpmyp.js.map → chunk-rrzt8jdy.js.map} +0 -0
- /package/dist/{chunk-6gmfggss.js.map → chunk-t7x8dmn0.js.map} +0 -0
- /package/dist/{chunk-wz0xs816.js.map → chunk-tg2cw67r.js.map} +0 -0
- /package/dist/{chunk-bwjcehza.js.map → chunk-way52z4h.js.map} +0 -0
- /package/dist/{chunk-tjb1mk5t.js.map → chunk-x6m907x7.js.map} +0 -0
- /package/dist/{chunk-t6vq7bff.js.map → chunk-xfs8x8m9.js.map} +0 -0
- /package/dist/{chunk-d2ync1v3.js.map → chunk-yevzdx4y.js.map} +0 -0
- /package/dist/{chunk-kg5j6fct.js.map → chunk-z4m0yz8c.js.map} +0 -0
package/src/auth/types.ts
CHANGED
|
@@ -11,7 +11,6 @@ import type {
|
|
|
11
11
|
SessionRecord,
|
|
12
12
|
UserRecord,
|
|
13
13
|
} from "../storage/auth"
|
|
14
|
-
import type { AuthSessionAudience, AuthSessionAudienceOptions } from "./audience"
|
|
15
14
|
|
|
16
15
|
export type Principal =
|
|
17
16
|
| { readonly type: "user"; readonly id: string }
|
|
@@ -63,7 +62,6 @@ export interface InvitationDeliveryInput {
|
|
|
63
62
|
readonly projectId: string
|
|
64
63
|
readonly authStorage: AuthStorage
|
|
65
64
|
readonly invitation: InvitationRecord
|
|
66
|
-
readonly audience: AuthSessionAudience
|
|
67
65
|
readonly returnTo: string
|
|
68
66
|
readonly requestOrigin: string
|
|
69
67
|
/** Return the delivered link once so the inviter can copy it through an approved channel. */
|
|
@@ -98,7 +96,6 @@ export interface MagicLinkRequestInput {
|
|
|
98
96
|
readonly projectId: string
|
|
99
97
|
readonly authStorage: AuthStorage
|
|
100
98
|
readonly email: string
|
|
101
|
-
readonly audience: AuthSessionAudience
|
|
102
99
|
readonly returnTo: string
|
|
103
100
|
readonly requestOrigin: string
|
|
104
101
|
/**
|
|
@@ -140,7 +137,6 @@ export interface MagicLinkCallbackInput {
|
|
|
140
137
|
}
|
|
141
138
|
|
|
142
139
|
export interface MagicLinkCallbackResult extends CompleteSignInResult {
|
|
143
|
-
readonly audience: AuthSessionAudience
|
|
144
140
|
readonly returnTo: string
|
|
145
141
|
}
|
|
146
142
|
|
|
@@ -182,7 +178,6 @@ export interface MagicLinkAuthStrategy extends InvitationDeliveryAuthStrategy {
|
|
|
182
178
|
export interface OidcStartSignInInput {
|
|
183
179
|
readonly projectId: string
|
|
184
180
|
readonly authStorage: AuthStorage
|
|
185
|
-
readonly audience: AuthSessionAudience
|
|
186
181
|
readonly returnTo: string
|
|
187
182
|
readonly requestOrigin: string
|
|
188
183
|
readonly now?: Date
|
|
@@ -208,7 +203,6 @@ export interface OidcCallbackInput {
|
|
|
208
203
|
}
|
|
209
204
|
|
|
210
205
|
export interface OidcCallbackResult extends CompleteSignInResult {
|
|
211
|
-
readonly audience: AuthSessionAudience
|
|
212
206
|
readonly returnTo: string
|
|
213
207
|
}
|
|
214
208
|
|
|
@@ -277,11 +271,14 @@ export interface MembershipOperationCapabilities {
|
|
|
277
271
|
readonly invite: boolean
|
|
278
272
|
readonly assignGroups: boolean
|
|
279
273
|
readonly suspend: boolean
|
|
274
|
+
readonly serviceAccounts: boolean
|
|
280
275
|
}
|
|
281
276
|
|
|
282
277
|
export interface GetMembershipOptionsResult {
|
|
283
278
|
/** Groups the caller may assign to a member (the `assignGroups` scope). */
|
|
284
279
|
readonly groups: readonly InvitationGroupOption[]
|
|
280
|
+
/** Groups the caller may place a service account in (the `serviceAccounts` scope). */
|
|
281
|
+
readonly serviceAccountGroups: readonly InvitationGroupOption[]
|
|
285
282
|
readonly capabilities: MembershipOperationCapabilities
|
|
286
283
|
}
|
|
287
284
|
|
|
@@ -377,7 +374,7 @@ export interface ReactivateMemberResult {
|
|
|
377
374
|
/** `"session"` reads only the cookie; `"any"` reads a bearer access token, else the cookie. */
|
|
378
375
|
export type AuthCredentialSource = "session" | "any"
|
|
379
376
|
|
|
380
|
-
export interface AuthSessionResolutionOptions
|
|
377
|
+
export interface AuthSessionResolutionOptions {
|
|
381
378
|
readonly credentialSource?: AuthCredentialSource
|
|
382
379
|
/** Marks this request as eligible to renew a near-expiry browser session. */
|
|
383
380
|
readonly sessionActivity?: "foreground"
|
|
@@ -385,7 +382,6 @@ export interface AuthSessionResolutionOptions extends AuthSessionAudienceOptions
|
|
|
385
382
|
|
|
386
383
|
/** Where an invitation link sends its recipient. */
|
|
387
384
|
export interface InvitationDestination {
|
|
388
|
-
readonly audience: AuthSessionAudience
|
|
389
385
|
readonly requestOrigin: string
|
|
390
386
|
readonly returnTo: string
|
|
391
387
|
}
|
package/src/auth/validation.ts
CHANGED
|
@@ -22,8 +22,6 @@ export const MAX_AUTH_INVITATION_TTL_MS = 30 * DAY
|
|
|
22
22
|
*/
|
|
23
23
|
export const DEFAULT_AUTH_SESSION_CACHE_TTL_MS = 5_000
|
|
24
24
|
|
|
25
|
-
export { resolveAuthSessionAudience } from "./audience"
|
|
26
|
-
|
|
27
25
|
export function resolveAuthConfig(config: SixbAuthConfig | undefined): ResolvedAuthConfig {
|
|
28
26
|
if (!config) {
|
|
29
27
|
return {
|
|
@@ -10,7 +10,6 @@
|
|
|
10
10
|
* is unrestricted.
|
|
11
11
|
*/
|
|
12
12
|
|
|
13
|
-
import type { AuthSessionAudience } from "../auth/audience"
|
|
14
13
|
import {
|
|
15
14
|
type ResolvedRuntimeAuthorization,
|
|
16
15
|
resolveExecutionScopeAuthorization,
|
|
@@ -18,12 +17,11 @@ import {
|
|
|
18
17
|
} from "../execution/authorization"
|
|
19
18
|
import type { ExecutionContext, RuntimeAuthorization } from "../execution/types"
|
|
20
19
|
import { AuthorizationError } from "./errors"
|
|
21
|
-
import type {
|
|
20
|
+
import type { SingletonGrantKind, TargetedGrantKind } from "./grant-kinds"
|
|
22
21
|
import type { AuthorizationContext, GrantIndex } from "./types"
|
|
23
22
|
|
|
24
23
|
/** Something a principal may attempt, paired with the resource it targets. */
|
|
25
24
|
export type AuthzRequest =
|
|
26
|
-
| { readonly kind: "application.access"; readonly audience: AuthSessionAudience }
|
|
27
25
|
| { readonly kind: "object.view"; readonly objectTypeId: string }
|
|
28
26
|
| { readonly kind: "dataset.view"; readonly datasetId: string }
|
|
29
27
|
| { readonly kind: "object.edit"; readonly objectTypeId: string }
|
|
@@ -59,13 +57,11 @@ interface AuthorizedRuntime {
|
|
|
59
57
|
// the two can never drift. `kind` is the resolved-index key, so enforcement is
|
|
60
58
|
// a direct lookup with no per-target dispatch.
|
|
61
59
|
type Atom =
|
|
62
|
-
| { readonly kind:
|
|
63
|
-
| { readonly kind:
|
|
60
|
+
| { readonly kind: SingletonGrantKind }
|
|
61
|
+
| { readonly kind: TargetedGrantKind; readonly id: string }
|
|
64
62
|
|
|
65
63
|
function atomsFor(request: AuthzRequest): readonly Atom[] {
|
|
66
64
|
switch (request.kind) {
|
|
67
|
-
case "application.access":
|
|
68
|
-
return [{ kind: "access:application", id: request.audience }]
|
|
69
65
|
case "object.view":
|
|
70
66
|
return [{ kind: "view:object", id: request.objectTypeId }]
|
|
71
67
|
case "dataset.view":
|
|
@@ -87,11 +83,11 @@ function atomsFor(request: AuthzRequest): readonly Atom[] {
|
|
|
87
83
|
case "agent.run":
|
|
88
84
|
return [{ kind: "run:agent" }]
|
|
89
85
|
case "logs.observe":
|
|
90
|
-
return [{ kind: "observe:logs"
|
|
86
|
+
return [{ kind: "observe:logs" }]
|
|
91
87
|
case "aiUsage.observe":
|
|
92
|
-
return [{ kind: "observe:aiUsage"
|
|
88
|
+
return [{ kind: "observe:aiUsage" }]
|
|
93
89
|
case "aiUsage.manage":
|
|
94
|
-
return [{ kind: "manage:aiUsage"
|
|
90
|
+
return [{ kind: "manage:aiUsage" }]
|
|
95
91
|
case "connector.manage":
|
|
96
92
|
return [{ kind: "manage:connector", id: request.connectorId }]
|
|
97
93
|
case "object.query":
|
|
@@ -100,20 +96,11 @@ function atomsFor(request: AuthzRequest): readonly Atom[] {
|
|
|
100
96
|
}
|
|
101
97
|
|
|
102
98
|
function atomKey(atom: Atom): string {
|
|
103
|
-
|
|
104
|
-
if (
|
|
105
|
-
atom.kind === "observe:logs" ||
|
|
106
|
-
atom.kind === "observe:aiUsage" ||
|
|
107
|
-
atom.kind === "manage:aiUsage"
|
|
108
|
-
) {
|
|
109
|
-
return atom.kind
|
|
110
|
-
}
|
|
111
|
-
return `${atom.kind}:${atom.id}`
|
|
99
|
+
return "id" in atom ? `${atom.kind}:${atom.id}` : atom.kind
|
|
112
100
|
}
|
|
113
101
|
|
|
114
102
|
function holds(grants: GrantIndex, atom: Atom): boolean {
|
|
115
|
-
|
|
116
|
-
return grants[atom.kind].has(atom.id)
|
|
103
|
+
return "id" in atom ? grants[atom.kind].has(atom.id) : grants[atom.kind]
|
|
117
104
|
}
|
|
118
105
|
|
|
119
106
|
/** Resolve a request against a principal's grants. Never throws. */
|
|
@@ -267,8 +254,6 @@ function deniedMessage(
|
|
|
267
254
|
): string {
|
|
268
255
|
const principalId = authorization?.principal.id ?? "unknown"
|
|
269
256
|
switch (request.kind) {
|
|
270
|
-
case "application.access":
|
|
271
|
-
return `[Sixb] Principal '${principalId}' is not allowed to access application '${request.audience}'.`
|
|
272
257
|
case "object.view":
|
|
273
258
|
return `[Sixb] Principal '${principalId}' is not allowed to view object type '${request.objectTypeId}'.`
|
|
274
259
|
case "dataset.view":
|
|
@@ -8,10 +8,9 @@
|
|
|
8
8
|
* entry in `GRANT_KINDS` plus the compile errors that forces at every consumer.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
import type {
|
|
11
|
+
import type { GrantDefinition } from "../security/types"
|
|
12
12
|
|
|
13
13
|
export type GrantKind =
|
|
14
|
-
| "access:application"
|
|
15
14
|
| "view:object"
|
|
16
15
|
| "view:dataset"
|
|
17
16
|
| "edit:object"
|
|
@@ -27,12 +26,12 @@ export type GrantKind =
|
|
|
27
26
|
| "manage:connector"
|
|
28
27
|
| "manage:aiUsage"
|
|
29
28
|
|
|
30
|
-
|
|
29
|
+
/** Capabilities over one project-wide surface: held or not, with no ids to select. */
|
|
30
|
+
export type SingletonGrantKind = "run:agent" | "observe:logs" | "observe:aiUsage" | "manage:aiUsage"
|
|
31
31
|
export type TargetedGrantKind = Exclude<GrantKind, SingletonGrantKind>
|
|
32
32
|
|
|
33
33
|
/** Registered id universes a grant kind ranges over, plus subtype expansion. */
|
|
34
34
|
export interface GrantUniverse {
|
|
35
|
-
readonly applicationIds: ReadonlySet<string>
|
|
36
35
|
readonly objectTypeIds: ReadonlySet<string>
|
|
37
36
|
readonly datasetIds: ReadonlySet<string>
|
|
38
37
|
readonly actionIds: ReadonlySet<string>
|
|
@@ -40,9 +39,7 @@ export interface GrantUniverse {
|
|
|
40
39
|
readonly workflowIds: ReadonlySet<string>
|
|
41
40
|
readonly syncIds: ReadonlySet<string>
|
|
42
41
|
readonly pipelineIds: ReadonlySet<string>
|
|
43
|
-
readonly observableIds: ReadonlySet<string>
|
|
44
42
|
readonly connectorIds: ReadonlySet<string>
|
|
45
|
-
readonly manageableIds: ReadonlySet<string>
|
|
46
43
|
readonly getSubTypes: (objectTypeId: string) => readonly string[]
|
|
47
44
|
}
|
|
48
45
|
|
|
@@ -76,11 +73,6 @@ export const GRANT_KINDS: {
|
|
|
76
73
|
? SingletonGrantKindSpec
|
|
77
74
|
: TargetedGrantKindSpec
|
|
78
75
|
} = {
|
|
79
|
-
"access:application": {
|
|
80
|
-
universeKey: "applicationIds",
|
|
81
|
-
subject: "application",
|
|
82
|
-
fix: "Use an application exported from '@sixb/core'.",
|
|
83
|
-
},
|
|
84
76
|
"view:object": {
|
|
85
77
|
universeKey: "objectTypeIds",
|
|
86
78
|
subject: "object type",
|
|
@@ -136,13 +128,13 @@ export const GRANT_KINDS: {
|
|
|
136
128
|
fix: "Configure models.language and use the exported agent reference in can.run(agent).",
|
|
137
129
|
},
|
|
138
130
|
"observe:logs": {
|
|
139
|
-
|
|
140
|
-
subject: "
|
|
131
|
+
singleton: true,
|
|
132
|
+
subject: "logs",
|
|
141
133
|
fix: 'Use can.observe("logs").',
|
|
142
134
|
},
|
|
143
135
|
"observe:aiUsage": {
|
|
144
|
-
|
|
145
|
-
subject: "
|
|
136
|
+
singleton: true,
|
|
137
|
+
subject: "AI usage",
|
|
146
138
|
fix: "Use can.observe(agent.usage).",
|
|
147
139
|
},
|
|
148
140
|
"manage:connector": {
|
|
@@ -151,25 +143,27 @@ export const GRANT_KINDS: {
|
|
|
151
143
|
fix: "Add it to 'connectors/' or pass it to createSixb({ connectors }).",
|
|
152
144
|
},
|
|
153
145
|
"manage:aiUsage": {
|
|
154
|
-
|
|
155
|
-
subject: "
|
|
146
|
+
singleton: true,
|
|
147
|
+
subject: "AI usage",
|
|
156
148
|
fix: "Use can.manage(agent.usage).",
|
|
157
149
|
},
|
|
158
150
|
}
|
|
159
151
|
|
|
160
152
|
export const GRANT_KIND_KEYS = Object.keys(GRANT_KINDS) as readonly GrantKind[]
|
|
153
|
+
export const SINGLETON_GRANT_KIND_KEYS = GRANT_KIND_KEYS.filter(
|
|
154
|
+
(kind): kind is SingletonGrantKind => "singleton" in GRANT_KINDS[kind]
|
|
155
|
+
)
|
|
161
156
|
export const TARGETED_GRANT_KIND_KEYS = GRANT_KIND_KEYS.filter(
|
|
162
|
-
(kind): kind is TargetedGrantKind =>
|
|
157
|
+
(kind): kind is TargetedGrantKind => !("singleton" in GRANT_KINDS[kind])
|
|
163
158
|
)
|
|
164
159
|
|
|
160
|
+
export function isSingletonGrantKind(kind: GrantKind): kind is SingletonGrantKind {
|
|
161
|
+
return "singleton" in GRANT_KINDS[kind]
|
|
162
|
+
}
|
|
163
|
+
|
|
165
164
|
/** The grant kind a stored grant resolves to. */
|
|
166
|
-
export function grantKindOf(grant: AgentRunGrant): SingletonGrantKind
|
|
167
|
-
export function grantKindOf(grant: Exclude<GrantDefinition, AgentRunGrant>): TargetedGrantKind
|
|
168
|
-
export function grantKindOf(grant: GrantDefinition): GrantKind
|
|
169
165
|
export function grantKindOf(grant: GrantDefinition): GrantKind {
|
|
170
166
|
switch (grant.capability) {
|
|
171
|
-
case "access":
|
|
172
|
-
return "access:application"
|
|
173
167
|
case "view":
|
|
174
168
|
return `view:${grant.target}`
|
|
175
169
|
case "edit":
|
|
@@ -196,7 +190,6 @@ export type MutableGrantIndex = {
|
|
|
196
190
|
|
|
197
191
|
export function emptyGrantSets(): MutableGrantIndex {
|
|
198
192
|
return {
|
|
199
|
-
"access:application": new Set(),
|
|
200
193
|
"view:object": new Set(),
|
|
201
194
|
"view:dataset": new Set(),
|
|
202
195
|
"edit:object": new Set(),
|
|
@@ -207,9 +200,9 @@ export function emptyGrantSets(): MutableGrantIndex {
|
|
|
207
200
|
"run:sync": new Set(),
|
|
208
201
|
"run:pipeline": new Set(),
|
|
209
202
|
"run:agent": false,
|
|
210
|
-
"observe:logs":
|
|
211
|
-
"observe:aiUsage":
|
|
203
|
+
"observe:logs": false,
|
|
204
|
+
"observe:aiUsage": false,
|
|
212
205
|
"manage:connector": new Set(),
|
|
213
|
-
"manage:aiUsage":
|
|
206
|
+
"manage:aiUsage": false,
|
|
214
207
|
}
|
|
215
208
|
}
|
|
@@ -5,6 +5,8 @@ import {
|
|
|
5
5
|
GRANT_KINDS,
|
|
6
6
|
type GrantUniverse,
|
|
7
7
|
grantKindOf,
|
|
8
|
+
isSingletonGrantKind,
|
|
9
|
+
SINGLETON_GRANT_KIND_KEYS,
|
|
8
10
|
TARGETED_GRANT_KIND_KEYS,
|
|
9
11
|
} from "./grant-kinds"
|
|
10
12
|
import type { AuthorizationContext, GrantIndex, ResolvedRole } from "./types"
|
|
@@ -14,7 +16,7 @@ import type { AuthorizationContext, GrantIndex, ResolvedRole } from "./types"
|
|
|
14
16
|
*
|
|
15
17
|
* Broad grants (`every.object().except([...])`) expand against the registered
|
|
16
18
|
* universe; object-type grants also expand to subtypes. Resource grants become
|
|
17
|
-
* id sets;
|
|
19
|
+
* id sets; grants on one project-wide surface (the Agent, logs, AI usage) become booleans.
|
|
18
20
|
* The per-kind universe and subtype rules come from the `GRANT_KINDS` table, so
|
|
19
21
|
* this loop never enumerates targets by hand.
|
|
20
22
|
*/
|
|
@@ -22,11 +24,13 @@ export function resolveRoleGrants(role: RoleDefinition, universe: GrantUniverse)
|
|
|
22
24
|
const grants = emptyGrantSets()
|
|
23
25
|
|
|
24
26
|
for (const grant of role.grants) {
|
|
25
|
-
|
|
26
|
-
|
|
27
|
+
const kind = grantKindOf(grant)
|
|
28
|
+
if (isSingletonGrantKind(kind)) {
|
|
29
|
+
grants[kind] = true
|
|
27
30
|
continue
|
|
28
31
|
}
|
|
29
|
-
|
|
32
|
+
// Every other kind carries a selection; this narrows the grant's type to say so.
|
|
33
|
+
if (!("selection" in grant)) continue
|
|
30
34
|
const spec = GRANT_KINDS[kind]
|
|
31
35
|
expandSelection(
|
|
32
36
|
grant.selection,
|
|
@@ -89,8 +93,8 @@ export function resolveAuthorizationContext(input: {
|
|
|
89
93
|
}
|
|
90
94
|
|
|
91
95
|
roleIds.push(role.id)
|
|
92
|
-
|
|
93
|
-
grants[
|
|
96
|
+
for (const kind of SINGLETON_GRANT_KIND_KEYS) {
|
|
97
|
+
if (role.grants[kind]) grants[kind] = true
|
|
94
98
|
}
|
|
95
99
|
for (const kind of TARGETED_GRANT_KIND_KEYS) {
|
|
96
100
|
for (const id of role.grants[kind]) {
|
package/src/deploy/services.ts
CHANGED
package/src/deploy/types.ts
CHANGED
|
@@ -29,7 +29,7 @@ export interface DeployConfig {
|
|
|
29
29
|
export type DeployEnv = Readonly<Record<string, string>>
|
|
30
30
|
|
|
31
31
|
/** The services a browser or client reaches through a public domain. */
|
|
32
|
-
export type DeployHttpServiceName = "api" | "
|
|
32
|
+
export type DeployHttpServiceName = "api" | "app"
|
|
33
33
|
|
|
34
34
|
/** The services that must run as exactly one process: a second would duplicate their work. */
|
|
35
35
|
export type DeploySingletonServiceName = "orchestrator" | "scheduler" | "rules"
|
|
@@ -40,7 +40,6 @@ export type DeployWorkerType = "sync" | "agent" | "pipeline" | "projection" | "w
|
|
|
40
40
|
|
|
41
41
|
export interface DeployServicesConfig {
|
|
42
42
|
readonly api?: boolean | DeployHttpServiceConfig
|
|
43
|
-
readonly atlas?: boolean | DeployHttpServiceConfig
|
|
44
43
|
readonly app?: boolean | DeployHttpServiceConfig
|
|
45
44
|
readonly orchestrator?: boolean | DeploySingletonServiceConfig
|
|
46
45
|
readonly scheduler?: boolean | DeploySingletonServiceConfig
|
package/src/deploy/validation.ts
CHANGED
|
@@ -55,7 +55,9 @@ function target(value: unknown): void {
|
|
|
55
55
|
|
|
56
56
|
function services(value: unknown): void {
|
|
57
57
|
const config = record(value, "services")
|
|
58
|
-
knownKeys(config, DEPLOY_SERVICES, "services"
|
|
58
|
+
knownKeys(config, DEPLOY_SERVICES, "services", {
|
|
59
|
+
atlas: "Atlas's pages are part of the app now; remove the setting and configure `app`.",
|
|
60
|
+
})
|
|
59
61
|
|
|
60
62
|
for (const service of DEPLOY_SERVICES) {
|
|
61
63
|
const override = config[service]
|
|
@@ -1,7 +1,12 @@
|
|
|
1
1
|
import { isDeepStrictEqual } from "node:util"
|
|
2
2
|
import { agentServiceAccountId } from "../agents/identity"
|
|
3
3
|
import type { Principal } from "../auth"
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
SINGLETON_GRANT_KIND_KEYS,
|
|
6
|
+
type SingletonGrantKind,
|
|
7
|
+
TARGETED_GRANT_KIND_KEYS,
|
|
8
|
+
type TargetedGrantKind,
|
|
9
|
+
} from "../authorization/grant-kinds"
|
|
5
10
|
import type { AuthorizationContext, GrantIndex } from "../authorization/types"
|
|
6
11
|
import { createSixbError } from "../errors/internal"
|
|
7
12
|
import type { ObjectRef } from "../ontology"
|
|
@@ -586,10 +591,11 @@ function snapshotAuthorizationContext(
|
|
|
586
591
|
for (const kind of TARGETED_GRANT_KIND_KEYS) {
|
|
587
592
|
grants[kind] = new ImmutableGrantSet(context.grants[kind])
|
|
588
593
|
}
|
|
589
|
-
const
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
}
|
|
594
|
+
const singletons = {} as Record<SingletonGrantKind, boolean>
|
|
595
|
+
for (const kind of SINGLETON_GRANT_KIND_KEYS) {
|
|
596
|
+
singletons[kind] = context.grants[kind]
|
|
597
|
+
}
|
|
598
|
+
const frozenGrants: GrantIndex = Object.freeze({ ...grants, ...singletons })
|
|
593
599
|
return Object.freeze({
|
|
594
600
|
principal,
|
|
595
601
|
...(context.sessionId === undefined ? {} : { sessionId: context.sessionId }),
|
package/src/index.ts
CHANGED
|
@@ -391,8 +391,6 @@ export {
|
|
|
391
391
|
|
|
392
392
|
export type {
|
|
393
393
|
AuthCookieOptions,
|
|
394
|
-
AuthSessionAudience,
|
|
395
|
-
AuthSessionAudienceOptions,
|
|
396
394
|
AuthSessionOptions,
|
|
397
395
|
AuthStrategy,
|
|
398
396
|
AuthStrategyKind,
|
|
@@ -401,22 +399,14 @@ export type {
|
|
|
401
399
|
Principal,
|
|
402
400
|
SixbAuthConfig,
|
|
403
401
|
} from "./auth"
|
|
404
|
-
export {
|
|
405
|
-
DEFAULT_AUTH_SESSION_AUDIENCE,
|
|
406
|
-
isValidAuthSessionAudience,
|
|
407
|
-
principalsEqual,
|
|
408
|
-
resolveAuthSessionAudience,
|
|
409
|
-
SYSTEM_PRINCIPAL,
|
|
410
|
-
} from "./auth"
|
|
402
|
+
export { principalsEqual, SYSTEM_PRINCIPAL } from "./auth"
|
|
411
403
|
|
|
412
404
|
// ── Authorization ──────────────────────────────────────────
|
|
413
405
|
|
|
414
406
|
export type { AuthorizationContext, GrantIndex, GrantKind } from "./authorization"
|
|
415
407
|
export {
|
|
416
408
|
AuthorizationError,
|
|
417
|
-
canAccessApplication,
|
|
418
409
|
isAllowed,
|
|
419
|
-
isApplicationAccessControlled,
|
|
420
410
|
resolveAuthorizationContext,
|
|
421
411
|
} from "./authorization"
|
|
422
412
|
|
|
@@ -440,10 +430,8 @@ export type {
|
|
|
440
430
|
// ── Security Definitions ───────────────────────────────────
|
|
441
431
|
|
|
442
432
|
export type {
|
|
443
|
-
AccessGrant,
|
|
444
433
|
AgentRunGrant,
|
|
445
434
|
AppendGrant,
|
|
446
|
-
ApplicationDefinition,
|
|
447
435
|
ApplyGrant,
|
|
448
436
|
BreadthSelector,
|
|
449
437
|
BreadthTarget,
|
|
@@ -476,7 +464,6 @@ export type {
|
|
|
476
464
|
ViewGrantTarget,
|
|
477
465
|
} from "./security"
|
|
478
466
|
export {
|
|
479
|
-
applications,
|
|
480
467
|
can,
|
|
481
468
|
defineGroup,
|
|
482
469
|
defineMarking,
|
|
@@ -58,9 +58,9 @@ async function executeEmbedding(
|
|
|
58
58
|
if (purpose !== undefined && purpose !== "document" && purpose !== "query") {
|
|
59
59
|
throw new TypeError("[SixbModels] Embedding purpose must be 'document' or 'query'.")
|
|
60
60
|
}
|
|
61
|
+
// The caller owns the deadline: only it knows whether anyone is waiting for the result.
|
|
61
62
|
const signal = session.signal(input.signal)
|
|
62
|
-
|
|
63
|
-
requestSignal.throwIfAborted()
|
|
63
|
+
signal.throwIfAborted()
|
|
64
64
|
if (!texts.length) return { vectors: [] }
|
|
65
65
|
|
|
66
66
|
const accounting = await session.accounting()
|
|
@@ -72,7 +72,7 @@ async function executeEmbedding(
|
|
|
72
72
|
"[SixbModels] Resolved embedding model identity does not match the selected model."
|
|
73
73
|
)
|
|
74
74
|
}
|
|
75
|
-
|
|
75
|
+
signal.throwIfAborted()
|
|
76
76
|
const callId = `call_${randomUUID()}`
|
|
77
77
|
const tokens = texts.reduce(
|
|
78
78
|
(sum, text) => sum + Math.ceil(new TextEncoder().encode(text).byteLength / 4),
|
|
@@ -92,8 +92,8 @@ async function executeEmbedding(
|
|
|
92
92
|
|
|
93
93
|
let result: EmbeddingModelResult
|
|
94
94
|
try {
|
|
95
|
-
|
|
96
|
-
result = await model.embed({ texts, purpose, signal
|
|
95
|
+
signal.throwIfAborted()
|
|
96
|
+
result = await model.embed({ texts, purpose, signal })
|
|
97
97
|
} catch (error) {
|
|
98
98
|
if (error instanceof EmbeddingModelResponseError) {
|
|
99
99
|
await recordEmbedding(accounting, model, callId, error.metadata)
|
|
@@ -105,7 +105,7 @@ async function executeEmbedding(
|
|
|
105
105
|
}
|
|
106
106
|
// Account before cancellation, vector validation or the materializer's optimistic write.
|
|
107
107
|
await recordEmbedding(accounting, model, callId, result ?? {})
|
|
108
|
-
|
|
108
|
+
signal.throwIfAborted()
|
|
109
109
|
return result
|
|
110
110
|
}
|
|
111
111
|
|
|
@@ -5,6 +5,10 @@ A named profile identifies a derived representation, separate from object proper
|
|
|
5
5
|
Indexing sends embedding purpose `document`; search sends `query`. The execution wrapper preserves
|
|
6
6
|
that role through model resolution, admission and accounting. Symmetric providers may ignore it.
|
|
7
7
|
|
|
8
|
+
Each caller sets its own deadline; the execution wrapper adds none. A search has someone waiting
|
|
9
|
+
and gives up after 30 seconds. Indexing, automatic or explicit, waits five minutes: the provider
|
|
10
|
+
bills a call whose response is abandoned, and an abandoned automatic call is a terminal failure.
|
|
11
|
+
|
|
8
12
|
Vector candidates may come from filters, traversals, explicit refs or set operations. Canonical
|
|
9
13
|
validation requires one concrete result type and admits every intermediate type, edge and source
|
|
10
14
|
property. Model lookup uses that resolved result type, not the query's initial type. SQL ranks the
|
|
@@ -6,7 +6,12 @@ import type { PreparedObjectVector } from "../../materialization/vectors"
|
|
|
6
6
|
import { sameEmbeddingModel } from "../../models/embedding-model"
|
|
7
7
|
import { getOntologyMutationRuntime } from "../../runtime/ontology-mutations"
|
|
8
8
|
import type { ExecutionObjectContext } from "../context"
|
|
9
|
-
import {
|
|
9
|
+
import {
|
|
10
|
+
INDEXING_EMBEDDING_TIMEOUT_MS,
|
|
11
|
+
normalizeVector,
|
|
12
|
+
vectorConfiguration,
|
|
13
|
+
vectorSources,
|
|
14
|
+
} from "./profile"
|
|
10
15
|
import type { ObjectVectorHandle } from "./types"
|
|
11
16
|
|
|
12
17
|
export function createObjectVectorHandle(
|
|
@@ -65,7 +70,11 @@ export function createObjectVectorHandle(
|
|
|
65
70
|
}
|
|
66
71
|
|
|
67
72
|
// Network work never holds a storage transaction or retries an obsolete computation.
|
|
68
|
-
const result = await model.embed({
|
|
73
|
+
const result = await model.embed({
|
|
74
|
+
texts: [input.text],
|
|
75
|
+
purpose: "document",
|
|
76
|
+
signal: AbortSignal.timeout(INDEXING_EMBEDDING_TIMEOUT_MS),
|
|
77
|
+
})
|
|
69
78
|
if (!Array.isArray(result?.vectors) || result.vectors.length !== 1) {
|
|
70
79
|
throw new MaterializationValidationError(
|
|
71
80
|
"Embedding model must return exactly one vector for one input text."
|
|
@@ -11,7 +11,7 @@ import { ModelExecutionSession } from "../../models/execution/session"
|
|
|
11
11
|
import type { SixbHostContext } from "../../runtime/types"
|
|
12
12
|
import type { VectorIndexingWork } from "../../storage/ontology/vector-indexing"
|
|
13
13
|
import { fail, retryAt, VectorIndexingDeferred } from "./indexing-shared"
|
|
14
|
-
import { normalizeVector } from "./profile"
|
|
14
|
+
import { INDEXING_EMBEDDING_TIMEOUT_MS, normalizeVector } from "./profile"
|
|
15
15
|
|
|
16
16
|
export interface PreparedIndexingWork {
|
|
17
17
|
readonly work: VectorIndexingWork
|
|
@@ -66,7 +66,7 @@ export async function generateVectors(
|
|
|
66
66
|
const result = await model.embed({
|
|
67
67
|
texts: entries.map((entry) => entry.input.text),
|
|
68
68
|
purpose: "document",
|
|
69
|
-
signal,
|
|
69
|
+
signal: AbortSignal.any([signal, AbortSignal.timeout(INDEXING_EMBEDDING_TIMEOUT_MS)]),
|
|
70
70
|
})
|
|
71
71
|
const values = normalizeEmbeddingResult(
|
|
72
72
|
result,
|
|
@@ -4,6 +4,11 @@ import type { ObjectVectorSearchProfile } from "../../ontology/types"
|
|
|
4
4
|
|
|
5
5
|
export const MAX_VECTOR_K = 1000
|
|
6
6
|
export const VECTOR_INPUT_VERSION = 1
|
|
7
|
+
/**
|
|
8
|
+
* Nobody waits on indexing, and the provider bills a call whose response is abandoned. The
|
|
9
|
+
* deadline only frees the worker from a dead connection, so it is far longer than a search's.
|
|
10
|
+
*/
|
|
11
|
+
export const INDEXING_EMBEDDING_TIMEOUT_MS = 5 * 60_000
|
|
7
12
|
|
|
8
13
|
export function vectorConfiguration(profile: ObjectVectorSearchProfile): string {
|
|
9
14
|
return sha256Canonical({
|
package/src/security/builders.ts
CHANGED
|
@@ -39,7 +39,12 @@ export interface DefineMembershipPolicyOptions {
|
|
|
39
39
|
readonly can: readonly MembershipOperation[]
|
|
40
40
|
}
|
|
41
41
|
|
|
42
|
-
const MEMBERSHIP_OPERATIONS = new Set<MembershipOperation>([
|
|
42
|
+
const MEMBERSHIP_OPERATIONS = new Set<MembershipOperation>([
|
|
43
|
+
"invite",
|
|
44
|
+
"assignGroups",
|
|
45
|
+
"suspend",
|
|
46
|
+
"serviceAccounts",
|
|
47
|
+
])
|
|
43
48
|
|
|
44
49
|
function assertNonEmptyArray<T>(value: readonly T[], field: string): void {
|
|
45
50
|
if (value.length === 0) {
|
|
@@ -65,7 +70,7 @@ function membershipOperationsFrom(
|
|
|
65
70
|
return operations.map((operation) => {
|
|
66
71
|
if (!MEMBERSHIP_OPERATIONS.has(operation)) {
|
|
67
72
|
throw new SecurityValidationError(
|
|
68
|
-
`[Sixb] ${field} must contain only membership operations: invite, assignGroups, suspend.`
|
|
73
|
+
`[Sixb] ${field} must contain only membership operations: invite, assignGroups, suspend, serviceAccounts.`
|
|
69
74
|
)
|
|
70
75
|
}
|
|
71
76
|
|
package/src/security/every.ts
CHANGED
|
@@ -20,7 +20,6 @@ import type { ShareDefinition } from "../shares"
|
|
|
20
20
|
import type { SyncDefinition } from "../syncs"
|
|
21
21
|
import type { WorkflowDefinition } from "../workflows/types"
|
|
22
22
|
import { SecurityValidationError } from "./errors"
|
|
23
|
-
import type { ApplicationDefinition } from "./types"
|
|
24
23
|
|
|
25
24
|
/** Capability targets a breadth selector can range over. */
|
|
26
25
|
export const BREADTH_TARGETS = [
|
|
@@ -30,7 +29,6 @@ export const BREADTH_TARGETS = [
|
|
|
30
29
|
"workflow",
|
|
31
30
|
"sync",
|
|
32
31
|
"pipeline",
|
|
33
|
-
"application",
|
|
34
32
|
"connector",
|
|
35
33
|
"share",
|
|
36
34
|
] as const
|
|
@@ -44,7 +42,6 @@ interface BreadthTargetInput {
|
|
|
44
42
|
workflow: WorkflowDefinition
|
|
45
43
|
sync: SyncDefinition
|
|
46
44
|
pipeline: PipelineDefinition
|
|
47
|
-
application: ApplicationDefinition
|
|
48
45
|
connector: ConnectorDefinition
|
|
49
46
|
share: ShareDefinition
|
|
50
47
|
}
|
|
@@ -106,7 +103,6 @@ export const every = {
|
|
|
106
103
|
workflow: (): BreadthSelector<"workflow"> => all("workflow"),
|
|
107
104
|
sync: (): BreadthSelector<"sync"> => all("sync"),
|
|
108
105
|
pipeline: (): BreadthSelector<"pipeline"> => all("pipeline"),
|
|
109
|
-
application: (): BreadthSelector<"application"> => all("application"),
|
|
110
106
|
connector: (): BreadthSelector<"connector"> => all("connector"),
|
|
111
107
|
share: (): BreadthSelector<"share"> => all("share"),
|
|
112
108
|
}
|