@inkeep/agents-core 0.68.4 → 0.70.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/dist/auth/auth-schema.d.ts +163 -163
  2. package/dist/auth/auth-validation-schemas.d.ts +154 -154
  3. package/dist/auth/auth.d.ts +9 -9
  4. package/dist/auth/authz/config.d.ts +33 -7
  5. package/dist/auth/authz/config.js +18 -8
  6. package/dist/auth/authz/credential-gateway.d.ts +57 -0
  7. package/dist/auth/authz/credential-gateway.js +118 -0
  8. package/dist/auth/authz/index.d.ts +4 -3
  9. package/dist/auth/authz/index.js +4 -3
  10. package/dist/auth/authz/types.d.ts +8 -1
  11. package/dist/auth/authz/types.js +7 -3
  12. package/dist/auth/entitlement-lock.js +2 -4
  13. package/dist/auth/entitlements.js +1 -1
  14. package/dist/auth/permissions.d.ts +13 -13
  15. package/dist/auth/support-copilot-platforms.d.ts +147 -0
  16. package/dist/auth/support-copilot-platforms.js +120 -0
  17. package/dist/client-exports.d.ts +3 -2
  18. package/dist/client-exports.js +3 -2
  19. package/dist/constants/allowed-file-formats.d.ts +6 -1
  20. package/dist/constants/allowed-file-formats.js +256 -24
  21. package/dist/constants/index.d.ts +2 -2
  22. package/dist/constants/index.js +2 -2
  23. package/dist/constants/signoz-queries.d.ts +1 -0
  24. package/dist/constants/signoz-queries.js +2 -1
  25. package/dist/context/TemplateEngine.d.ts +17 -1
  26. package/dist/context/TemplateEngine.js +37 -3
  27. package/dist/data-access/index.d.ts +2 -2
  28. package/dist/data-access/index.js +2 -2
  29. package/dist/data-access/manage/agents.d.ts +21 -21
  30. package/dist/data-access/manage/artifactComponents.d.ts +8 -8
  31. package/dist/data-access/manage/contextConfigs.d.ts +8 -8
  32. package/dist/data-access/manage/dataComponents.d.ts +2 -2
  33. package/dist/data-access/manage/functionTools.d.ts +10 -10
  34. package/dist/data-access/manage/skills.d.ts +10 -10
  35. package/dist/data-access/manage/subAgentExternalAgentRelations.d.ts +12 -12
  36. package/dist/data-access/manage/subAgentRelations.d.ts +16 -16
  37. package/dist/data-access/manage/subAgentTeamAgentRelations.d.ts +12 -12
  38. package/dist/data-access/manage/subAgents.d.ts +15 -15
  39. package/dist/data-access/manage/tools.d.ts +15 -15
  40. package/dist/data-access/manage/triggers.d.ts +1 -1
  41. package/dist/data-access/runtime/apiKeys.d.ts +12 -12
  42. package/dist/data-access/runtime/apps.d.ts +35 -11
  43. package/dist/data-access/runtime/conversations.d.ts +12 -12
  44. package/dist/data-access/runtime/entitlements.d.ts +2 -1
  45. package/dist/data-access/runtime/entitlements.js +5 -1
  46. package/dist/data-access/runtime/feedback.d.ts +6 -6
  47. package/dist/data-access/runtime/messages.d.ts +6 -6
  48. package/dist/data-access/runtime/scheduledTriggerUsers.d.ts +1 -1
  49. package/dist/data-access/runtime/tasks.d.ts +3 -3
  50. package/dist/db/runtime/runtime-schema.d.ts +395 -379
  51. package/dist/index.d.ts +7 -5
  52. package/dist/index.js +7 -5
  53. package/dist/middleware/no-auth.d.ts +2 -2
  54. package/dist/node_modules/.pnpm/{vitest@3.2.4_@edge-runtime_vm@3.2.0_@types_debug@4.1.12_@types_node@20.19.27_jiti@2.6.1_93023d256ff9ed909ae8f0d436c922a0 → vitest@3.2.4_@edge-runtime_vm@3.2.0_@types_debug@4.1.12_@types_node@20.19.27_jiti@2.6.1_e422349b438eb7189cab8b1648fc0621}/node_modules/vitest/dist/chunks/_commonjsHelpers.BFTU3MAI.js +1 -1
  55. package/dist/node_modules/.pnpm/{vitest@3.2.4_@edge-runtime_vm@3.2.0_@types_debug@4.1.12_@types_node@20.19.27_jiti@2.6.1_93023d256ff9ed909ae8f0d436c922a0 → vitest@3.2.4_@edge-runtime_vm@3.2.0_@types_debug@4.1.12_@types_node@20.19.27_jiti@2.6.1_e422349b438eb7189cab8b1648fc0621}/node_modules/vitest/dist/chunks/date.Bq6ZW5rf.js +1 -1
  56. package/dist/node_modules/.pnpm/{vitest@3.2.4_@edge-runtime_vm@3.2.0_@types_debug@4.1.12_@types_node@20.19.27_jiti@2.6.1_93023d256ff9ed909ae8f0d436c922a0 → vitest@3.2.4_@edge-runtime_vm@3.2.0_@types_debug@4.1.12_@types_node@20.19.27_jiti@2.6.1_e422349b438eb7189cab8b1648fc0621}/node_modules/vitest/dist/chunks/utils.XdZDrNZV.js +1 -1
  57. package/dist/node_modules/.pnpm/{vitest@3.2.4_@edge-runtime_vm@3.2.0_@types_debug@4.1.12_@types_node@20.19.27_jiti@2.6.1_93023d256ff9ed909ae8f0d436c922a0 → vitest@3.2.4_@edge-runtime_vm@3.2.0_@types_debug@4.1.12_@types_node@20.19.27_jiti@2.6.1_e422349b438eb7189cab8b1648fc0621}/node_modules/vitest/dist/chunks/vi.bdSIJ99Y.js +1 -1
  58. package/dist/test-utils/mocks/logger.js +1 -1
  59. package/dist/utils/apiKeys.js +1 -1
  60. package/dist/utils/error.d.ts +51 -51
  61. package/dist/validation/drizzle-schema-helpers.d.ts +3 -3
  62. package/dist/validation/index.d.ts +2 -2
  63. package/dist/validation/index.js +2 -2
  64. package/dist/validation/schemas/skills.d.ts +46 -46
  65. package/dist/validation/schemas.d.ts +2080 -1892
  66. package/dist/validation/schemas.js +16 -2
  67. package/package.json +1 -1
  68. package/spicedb/schema.zed +27 -0
@@ -4,7 +4,7 @@ import * as jose0 from "jose";
4
4
  import * as zod0 from "zod";
5
5
  import * as better_auth0 from "better-auth";
6
6
  import * as _better_auth_oauth_provider0 from "@better-auth/oauth-provider";
7
- import * as better_auth_plugins0 from "better-auth/plugins";
7
+ import * as better_auth_plugins20 from "better-auth/plugins";
8
8
 
9
9
  //#region src/auth/auth.d.ts
10
10
 
@@ -40,10 +40,10 @@ declare function _inferAuthType(): better_auth0.Auth<{
40
40
  handler: (inputContext: better_auth0.MiddlewareInputContext<better_auth0.MiddlewareOptions>) => Promise<void>;
41
41
  }[];
42
42
  };
43
- options: better_auth_plugins0.BearerOptions | undefined;
43
+ options: better_auth_plugins20.BearerOptions | undefined;
44
44
  }, {
45
45
  id: "oauth-proxy";
46
- options: NoInfer<better_auth_plugins0.OAuthProxyOptions>;
46
+ options: NoInfer<better_auth_plugins20.OAuthProxyOptions>;
47
47
  endpoints: {
48
48
  oAuthProxy: better_auth0.StrictEndpoint<"/oauth-proxy-callback", {
49
49
  method: "GET";
@@ -97,7 +97,7 @@ declare function _inferAuthType(): better_auth0.Auth<{
97
97
  };
98
98
  }, {
99
99
  id: "jwt";
100
- options: NoInfer<better_auth_plugins0.JwtOptions>;
100
+ options: NoInfer<better_auth_plugins20.JwtOptions>;
101
101
  endpoints: {
102
102
  getJwks: better_auth0.StrictEndpoint<string, {
103
103
  method: "GET";
@@ -234,7 +234,7 @@ declare function _inferAuthType(): better_auth0.Auth<{
234
234
  $Infer: {
235
235
  body: {
236
236
  payload: jose0.JWTPayload;
237
- overrideOptions?: better_auth_plugins0.JwtOptions | undefined;
237
+ overrideOptions?: better_auth_plugins20.JwtOptions | undefined;
238
238
  };
239
239
  };
240
240
  };
@@ -331,7 +331,7 @@ declare function _inferAuthType(): better_auth0.Auth<{
331
331
  SERVER_ONLY: true;
332
332
  };
333
333
  }, Omit<_better_auth_oauth_provider0.OIDCMetadata, "id_token_signing_alg_values_supported"> & {
334
- id_token_signing_alg_values_supported: better_auth_plugins0.JWSAlgorithms[] | ["HS256"];
334
+ id_token_signing_alg_values_supported: better_auth_plugins20.JWSAlgorithms[] | ["HS256"];
335
335
  }>;
336
336
  oauth2Authorize: better_auth0.StrictEndpoint<"/oauth2/authorize", {
337
337
  method: "GET";
@@ -2324,7 +2324,7 @@ declare function _inferAuthType(): better_auth0.Auth<{
2324
2324
  window: number;
2325
2325
  max: number;
2326
2326
  })[];
2327
- }, better_auth_plugins0.DefaultOrganizationPlugin<{
2327
+ }, better_auth_plugins20.DefaultOrganizationPlugin<{
2328
2328
  schema: {
2329
2329
  invitation: {
2330
2330
  additionalFields: {
@@ -2687,8 +2687,8 @@ declare function _inferAuthType(): better_auth0.Auth<{
2687
2687
  AUTHENTICATION_REQUIRED: better_auth0.RawError<"AUTHENTICATION_REQUIRED">;
2688
2688
  };
2689
2689
  options: Partial<{
2690
- expiresIn: better_auth_plugins0.TimeString;
2691
- interval: better_auth_plugins0.TimeString;
2690
+ expiresIn: better_auth_plugins20.TimeString;
2691
+ interval: better_auth_plugins20.TimeString;
2692
2692
  deviceCodeLength: number;
2693
2693
  userCodeLength: number;
2694
2694
  schema: {
@@ -13,23 +13,49 @@ declare function getSpiceDbConfig(): {
13
13
  tlsEnabled: boolean;
14
14
  };
15
15
  /**
16
- * Compose a tenant-scoped SpiceDB project object ID.
16
+ * Branded SpiceDB object ID types.
17
+ *
18
+ * SpiceDB object IDs are global — `credential_reference:cred_foo` refers to one
19
+ * object regardless of who wrote the tuple. To prevent cross-tenant collisions we
20
+ * namespace composite-PK resources under their scope (`{tenantId}/{projectId}/...`).
17
21
  *
18
- * SpiceDB object IDs are global, so we namespace projects under their tenant
19
- * to prevent cross-tenant collisions (e.g. two orgs with a project called "default").
22
+ * The brand is enforcement, not decoration: downstream helpers accept only the
23
+ * branded type, so a raw DB ID can never be passed to a SpiceDB call without
24
+ * going through the appropriate `toSpiceDb*Id` constructor. This catches at
25
+ * compile time the "forgot to tenant-prefix" bug class.
26
+ */
27
+ type SpiceDbProjectId = string & {
28
+ readonly __brand: 'SpiceDbProjectId';
29
+ };
30
+ type SpiceDbCredentialReferenceId = string & {
31
+ readonly __brand: 'SpiceDbCredentialReferenceId';
32
+ };
33
+ /**
34
+ * Compose a tenant-scoped SpiceDB project object ID.
20
35
  *
21
- * Format: `{tenantId}/{projectId}`
36
+ * Format: `{tenantId}/{projectId}` — projects' backing-store PK is
37
+ * `(tenantId, projectId)`, so this mirrors that composite key verbatim.
22
38
  */
23
- declare function toSpiceDbProjectId(tenantId: string, projectId: string): string;
39
+ declare function toSpiceDbProjectId(tenantId: string, projectId: string): SpiceDbProjectId;
24
40
  /**
25
41
  * Parse a tenant-scoped SpiceDB project object ID back into its parts.
26
42
  *
27
43
  * @returns `{ tenantId, projectId }` extracted from the composite ID.
28
44
  * @throws if the ID does not contain the separator.
29
45
  */
30
- declare function fromSpiceDbProjectId(spiceDbProjectId: string): {
46
+ declare function fromSpiceDbProjectId(spiceDbProjectId: SpiceDbProjectId | string): {
31
47
  tenantId: string;
32
48
  projectId: string;
33
49
  };
50
+ /**
51
+ * Compose a tenant+project-scoped SpiceDB credential_reference object ID.
52
+ *
53
+ * Format: `{tenantId}/{projectId}/{credentialReferenceId}` — credentials' backing-store
54
+ * PK is `(tenantId, projectId, id)`, so this mirrors that composite key verbatim.
55
+ * Without this scoping, two tenants that each define a credential with the same
56
+ * slug (e.g. `cred_helpscout`) would share the same SpiceDB object and any grant
57
+ * on one would appear to grant the other.
58
+ */
59
+ declare function toSpiceDbCredentialReferenceId(tenantId: string, projectId: string, credentialReferenceId: string): SpiceDbCredentialReferenceId;
34
60
  //#endregion
35
- export { fromSpiceDbProjectId, getSpiceDbConfig, isLocalhostEndpoint, toSpiceDbProjectId };
61
+ export { SpiceDbCredentialReferenceId, SpiceDbProjectId, fromSpiceDbProjectId, getSpiceDbConfig, isLocalhostEndpoint, toSpiceDbCredentialReferenceId, toSpiceDbProjectId };
@@ -19,17 +19,15 @@ function getSpiceDbConfig() {
19
19
  tlsEnabled: env.SPICEDB_TLS_ENABLED ?? !isLocalhostEndpoint(endpoint)
20
20
  };
21
21
  }
22
- const SPICEDB_PROJECT_ID_SEPARATOR = "/";
22
+ const SPICEDB_ID_SEPARATOR = "/";
23
23
  /**
24
24
  * Compose a tenant-scoped SpiceDB project object ID.
25
25
  *
26
- * SpiceDB object IDs are global, so we namespace projects under their tenant
27
- * to prevent cross-tenant collisions (e.g. two orgs with a project called "default").
28
- *
29
- * Format: `{tenantId}/{projectId}`
26
+ * Format: `{tenantId}/{projectId}` projects' backing-store PK is
27
+ * `(tenantId, projectId)`, so this mirrors that composite key verbatim.
30
28
  */
31
29
  function toSpiceDbProjectId(tenantId, projectId) {
32
- return `${tenantId}${SPICEDB_PROJECT_ID_SEPARATOR}${projectId}`;
30
+ return `${tenantId}${SPICEDB_ID_SEPARATOR}${projectId}`;
33
31
  }
34
32
  /**
35
33
  * Parse a tenant-scoped SpiceDB project object ID back into its parts.
@@ -38,13 +36,25 @@ function toSpiceDbProjectId(tenantId, projectId) {
38
36
  * @throws if the ID does not contain the separator.
39
37
  */
40
38
  function fromSpiceDbProjectId(spiceDbProjectId) {
41
- const separatorIndex = spiceDbProjectId.indexOf(SPICEDB_PROJECT_ID_SEPARATOR);
39
+ const separatorIndex = spiceDbProjectId.indexOf(SPICEDB_ID_SEPARATOR);
42
40
  if (separatorIndex === -1) throw new Error(`Invalid SpiceDB project ID format: ${spiceDbProjectId}`);
43
41
  return {
44
42
  tenantId: spiceDbProjectId.substring(0, separatorIndex),
45
43
  projectId: spiceDbProjectId.substring(separatorIndex + 1)
46
44
  };
47
45
  }
46
+ /**
47
+ * Compose a tenant+project-scoped SpiceDB credential_reference object ID.
48
+ *
49
+ * Format: `{tenantId}/{projectId}/{credentialReferenceId}` — credentials' backing-store
50
+ * PK is `(tenantId, projectId, id)`, so this mirrors that composite key verbatim.
51
+ * Without this scoping, two tenants that each define a credential with the same
52
+ * slug (e.g. `cred_helpscout`) would share the same SpiceDB object and any grant
53
+ * on one would appear to grant the other.
54
+ */
55
+ function toSpiceDbCredentialReferenceId(tenantId, projectId, credentialReferenceId) {
56
+ return `${tenantId}${SPICEDB_ID_SEPARATOR}${projectId}${SPICEDB_ID_SEPARATOR}${credentialReferenceId}`;
57
+ }
48
58
 
49
59
  //#endregion
50
- export { fromSpiceDbProjectId, getSpiceDbConfig, isLocalhostEndpoint, toSpiceDbProjectId };
60
+ export { fromSpiceDbProjectId, getSpiceDbConfig, isLocalhostEndpoint, toSpiceDbCredentialReferenceId, toSpiceDbProjectId };
@@ -0,0 +1,57 @@
1
+ //#region src/auth/authz/credential-gateway.d.ts
2
+ /**
3
+ * Grant an app permission to read a credential.
4
+ *
5
+ * Requires the full credential scope (tenantId + projectId + credentialReferenceId)
6
+ * because credential_reference IDs are only unique within a project; the SpiceDB
7
+ * object ID is constructed via {@link toSpiceDbCredentialReferenceId}.
8
+ */
9
+ declare function grantAppCredentialAccess(params: {
10
+ tenantId: string;
11
+ projectId: string;
12
+ credentialReferenceId: string;
13
+ appId: string;
14
+ }): Promise<void>;
15
+ /**
16
+ * Revoke an app's permission to read a credential.
17
+ */
18
+ declare function revokeAppCredentialAccess(params: {
19
+ tenantId: string;
20
+ projectId: string;
21
+ credentialReferenceId: string;
22
+ appId: string;
23
+ }): Promise<void>;
24
+ /**
25
+ * Check whether an app has permission to read a credential.
26
+ */
27
+ declare function canAppReadCredential(params: {
28
+ tenantId: string;
29
+ projectId: string;
30
+ credentialReferenceId: string;
31
+ appId: string;
32
+ }): Promise<boolean>;
33
+ /**
34
+ * Atomically reconcile the credential an app is granted read access to.
35
+ *
36
+ * One call covers all transitions:
37
+ * - prior=∅, next=∅ → no-op
38
+ * - prior=∅, next=Y → TOUCH new
39
+ * - prior=X, next=∅ → DELETE old (fixes the "user cleared the credential" case)
40
+ * - prior=X, next=X → idempotent TOUCH (collapsed, safe no-op in practice)
41
+ * - prior=X, next=Y (X≠Y) → DELETE old + TOUCH new in a single writeRelationships batch
42
+ *
43
+ * All mutations are issued via `WriteRelationships.updates[]`, so any transition
44
+ * involving both a delete and a write is observed atomically by readers (one
45
+ * zedtoken, no window where neither the old nor the new tuple is valid).
46
+ *
47
+ * Mirrors the pattern used by `changeOrgRole` / `changeProjectRole` in sync.ts.
48
+ */
49
+ declare function rewriteAppCredentialAccess(params: {
50
+ tenantId: string;
51
+ projectId: string;
52
+ priorCredentialReferenceId?: string;
53
+ nextCredentialReferenceId?: string;
54
+ appId: string;
55
+ }): Promise<void>;
56
+ //#endregion
57
+ export { canAppReadCredential, grantAppCredentialAccess, revokeAppCredentialAccess, rewriteAppCredentialAccess };
@@ -0,0 +1,118 @@
1
+ import { SpiceDbRelations, SpiceDbResourceTypes } from "./types.js";
2
+ import { toSpiceDbCredentialReferenceId } from "./config.js";
3
+ import { RelationshipOperation, checkPermission, deleteRelationship, getSpiceClient, writeRelationship } from "./client.js";
4
+
5
+ //#region src/auth/authz/credential-gateway.ts
6
+ /**
7
+ * Grant an app permission to read a credential.
8
+ *
9
+ * Requires the full credential scope (tenantId + projectId + credentialReferenceId)
10
+ * because credential_reference IDs are only unique within a project; the SpiceDB
11
+ * object ID is constructed via {@link toSpiceDbCredentialReferenceId}.
12
+ */
13
+ async function grantAppCredentialAccess(params) {
14
+ await writeRelationship({
15
+ resourceType: SpiceDbResourceTypes.CREDENTIAL_REFERENCE,
16
+ resourceId: toSpiceDbCredentialReferenceId(params.tenantId, params.projectId, params.credentialReferenceId),
17
+ relation: SpiceDbRelations.APP_READER,
18
+ subjectType: SpiceDbResourceTypes.APP,
19
+ subjectId: params.appId
20
+ });
21
+ }
22
+ /**
23
+ * Revoke an app's permission to read a credential.
24
+ */
25
+ async function revokeAppCredentialAccess(params) {
26
+ await deleteRelationship({
27
+ resourceType: SpiceDbResourceTypes.CREDENTIAL_REFERENCE,
28
+ resourceId: toSpiceDbCredentialReferenceId(params.tenantId, params.projectId, params.credentialReferenceId),
29
+ relation: SpiceDbRelations.APP_READER,
30
+ subjectType: SpiceDbResourceTypes.APP,
31
+ subjectId: params.appId
32
+ });
33
+ }
34
+ /**
35
+ * Check whether an app has permission to read a credential.
36
+ */
37
+ async function canAppReadCredential(params) {
38
+ return checkPermission({
39
+ resourceType: SpiceDbResourceTypes.CREDENTIAL_REFERENCE,
40
+ resourceId: toSpiceDbCredentialReferenceId(params.tenantId, params.projectId, params.credentialReferenceId),
41
+ permission: "read",
42
+ subjectType: SpiceDbResourceTypes.APP,
43
+ subjectId: params.appId
44
+ });
45
+ }
46
+ /**
47
+ * Atomically reconcile the credential an app is granted read access to.
48
+ *
49
+ * One call covers all transitions:
50
+ * - prior=∅, next=∅ → no-op
51
+ * - prior=∅, next=Y → TOUCH new
52
+ * - prior=X, next=∅ → DELETE old (fixes the "user cleared the credential" case)
53
+ * - prior=X, next=X → idempotent TOUCH (collapsed, safe no-op in practice)
54
+ * - prior=X, next=Y (X≠Y) → DELETE old + TOUCH new in a single writeRelationships batch
55
+ *
56
+ * All mutations are issued via `WriteRelationships.updates[]`, so any transition
57
+ * involving both a delete and a write is observed atomically by readers (one
58
+ * zedtoken, no window where neither the old nor the new tuple is valid).
59
+ *
60
+ * Mirrors the pattern used by `changeOrgRole` / `changeProjectRole` in sync.ts.
61
+ */
62
+ async function rewriteAppCredentialAccess(params) {
63
+ const { priorCredentialReferenceId, nextCredentialReferenceId, tenantId, projectId, appId } = params;
64
+ if (!priorCredentialReferenceId && !nextCredentialReferenceId) return;
65
+ const spice = getSpiceClient();
66
+ const updates = [];
67
+ if (priorCredentialReferenceId && priorCredentialReferenceId !== nextCredentialReferenceId) {
68
+ const priorId = toSpiceDbCredentialReferenceId(tenantId, projectId, priorCredentialReferenceId);
69
+ updates.push({
70
+ operation: RelationshipOperation.DELETE,
71
+ relationship: {
72
+ resource: {
73
+ objectType: SpiceDbResourceTypes.CREDENTIAL_REFERENCE,
74
+ objectId: priorId
75
+ },
76
+ relation: SpiceDbRelations.APP_READER,
77
+ subject: {
78
+ object: {
79
+ objectType: SpiceDbResourceTypes.APP,
80
+ objectId: appId
81
+ },
82
+ optionalRelation: ""
83
+ },
84
+ optionalCaveat: void 0
85
+ }
86
+ });
87
+ }
88
+ if (nextCredentialReferenceId) {
89
+ const nextId = toSpiceDbCredentialReferenceId(tenantId, projectId, nextCredentialReferenceId);
90
+ updates.push({
91
+ operation: RelationshipOperation.TOUCH,
92
+ relationship: {
93
+ resource: {
94
+ objectType: SpiceDbResourceTypes.CREDENTIAL_REFERENCE,
95
+ objectId: nextId
96
+ },
97
+ relation: SpiceDbRelations.APP_READER,
98
+ subject: {
99
+ object: {
100
+ objectType: SpiceDbResourceTypes.APP,
101
+ objectId: appId
102
+ },
103
+ optionalRelation: ""
104
+ },
105
+ optionalCaveat: void 0
106
+ }
107
+ });
108
+ }
109
+ if (updates.length === 0) return;
110
+ await spice.promises.writeRelationships({
111
+ updates,
112
+ optionalPreconditions: [],
113
+ optionalTransactionMetadata: void 0
114
+ });
115
+ }
116
+
117
+ //#endregion
118
+ export { canAppReadCredential, grantAppCredentialAccess, revokeAppCredentialAccess, rewriteAppCredentialAccess };
@@ -1,6 +1,7 @@
1
1
  import { checkBulkPermissions, checkPermission, deleteRelationship, getSpiceClient, lookupResources, readRelationships, resetSpiceClient, writeRelationship } from "./client.js";
2
- import { fromSpiceDbProjectId, getSpiceDbConfig, toSpiceDbProjectId } from "./config.js";
3
- import { OrgRole, OrgRoles, ProjectPermissionLevel, ProjectPermissions, ProjectRole, ProjectRoles, SpiceDbOrgPermission, SpiceDbOrgPermissions, SpiceDbProjectPermission, SpiceDbProjectPermissions, SpiceDbRelations, SpiceDbResourceTypes } from "./types.js";
2
+ import { SpiceDbCredentialReferenceId, SpiceDbProjectId, fromSpiceDbProjectId, getSpiceDbConfig, toSpiceDbCredentialReferenceId, toSpiceDbProjectId } from "./config.js";
3
+ import { canAppReadCredential, grantAppCredentialAccess, revokeAppCredentialAccess, rewriteAppCredentialAccess } from "./credential-gateway.js";
4
+ import { OrgRole, OrgRoles, ProjectPermissionLevel, ProjectPermissions, ProjectRole, ProjectRoles, SpiceDbCredentialReferencePermission, SpiceDbCredentialReferencePermissions, SpiceDbOrgPermission, SpiceDbOrgPermissions, SpiceDbProjectPermission, SpiceDbProjectPermissions, SpiceDbRelations, SpiceDbResourceTypes } from "./types.js";
4
5
  import { canEditProject, canUseProject, canUseProjectStrict, canViewProject, listAccessibleProjectIds, listUsableProjectIds } from "./permissions.js";
5
6
  import { changeOrgRole, changeProjectRole, grantProjectAccess, listProjectMembers, listUserProjectMembershipsInSpiceDb, removeProjectFromSpiceDb, revokeAllProjectMemberships, revokeProjectAccess, syncOrgMemberToSpiceDb, syncProjectToSpiceDb } from "./sync.js";
6
- export { type OrgRole, OrgRoles, type ProjectPermissionLevel, type ProjectPermissions, type ProjectRole, ProjectRoles, type SpiceDbOrgPermission, SpiceDbOrgPermissions, type SpiceDbProjectPermission, SpiceDbProjectPermissions, SpiceDbRelations, SpiceDbResourceTypes, canEditProject, canUseProject, canUseProjectStrict, canViewProject, changeOrgRole, changeProjectRole, checkBulkPermissions, checkPermission, deleteRelationship, fromSpiceDbProjectId, getSpiceClient, getSpiceDbConfig, grantProjectAccess, listAccessibleProjectIds, listProjectMembers, listUsableProjectIds, listUserProjectMembershipsInSpiceDb, lookupResources, readRelationships, removeProjectFromSpiceDb, resetSpiceClient, revokeAllProjectMemberships, revokeProjectAccess, syncOrgMemberToSpiceDb, syncProjectToSpiceDb, toSpiceDbProjectId, writeRelationship };
7
+ export { type OrgRole, OrgRoles, type ProjectPermissionLevel, type ProjectPermissions, type ProjectRole, ProjectRoles, type SpiceDbCredentialReferenceId, type SpiceDbCredentialReferencePermission, SpiceDbCredentialReferencePermissions, type SpiceDbOrgPermission, SpiceDbOrgPermissions, type SpiceDbProjectId, type SpiceDbProjectPermission, SpiceDbProjectPermissions, SpiceDbRelations, SpiceDbResourceTypes, canAppReadCredential, canEditProject, canUseProject, canUseProjectStrict, canViewProject, changeOrgRole, changeProjectRole, checkBulkPermissions, checkPermission, deleteRelationship, fromSpiceDbProjectId, getSpiceClient, getSpiceDbConfig, grantAppCredentialAccess, grantProjectAccess, listAccessibleProjectIds, listProjectMembers, listUsableProjectIds, listUserProjectMembershipsInSpiceDb, lookupResources, readRelationships, removeProjectFromSpiceDb, resetSpiceClient, revokeAllProjectMemberships, revokeAppCredentialAccess, revokeProjectAccess, rewriteAppCredentialAccess, syncOrgMemberToSpiceDb, syncProjectToSpiceDb, toSpiceDbCredentialReferenceId, toSpiceDbProjectId, writeRelationship };
@@ -1,7 +1,8 @@
1
- import { OrgRoles, ProjectRoles, SpiceDbOrgPermissions, SpiceDbProjectPermissions, SpiceDbRelations, SpiceDbResourceTypes } from "./types.js";
2
- import { fromSpiceDbProjectId, getSpiceDbConfig, toSpiceDbProjectId } from "./config.js";
1
+ import { OrgRoles, ProjectRoles, SpiceDbCredentialReferencePermissions, SpiceDbOrgPermissions, SpiceDbProjectPermissions, SpiceDbRelations, SpiceDbResourceTypes } from "./types.js";
2
+ import { fromSpiceDbProjectId, getSpiceDbConfig, toSpiceDbCredentialReferenceId, toSpiceDbProjectId } from "./config.js";
3
3
  import { checkBulkPermissions, checkPermission, deleteRelationship, getSpiceClient, lookupResources, readRelationships, resetSpiceClient, writeRelationship } from "./client.js";
4
+ import { canAppReadCredential, grantAppCredentialAccess, revokeAppCredentialAccess, rewriteAppCredentialAccess } from "./credential-gateway.js";
4
5
  import { canEditProject, canUseProject, canUseProjectStrict, canViewProject, listAccessibleProjectIds, listUsableProjectIds } from "./permissions.js";
5
6
  import { changeOrgRole, changeProjectRole, grantProjectAccess, listProjectMembers, listUserProjectMembershipsInSpiceDb, removeProjectFromSpiceDb, revokeAllProjectMemberships, revokeProjectAccess, syncOrgMemberToSpiceDb, syncProjectToSpiceDb } from "./sync.js";
6
7
 
7
- export { OrgRoles, ProjectRoles, SpiceDbOrgPermissions, SpiceDbProjectPermissions, SpiceDbRelations, SpiceDbResourceTypes, canEditProject, canUseProject, canUseProjectStrict, canViewProject, changeOrgRole, changeProjectRole, checkBulkPermissions, checkPermission, deleteRelationship, fromSpiceDbProjectId, getSpiceClient, getSpiceDbConfig, grantProjectAccess, listAccessibleProjectIds, listProjectMembers, listUsableProjectIds, listUserProjectMembershipsInSpiceDb, lookupResources, readRelationships, removeProjectFromSpiceDb, resetSpiceClient, revokeAllProjectMemberships, revokeProjectAccess, syncOrgMemberToSpiceDb, syncProjectToSpiceDb, toSpiceDbProjectId, writeRelationship };
8
+ export { OrgRoles, ProjectRoles, SpiceDbCredentialReferencePermissions, SpiceDbOrgPermissions, SpiceDbProjectPermissions, SpiceDbRelations, SpiceDbResourceTypes, canAppReadCredential, canEditProject, canUseProject, canUseProjectStrict, canViewProject, changeOrgRole, changeProjectRole, checkBulkPermissions, checkPermission, deleteRelationship, fromSpiceDbProjectId, getSpiceClient, getSpiceDbConfig, grantAppCredentialAccess, grantProjectAccess, listAccessibleProjectIds, listProjectMembers, listUsableProjectIds, listUserProjectMembershipsInSpiceDb, lookupResources, readRelationships, removeProjectFromSpiceDb, resetSpiceClient, revokeAllProjectMemberships, revokeAppCredentialAccess, revokeProjectAccess, rewriteAppCredentialAccess, syncOrgMemberToSpiceDb, syncProjectToSpiceDb, toSpiceDbCredentialReferenceId, toSpiceDbProjectId, writeRelationship };
@@ -10,6 +10,8 @@ declare const SpiceDbResourceTypes: {
10
10
  readonly USER: "user";
11
11
  readonly ORGANIZATION: "organization";
12
12
  readonly PROJECT: "project";
13
+ readonly APP: "app";
14
+ readonly CREDENTIAL_REFERENCE: "credential_reference";
13
15
  };
14
16
  /**
15
17
  * SpiceDB relations used in the schema
@@ -25,6 +27,7 @@ declare const SpiceDbRelations: {
25
27
  readonly PROJECT_ADMIN: "project_admin";
26
28
  readonly PROJECT_MEMBER: "project_member";
27
29
  readonly PROJECT_VIEWER: "project_viewer";
30
+ readonly APP_READER: "app_reader";
28
31
  };
29
32
  /**
30
33
  * SpiceDB permissions for organization resources.
@@ -52,6 +55,10 @@ declare const SpiceDbProjectPermissions: {
52
55
  readonly EDIT: "edit";
53
56
  };
54
57
  type SpiceDbProjectPermission = (typeof SpiceDbProjectPermissions)[keyof typeof SpiceDbProjectPermissions];
58
+ declare const SpiceDbCredentialReferencePermissions: {
59
+ readonly READ: "read";
60
+ };
61
+ type SpiceDbCredentialReferencePermission = (typeof SpiceDbCredentialReferencePermissions)[keyof typeof SpiceDbCredentialReferencePermissions];
55
62
  /**
56
63
  * Permission levels for project access checks.
57
64
  */
@@ -89,4 +96,4 @@ interface ProjectPermissions {
89
96
  canEdit: boolean;
90
97
  }
91
98
  //#endregion
92
- export { OrgRole, OrgRoles, ProjectPermissionLevel, ProjectPermissions, ProjectRole, ProjectRoles, SpiceDbOrgPermission, SpiceDbOrgPermissions, SpiceDbProjectPermission, SpiceDbProjectPermissions, SpiceDbRelations, SpiceDbResourceTypes };
99
+ export { OrgRole, OrgRoles, ProjectPermissionLevel, ProjectPermissions, ProjectRole, ProjectRoles, SpiceDbCredentialReferencePermission, SpiceDbCredentialReferencePermissions, SpiceDbOrgPermission, SpiceDbOrgPermissions, SpiceDbProjectPermission, SpiceDbProjectPermissions, SpiceDbRelations, SpiceDbResourceTypes };
@@ -9,7 +9,9 @@
9
9
  const SpiceDbResourceTypes = {
10
10
  USER: "user",
11
11
  ORGANIZATION: "organization",
12
- PROJECT: "project"
12
+ PROJECT: "project",
13
+ APP: "app",
14
+ CREDENTIAL_REFERENCE: "credential_reference"
13
15
  };
14
16
  /**
15
17
  * SpiceDB relations used in the schema
@@ -24,7 +26,8 @@ const SpiceDbRelations = {
24
26
  ORGANIZATION: "organization",
25
27
  PROJECT_ADMIN: "project_admin",
26
28
  PROJECT_MEMBER: "project_member",
27
- PROJECT_VIEWER: "project_viewer"
29
+ PROJECT_VIEWER: "project_viewer",
30
+ APP_READER: "app_reader"
28
31
  };
29
32
  /**
30
33
  * SpiceDB permissions for organization resources.
@@ -50,6 +53,7 @@ const SpiceDbProjectPermissions = {
50
53
  USE: "use",
51
54
  EDIT: "edit"
52
55
  };
56
+ const SpiceDbCredentialReferencePermissions = { READ: "read" };
53
57
  /**
54
58
  * Organization roles from SpiceDB schema.
55
59
  */
@@ -73,4 +77,4 @@ const ProjectRoles = {
73
77
  };
74
78
 
75
79
  //#endregion
76
- export { OrgRoles, ProjectRoles, SpiceDbOrgPermissions, SpiceDbProjectPermissions, SpiceDbRelations, SpiceDbResourceTypes };
80
+ export { OrgRoles, ProjectRoles, SpiceDbCredentialReferencePermissions, SpiceDbOrgPermissions, SpiceDbProjectPermissions, SpiceDbRelations, SpiceDbResourceTypes };
@@ -1,11 +1,9 @@
1
- import { orgEntitlement } from "../db/runtime/runtime-schema.js";
2
- import { and, eq } from "drizzle-orm";
1
+ import { dalSelectEntitlementForUpdate } from "../data-access/runtime/entitlements.js";
3
2
 
4
3
  //#region src/auth/entitlement-lock.ts
5
4
  async function withEntitlementLock(db, orgId, resourceType, fn) {
6
5
  return db.transaction(async (tx) => {
7
- const rows = await tx.select({ maxValue: orgEntitlement.maxValue }).from(orgEntitlement).where(and(eq(orgEntitlement.organizationId, orgId), eq(orgEntitlement.resourceType, resourceType))).for("update");
8
- return fn(rows.length === 0 ? null : rows[0].maxValue, tx);
6
+ return fn(await dalSelectEntitlementForUpdate(tx, orgId, resourceType), tx);
9
7
  });
10
8
  }
11
9
 
@@ -1,7 +1,7 @@
1
1
  import { DEFAULT_MEMBERSHIP_LIMIT, SEAT_RESOURCE_TYPES } from "./entitlement-constants.js";
2
2
  import { getLogger } from "../utils/logger.js";
3
- import { withEntitlementLock } from "./entitlement-lock.js";
4
3
  import { dalCountMembersByRoleBucket, dalGetServiceAccountUserId, dalResolveEntitlement, dalSumSeatEntitlements } from "../data-access/runtime/entitlements.js";
4
+ import { withEntitlementLock } from "./entitlement-lock.js";
5
5
  import { APIError } from "better-auth/api";
6
6
 
7
7
  //#region src/auth/entitlements.ts
@@ -1,29 +1,29 @@
1
- import * as better_auth_plugins7 from "better-auth/plugins";
1
+ import * as better_auth_plugins0 from "better-auth/plugins";
2
2
  import { AccessControl } from "better-auth/plugins/access";
3
3
  import { organizationClient } from "better-auth/client/plugins";
4
4
 
5
5
  //#region src/auth/permissions.d.ts
6
6
  declare const ac: AccessControl;
7
7
  declare const memberRole: {
8
- authorize<K_1 extends "project" | "invitation" | "member" | "organization" | "team" | "ac">(request: K_1 extends infer T extends K ? { [key in T]?: better_auth_plugins7.Subset<"project" | "invitation" | "member" | "organization" | "team" | "ac", better_auth_plugins7.Statements>[key] | {
9
- actions: better_auth_plugins7.Subset<"project" | "invitation" | "member" | "organization" | "team" | "ac", better_auth_plugins7.Statements>[key];
8
+ authorize<K_1 extends "organization" | "project" | "invitation" | "member" | "team" | "ac">(request: K_1 extends infer T extends K ? { [key in T]?: better_auth_plugins0.Subset<"organization" | "project" | "invitation" | "member" | "team" | "ac", better_auth_plugins0.Statements>[key] | {
9
+ actions: better_auth_plugins0.Subset<"organization" | "project" | "invitation" | "member" | "team" | "ac", better_auth_plugins0.Statements>[key];
10
10
  connector: "OR" | "AND";
11
- } | undefined } : never, connector?: "OR" | "AND"): better_auth_plugins7.AuthorizeResponse;
12
- statements: better_auth_plugins7.Subset<"project" | "invitation" | "member" | "organization" | "team" | "ac", better_auth_plugins7.Statements>;
11
+ } | undefined } : never, connector?: "OR" | "AND"): better_auth_plugins0.AuthorizeResponse;
12
+ statements: better_auth_plugins0.Subset<"organization" | "project" | "invitation" | "member" | "team" | "ac", better_auth_plugins0.Statements>;
13
13
  };
14
14
  declare const adminRole: {
15
- authorize<K_1 extends "project" | "invitation" | "member" | "organization" | "team" | "ac">(request: K_1 extends infer T extends K ? { [key in T]?: better_auth_plugins7.Subset<"project" | "invitation" | "member" | "organization" | "team" | "ac", better_auth_plugins7.Statements>[key] | {
16
- actions: better_auth_plugins7.Subset<"project" | "invitation" | "member" | "organization" | "team" | "ac", better_auth_plugins7.Statements>[key];
15
+ authorize<K_1 extends "organization" | "project" | "invitation" | "member" | "team" | "ac">(request: K_1 extends infer T extends K ? { [key in T]?: better_auth_plugins0.Subset<"organization" | "project" | "invitation" | "member" | "team" | "ac", better_auth_plugins0.Statements>[key] | {
16
+ actions: better_auth_plugins0.Subset<"organization" | "project" | "invitation" | "member" | "team" | "ac", better_auth_plugins0.Statements>[key];
17
17
  connector: "OR" | "AND";
18
- } | undefined } : never, connector?: "OR" | "AND"): better_auth_plugins7.AuthorizeResponse;
19
- statements: better_auth_plugins7.Subset<"project" | "invitation" | "member" | "organization" | "team" | "ac", better_auth_plugins7.Statements>;
18
+ } | undefined } : never, connector?: "OR" | "AND"): better_auth_plugins0.AuthorizeResponse;
19
+ statements: better_auth_plugins0.Subset<"organization" | "project" | "invitation" | "member" | "team" | "ac", better_auth_plugins0.Statements>;
20
20
  };
21
21
  declare const ownerRole: {
22
- authorize<K_1 extends "project" | "invitation" | "member" | "organization" | "team" | "ac">(request: K_1 extends infer T extends K ? { [key in T]?: better_auth_plugins7.Subset<"project" | "invitation" | "member" | "organization" | "team" | "ac", better_auth_plugins7.Statements>[key] | {
23
- actions: better_auth_plugins7.Subset<"project" | "invitation" | "member" | "organization" | "team" | "ac", better_auth_plugins7.Statements>[key];
22
+ authorize<K_1 extends "organization" | "project" | "invitation" | "member" | "team" | "ac">(request: K_1 extends infer T extends K ? { [key in T]?: better_auth_plugins0.Subset<"organization" | "project" | "invitation" | "member" | "team" | "ac", better_auth_plugins0.Statements>[key] | {
23
+ actions: better_auth_plugins0.Subset<"organization" | "project" | "invitation" | "member" | "team" | "ac", better_auth_plugins0.Statements>[key];
24
24
  connector: "OR" | "AND";
25
- } | undefined } : never, connector?: "OR" | "AND"): better_auth_plugins7.AuthorizeResponse;
26
- statements: better_auth_plugins7.Subset<"project" | "invitation" | "member" | "organization" | "team" | "ac", better_auth_plugins7.Statements>;
25
+ } | undefined } : never, connector?: "OR" | "AND"): better_auth_plugins0.AuthorizeResponse;
26
+ statements: better_auth_plugins0.Subset<"organization" | "project" | "invitation" | "member" | "team" | "ac", better_auth_plugins0.Statements>;
27
27
  };
28
28
  //#endregion
29
29
  export { ac, adminRole, memberRole, organizationClient, ownerRole };