@agent-native/dispatch 0.8.2 → 0.8.4
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/update-vault-secret.d.ts.map +1 -1
- package/dist/actions/update-vault-secret.js +34 -6
- package/dist/actions/update-vault-secret.js.map +1 -1
- package/dist/routes/index.d.ts.map +1 -1
- package/dist/routes/index.js +1 -0
- package/dist/routes/index.js.map +1 -1
- package/dist/routes/pages/extensions.$id.d.ts +3 -0
- package/dist/routes/pages/extensions.$id.d.ts.map +1 -1
- package/dist/routes/pages/extensions.$id.js +5 -2
- package/dist/routes/pages/extensions.$id.js.map +1 -1
- package/dist/routes/pages/extensions._index.d.ts +3 -0
- package/dist/routes/pages/extensions._index.d.ts.map +1 -1
- package/dist/routes/pages/extensions._index.js +5 -2
- package/dist/routes/pages/extensions._index.js.map +1 -1
- package/dist/routes/pages/tools.$id.d.ts +3 -0
- package/dist/routes/pages/tools.$id.d.ts.map +1 -1
- package/dist/routes/pages/tools.$id.js +3 -0
- package/dist/routes/pages/tools.$id.js.map +1 -1
- package/dist/routes/pages/tools._index.d.ts +3 -0
- package/dist/routes/pages/tools._index.d.ts.map +1 -1
- package/dist/routes/pages/tools._index.js +3 -0
- package/dist/routes/pages/tools._index.js.map +1 -1
- package/dist/routes/pages/vault.d.ts.map +1 -1
- package/dist/routes/pages/vault.js +46 -2
- package/dist/routes/pages/vault.js.map +1 -1
- package/dist/server/lib/vault-store.d.ts +8 -1
- package/dist/server/lib/vault-store.d.ts.map +1 -1
- package/dist/server/lib/vault-store.js +90 -5
- package/dist/server/lib/vault-store.js.map +1 -1
- package/package.json +1 -1
- package/src/actions/update-vault-secret.ts +39 -6
- package/src/routes/index.ts +1 -0
- package/src/routes/pages/extensions.$id.tsx +6 -2
- package/src/routes/pages/extensions._index.tsx +6 -2
- package/src/routes/pages/tools.$id.tsx +4 -0
- package/src/routes/pages/tools._index.tsx +4 -0
- package/src/routes/pages/vault.tsx +172 -1
- package/src/server/lib/vault-store.spec.ts +80 -0
- package/src/server/lib/vault-store.ts +125 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vault-store.d.ts","sourceRoot":"","sources":["../../../src/server/lib/vault-store.ts"],"names":[],"mappings":"AAGA,OAAO,
|
|
1
|
+
{"version":3,"file":"vault-store.d.ts","sourceRoot":"","sources":["../../../src/server/lib/vault-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,12 @@
|
|
|
1
1
|
import crypto from "node:crypto";
|
|
2
2
|
import { and, desc, eq, isNull, or } from "drizzle-orm";
|
|
3
3
|
import { discoverAgents } from "@agent-native/core/server/agent-discovery";
|
|
4
|
-
import { writeAppSecret } from "@agent-native/core/secrets";
|
|
4
|
+
import { deleteAppSecret, listAppSecretsForScope, writeAppSecret, } from "@agent-native/core/secrets";
|
|
5
5
|
import { getOrgSetting, getUserSetting, putOrgSetting, putUserSetting, } from "@agent-native/core/settings";
|
|
6
6
|
import { getDb, schema } from "../../db/index.js";
|
|
7
7
|
import { currentOwnerEmail, currentOrgId, recordAudit, } from "./dispatch-store.js";
|
|
8
8
|
const VAULT_ACCESS_SETTINGS_KEY = "dispatch-vault-access-settings";
|
|
9
|
+
const VAULT_SYNC_DESCRIPTION_PREFIX = "Synced from Dispatch vault:";
|
|
9
10
|
/**
|
|
10
11
|
* Build a VaultCtx from the current request. Throws if the request is
|
|
11
12
|
* unauthenticated — the previous behavior of falling back to "local@localhost"
|
|
@@ -201,23 +202,83 @@ export async function createSecret(input, ctx = requireVaultCtx()) {
|
|
|
201
202
|
await syncSecretsToCredentialStore([created], ctx);
|
|
202
203
|
return created;
|
|
203
204
|
}
|
|
204
|
-
export async function updateSecret(secretId,
|
|
205
|
+
export async function updateSecret(secretId, input, ctx = requireVaultCtx()) {
|
|
205
206
|
const db = getDb();
|
|
206
207
|
const existing = await getSecret(secretId, ctx);
|
|
207
208
|
if (!existing)
|
|
208
209
|
throw new Error("Secret not found");
|
|
210
|
+
const patch = typeof input === "string" ? { value: input } : input;
|
|
211
|
+
const credentialKey = patch.credentialKey !== undefined
|
|
212
|
+
? normalizeCredentialKey(patch.credentialKey)
|
|
213
|
+
: existing.credentialKey;
|
|
214
|
+
if (!credentialKey)
|
|
215
|
+
throw new Error("Credential key is required");
|
|
216
|
+
const name = patch.name !== undefined ? patch.name.trim() : existing.name;
|
|
217
|
+
if (!name)
|
|
218
|
+
throw new Error("Secret name is required");
|
|
219
|
+
const value = patch.value !== undefined ? patch.value : existing.value;
|
|
220
|
+
if (!value)
|
|
221
|
+
throw new Error("Secret value is required");
|
|
222
|
+
const provider = patch.provider !== undefined ? patch.provider || null : existing.provider;
|
|
223
|
+
const description = patch.description !== undefined
|
|
224
|
+
? patch.description || null
|
|
225
|
+
: existing.description;
|
|
226
|
+
if (credentialKey !== existing.credentialKey) {
|
|
227
|
+
const conflict = await db
|
|
228
|
+
.select({ id: schema.vaultSecrets.id })
|
|
229
|
+
.from(schema.vaultSecrets)
|
|
230
|
+
.where(and(eq(schema.vaultSecrets.credentialKey, credentialKey), ctxScope(schema.vaultSecrets, ctx)))
|
|
231
|
+
.limit(1);
|
|
232
|
+
if (conflict[0] && conflict[0].id !== secretId) {
|
|
233
|
+
throw new Error(`Credential key "${credentialKey}" is already in use`);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
209
236
|
await db
|
|
210
237
|
.update(schema.vaultSecrets)
|
|
211
|
-
.set({
|
|
238
|
+
.set({
|
|
239
|
+
name,
|
|
240
|
+
credentialKey,
|
|
241
|
+
value,
|
|
242
|
+
provider,
|
|
243
|
+
description,
|
|
244
|
+
updatedAt: now(),
|
|
245
|
+
})
|
|
212
246
|
.where(and(eq(schema.vaultSecrets.id, secretId), ctxScope(schema.vaultSecrets, ctx)));
|
|
247
|
+
const auditMetadata = {
|
|
248
|
+
name,
|
|
249
|
+
previousName: name !== existing.name ? existing.name : undefined,
|
|
250
|
+
credentialKey,
|
|
251
|
+
previousCredentialKey: credentialKey !== existing.credentialKey
|
|
252
|
+
? existing.credentialKey
|
|
253
|
+
: undefined,
|
|
254
|
+
provider,
|
|
255
|
+
previousProvider: provider !== existing.provider ? existing.provider : undefined,
|
|
256
|
+
description,
|
|
257
|
+
previousDescription: description !== existing.description ? existing.description : undefined,
|
|
258
|
+
valueChanged: value !== existing.value ? true : undefined,
|
|
259
|
+
};
|
|
213
260
|
await recordVaultAudit({
|
|
214
261
|
action: "secret.updated",
|
|
215
262
|
secretId,
|
|
216
|
-
summary: `Updated
|
|
263
|
+
summary: `Updated secret "${name}" (${credentialKey})`,
|
|
264
|
+
metadata: auditMetadata,
|
|
265
|
+
});
|
|
266
|
+
await recordAudit({
|
|
267
|
+
action: "vault.secret.updated",
|
|
268
|
+
targetType: "vault-secret",
|
|
269
|
+
targetId: secretId,
|
|
270
|
+
summary: `Updated vault secret "${name}" (${credentialKey})`,
|
|
271
|
+
metadata: auditMetadata,
|
|
217
272
|
});
|
|
218
273
|
const updated = await getSecret(secretId, ctx);
|
|
219
274
|
if (updated)
|
|
220
275
|
await syncSecretsToCredentialStore([updated], ctx);
|
|
276
|
+
if (updated && credentialKey !== existing.credentialKey) {
|
|
277
|
+
await cleanupSyncedCredentialKeysIfUnused(ctx, [existing.credentialKey]);
|
|
278
|
+
}
|
|
279
|
+
else if (patch.credentialKey !== undefined) {
|
|
280
|
+
await cleanupSyncedCredentialKeysIfUnused(ctx);
|
|
281
|
+
}
|
|
221
282
|
return updated;
|
|
222
283
|
}
|
|
223
284
|
export async function deleteSecret(secretId, ctx = requireVaultCtx()) {
|
|
@@ -235,6 +296,7 @@ export async function deleteSecret(secretId, ctx = requireVaultCtx()) {
|
|
|
235
296
|
await db
|
|
236
297
|
.delete(schema.vaultSecrets)
|
|
237
298
|
.where(and(eq(schema.vaultSecrets.id, secretId), ctxScope(schema.vaultSecrets, ctx)));
|
|
299
|
+
await cleanupSyncedCredentialKeysIfUnused(ctx, [existing.credentialKey]);
|
|
238
300
|
await recordVaultAudit({
|
|
239
301
|
action: "secret.deleted",
|
|
240
302
|
secretId,
|
|
@@ -377,12 +439,35 @@ export async function syncSecretsToCredentialStore(secrets, ctx) {
|
|
|
377
439
|
value: secret.value,
|
|
378
440
|
scope: target.scope,
|
|
379
441
|
scopeId: target.scopeId,
|
|
380
|
-
description:
|
|
442
|
+
description: `${VAULT_SYNC_DESCRIPTION_PREFIX} ${secret.name}`,
|
|
381
443
|
});
|
|
382
444
|
syncedKeys.push(secret.credentialKey);
|
|
383
445
|
}
|
|
384
446
|
return { ...target, keys: syncedKeys };
|
|
385
447
|
}
|
|
448
|
+
export async function cleanupSyncedCredentialKeysIfUnused(ctx, candidateKeys) {
|
|
449
|
+
const db = getDb();
|
|
450
|
+
const target = credentialStoreScopeForVaultCtx(ctx);
|
|
451
|
+
const keys = candidateKeys
|
|
452
|
+
? candidateKeys
|
|
453
|
+
: (await listAppSecretsForScope(target.scope, target.scopeId))
|
|
454
|
+
.filter((secret) => secret.description?.startsWith(VAULT_SYNC_DESCRIPTION_PREFIX))
|
|
455
|
+
.map((secret) => secret.key);
|
|
456
|
+
for (const key of new Set(keys.filter(Boolean))) {
|
|
457
|
+
const stillUsesKey = await db
|
|
458
|
+
.select({ id: schema.vaultSecrets.id })
|
|
459
|
+
.from(schema.vaultSecrets)
|
|
460
|
+
.where(and(eq(schema.vaultSecrets.credentialKey, key), ctxScope(schema.vaultSecrets, ctx)))
|
|
461
|
+
.limit(1);
|
|
462
|
+
if (!stillUsesKey[0]) {
|
|
463
|
+
await deleteAppSecret({
|
|
464
|
+
key,
|
|
465
|
+
scope: target.scope,
|
|
466
|
+
scopeId: target.scopeId,
|
|
467
|
+
});
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
}
|
|
386
471
|
// ─── Sync ──────────────────────────────────────────────────────
|
|
387
472
|
export async function syncGrantsToApp(appId, ctx = requireVaultCtx()) {
|
|
388
473
|
const db = getDb();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vault-store.js","sourceRoot":"","sources":["../../../src/server/lib/vault-store.ts"],"names":[],"mappings":"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","sourcesContent":["import crypto from \"node:crypto\";\nimport { and, desc, eq, isNull, or } from \"drizzle-orm\";\nimport { discoverAgents } from \"@agent-native/core/server/agent-discovery\";\nimport { writeAppSecret, type SecretScope } from \"@agent-native/core/secrets\";\nimport {\n getOrgSetting,\n getUserSetting,\n putOrgSetting,\n putUserSetting,\n} from \"@agent-native/core/settings\";\nimport { getDb, schema } from \"../../db/index.js\";\nimport {\n currentOwnerEmail,\n currentOrgId,\n recordAudit,\n} from \"./dispatch-store.js\";\n\nconst VAULT_ACCESS_SETTINGS_KEY = \"dispatch-vault-access-settings\";\n\nexport type VaultAccessMode = \"all-apps\" | \"manual\";\n\nexport interface VaultAccessSettings {\n mode: VaultAccessMode;\n scope: \"org\" | \"user\";\n scopeId: string;\n}\n\n/**\n * Caller-supplied access context for vault operations.\n *\n * Every getSecret / updateSecret / deleteSecret / createGrant call must\n * pass the ctx of the *current request* so the row is scoped to that\n * caller's tenant. Looking up a vault secret by id alone is unsafe — UUIDs\n * are not authorization. A row matches the ctx if either the caller owns\n * it or it lives in the caller's active org.\n */\nexport interface VaultCtx {\n ownerEmail: string;\n orgId: string | null;\n}\n\n/**\n * Build a VaultCtx from the current request. Throws if the request is\n * unauthenticated — the previous behavior of falling back to \"local@localhost\"\n * leaked rows across tenants when a misconfigured environment skipped auth.\n */\nexport function requireVaultCtx(): VaultCtx {\n const ownerEmail = currentOwnerEmail();\n if (!ownerEmail) {\n throw new Error(\"Vault operation requires an authenticated user\");\n }\n return { ownerEmail, orgId: currentOrgId() };\n}\n\n/** WHERE clause that limits a vault row to the caller's ownership scope. */\nfunction ctxScope<T extends { ownerEmail: any; orgId: any }>(\n table: T,\n ctx: VaultCtx,\n) {\n if (!ctx.orgId) {\n return and(eq(table.ownerEmail, ctx.ownerEmail), isNull(table.orgId));\n }\n return or(eq(table.ownerEmail, ctx.ownerEmail), eq(table.orgId, ctx.orgId));\n}\n\n/** Build a ctx that scopes to a specific row's owner/org (used when a\n * request approver acts on behalf of the original requester so the\n * created secret lands in the request's org). */\nfunction ctxForRow(row: {\n ownerEmail: string;\n orgId: string | null;\n}): VaultCtx {\n return { ownerEmail: row.ownerEmail, orgId: row.orgId };\n}\n\nfunction id() {\n return crypto.randomUUID();\n}\n\nfunction now() {\n return Date.now();\n}\n\nfunction safeJson(value: unknown) {\n return JSON.stringify(value ?? null);\n}\n\nfunction scopedFilter<T extends { ownerEmail: any; orgId: any }>(table: T) {\n return ctxScope(table, requireVaultCtx());\n}\n\nfunction normalizeCredentialKey(value: string) {\n return value.trim();\n}\n\nfunction vaultAccessScope() {\n const orgId = currentOrgId();\n if (orgId) return { scope: \"org\" as const, scopeId: orgId };\n return { scope: \"user\" as const, scopeId: currentOwnerEmail() };\n}\n\nfunction parseVaultAccessMode(value: unknown): VaultAccessMode {\n return value === \"manual\" ? \"manual\" : \"all-apps\";\n}\n\nexport async function getVaultAccessSettings(): Promise<VaultAccessSettings> {\n const scope = vaultAccessScope();\n const raw =\n scope.scope === \"org\"\n ? await getOrgSetting(scope.scopeId, VAULT_ACCESS_SETTINGS_KEY)\n : await getUserSetting(scope.scopeId, VAULT_ACCESS_SETTINGS_KEY);\n return {\n ...scope,\n mode: parseVaultAccessMode(raw?.mode),\n };\n}\n\nexport async function setVaultAccessSettings(input: {\n mode: VaultAccessMode;\n}): Promise<VaultAccessSettings> {\n const scope = vaultAccessScope();\n const next = { mode: parseVaultAccessMode(input.mode) };\n if (scope.scope === \"org\") {\n await putOrgSetting(scope.scopeId, VAULT_ACCESS_SETTINGS_KEY, next);\n } else {\n await putUserSetting(scope.scopeId, VAULT_ACCESS_SETTINGS_KEY, next);\n }\n await recordAudit({\n action: \"vault.access-settings.updated\",\n targetType: \"vault-settings\",\n targetId: VAULT_ACCESS_SETTINGS_KEY,\n summary:\n next.mode === \"all-apps\"\n ? \"Set vault access to all workspace apps\"\n : \"Set vault access to manual per-app grants\",\n metadata: next,\n });\n return getVaultAccessSettings();\n}\n\n// ─── Vault Audit ──────────────────────────────────────────────────\n\nexport async function recordVaultAudit(input: {\n action: string;\n secretId?: string | null;\n appId?: string | null;\n summary: string;\n metadata?: unknown;\n actor?: string;\n}) {\n const db = getDb();\n await db.insert(schema.vaultAuditLog).values({\n id: id(),\n ownerEmail: currentOwnerEmail(),\n orgId: currentOrgId(),\n secretId: input.secretId || null,\n appId: input.appId || null,\n action: input.action,\n actor: input.actor || currentOwnerEmail(),\n summary: input.summary,\n metadata: input.metadata ? safeJson(input.metadata) : null,\n createdAt: now(),\n });\n}\n\nexport async function listVaultAudit(limit = 50) {\n const db = getDb();\n return db\n .select()\n .from(schema.vaultAuditLog)\n .where(scopedFilter(schema.vaultAuditLog))\n .orderBy(desc(schema.vaultAuditLog.createdAt))\n .limit(limit);\n}\n\n// ─── Secrets ──────────────────────────────────────────────────────\n\nexport async function listSecrets() {\n const db = getDb();\n return db\n .select()\n .from(schema.vaultSecrets)\n .where(scopedFilter(schema.vaultSecrets))\n .orderBy(desc(schema.vaultSecrets.updatedAt));\n}\n\nexport async function getSecret(secretId: string, ctx: VaultCtx) {\n const db = getDb();\n const [row] = await db\n .select()\n .from(schema.vaultSecrets)\n .where(\n and(\n eq(schema.vaultSecrets.id, secretId),\n ctxScope(schema.vaultSecrets, ctx),\n ),\n )\n .limit(1);\n return row ?? null;\n}\n\nexport async function createSecret(\n input: {\n credentialKey: string;\n value: string;\n name: string;\n provider?: string | null;\n description?: string | null;\n },\n ctx: VaultCtx = requireVaultCtx(),\n) {\n const db = getDb();\n const timestamp = now();\n const credentialKey = normalizeCredentialKey(input.credentialKey);\n if (!credentialKey) throw new Error(\"Credential key is required\");\n const existing = await db\n .select()\n .from(schema.vaultSecrets)\n .where(\n and(\n eq(schema.vaultSecrets.credentialKey, credentialKey),\n ctxScope(schema.vaultSecrets, ctx),\n ),\n )\n .orderBy(desc(schema.vaultSecrets.updatedAt))\n .limit(1);\n\n if (existing[0]) {\n await db\n .update(schema.vaultSecrets)\n .set({\n name: input.name,\n credentialKey,\n value: input.value,\n provider: input.provider || null,\n description: input.description || null,\n updatedAt: timestamp,\n })\n .where(\n and(\n eq(schema.vaultSecrets.id, existing[0].id),\n ctxScope(schema.vaultSecrets, ctx),\n ),\n );\n\n await recordVaultAudit({\n action: \"secret.updated\",\n secretId: existing[0].id,\n summary: `Updated secret \"${input.name}\" (${credentialKey})`,\n metadata: { credentialKey, provider: input.provider },\n });\n\n await recordAudit({\n action: \"vault.secret.updated\",\n targetType: \"vault-secret\",\n targetId: existing[0].id,\n summary: `Updated vault secret \"${input.name}\" (${credentialKey})`,\n });\n\n const updated = await getSecret(existing[0].id, ctx);\n if (updated) await syncSecretsToCredentialStore([updated], ctx);\n return updated;\n }\n\n const secretId = id();\n const actor = ctx.ownerEmail;\n\n await db.insert(schema.vaultSecrets).values({\n id: secretId,\n ownerEmail: actor,\n orgId: ctx.orgId,\n name: input.name,\n credentialKey,\n value: input.value,\n provider: input.provider || null,\n description: input.description || null,\n createdBy: actor,\n createdAt: timestamp,\n updatedAt: timestamp,\n });\n\n await recordVaultAudit({\n action: \"secret.created\",\n secretId,\n summary: `Created secret \"${input.name}\" (${credentialKey})`,\n metadata: { credentialKey, provider: input.provider },\n });\n\n await recordAudit({\n action: \"vault.secret.created\",\n targetType: \"vault-secret\",\n targetId: secretId,\n summary: `Created vault secret \"${input.name}\" (${credentialKey})`,\n });\n\n const created = await getSecret(secretId, ctx);\n if (created) await syncSecretsToCredentialStore([created], ctx);\n return created;\n}\n\nexport async function updateSecret(\n secretId: string,\n value: string,\n ctx: VaultCtx = requireVaultCtx(),\n) {\n const db = getDb();\n const existing = await getSecret(secretId, ctx);\n if (!existing) throw new Error(\"Secret not found\");\n\n await db\n .update(schema.vaultSecrets)\n .set({ value, updatedAt: now() })\n .where(\n and(\n eq(schema.vaultSecrets.id, secretId),\n ctxScope(schema.vaultSecrets, ctx),\n ),\n );\n\n await recordVaultAudit({\n action: \"secret.updated\",\n secretId,\n summary: `Updated value for secret \"${existing.name}\" (${existing.credentialKey})`,\n });\n\n const updated = await getSecret(secretId, ctx);\n if (updated) await syncSecretsToCredentialStore([updated], ctx);\n return updated;\n}\n\nexport async function deleteSecret(\n secretId: string,\n ctx: VaultCtx = requireVaultCtx(),\n) {\n const db = getDb();\n const existing = await getSecret(secretId, ctx);\n if (!existing) throw new Error(\"Secret not found\");\n\n // Revoke all active grants first\n const grants = await listGrants({ secretId });\n for (const grant of grants) {\n if (grant.status === \"active\") {\n await revokeGrant(grant.id, ctx);\n }\n }\n\n await db\n .delete(schema.vaultSecrets)\n .where(\n and(\n eq(schema.vaultSecrets.id, secretId),\n ctxScope(schema.vaultSecrets, ctx),\n ),\n );\n\n await recordVaultAudit({\n action: \"secret.deleted\",\n secretId,\n summary: `Deleted secret \"${existing.name}\" (${existing.credentialKey})`,\n });\n\n await recordAudit({\n action: \"vault.secret.deleted\",\n targetType: \"vault-secret\",\n targetId: secretId,\n summary: `Deleted vault secret \"${existing.name}\" (${existing.credentialKey})`,\n });\n\n return existing;\n}\n\n// ─── Grants ──────────────────────────────────────────────────────\n\nexport async function listGrants(filter?: {\n secretId?: string;\n appId?: string;\n}) {\n const db = getDb();\n const conditions = [scopedFilter(schema.vaultGrants)];\n if (filter?.secretId) {\n conditions.push(eq(schema.vaultGrants.secretId, filter.secretId) as any);\n }\n if (filter?.appId) {\n conditions.push(eq(schema.vaultGrants.appId, filter.appId) as any);\n }\n return db\n .select()\n .from(schema.vaultGrants)\n .where(and(...conditions))\n .orderBy(desc(schema.vaultGrants.updatedAt));\n}\n\nexport async function getGrant(\n grantId: string,\n ctx: VaultCtx = requireVaultCtx(),\n) {\n const db = getDb();\n const [row] = await db\n .select()\n .from(schema.vaultGrants)\n .where(\n and(\n eq(schema.vaultGrants.id, grantId),\n ctxScope(schema.vaultGrants, ctx),\n ),\n )\n .limit(1);\n return row ?? null;\n}\n\nexport async function createGrant(\n secretId: string,\n appId: string,\n ctx: VaultCtx = requireVaultCtx(),\n) {\n const db = getDb();\n const secret = await getSecret(secretId, ctx);\n if (!secret) throw new Error(\"Secret not found\");\n\n const timestamp = now();\n const grantId = id();\n const actor = ctx.ownerEmail;\n\n await db.insert(schema.vaultGrants).values({\n id: grantId,\n ownerEmail: actor,\n orgId: ctx.orgId,\n secretId,\n appId,\n grantedBy: actor,\n status: \"active\",\n syncedAt: null,\n createdAt: timestamp,\n updatedAt: timestamp,\n });\n\n await recordVaultAudit({\n action: \"grant.created\",\n secretId,\n appId,\n summary: `Granted \"${secret.name}\" (${secret.credentialKey}) to ${appId}`,\n metadata: { grantId },\n });\n\n await recordAudit({\n action: \"vault.grant.created\",\n targetType: \"vault-grant\",\n targetId: grantId,\n summary: `Granted vault secret \"${secret.name}\" to ${appId}`,\n });\n\n return getGrant(grantId);\n}\n\nexport async function grantSecretsToApp(\n secretIds: string[],\n appId: string,\n ctx: VaultCtx = requireVaultCtx(),\n) {\n const access = await getVaultAccessSettings();\n const uniqueSecretIds = Array.from(new Set(secretIds));\n if (access.mode === \"all-apps\") {\n return {\n appId,\n accessMode: access.mode,\n created: [],\n skipped: uniqueSecretIds,\n };\n }\n const existingActive = (await listGrants({ appId })).filter(\n (grant) => grant.status === \"active\",\n );\n const existingSecretIds = new Set(\n existingActive.map((grant) => grant.secretId),\n );\n const created = [];\n const skipped: string[] = [];\n\n for (const secretId of uniqueSecretIds) {\n if (existingSecretIds.has(secretId)) {\n skipped.push(secretId);\n continue;\n }\n const grant = await createGrant(secretId, appId, ctx);\n if (grant) {\n created.push(grant);\n existingSecretIds.add(secretId);\n }\n }\n\n return { appId, accessMode: access.mode, created, skipped };\n}\n\nexport async function revokeGrant(\n grantId: string,\n ctx: VaultCtx = requireVaultCtx(),\n) {\n const db = getDb();\n const grant = await getGrant(grantId, ctx);\n if (!grant) throw new Error(\"Grant not found\");\n\n const secret = await getSecret(grant.secretId, ctx);\n\n await db\n .update(schema.vaultGrants)\n .set({ status: \"revoked\", updatedAt: now() })\n .where(\n and(\n eq(schema.vaultGrants.id, grantId),\n ctxScope(schema.vaultGrants, ctx),\n ),\n );\n\n await recordVaultAudit({\n action: \"grant.revoked\",\n secretId: grant.secretId,\n appId: grant.appId,\n summary: `Revoked ${secret?.credentialKey || grant.secretId} from ${grant.appId}`,\n metadata: { grantId },\n });\n\n await recordAudit({\n action: \"vault.grant.revoked\",\n targetType: \"vault-grant\",\n targetId: grantId,\n summary: `Revoked vault secret \"${secret?.name || grant.secretId}\" from ${grant.appId}`,\n });\n\n return getGrant(grantId, ctx);\n}\n\n// ─── Shared Credential Store Sync ─────────────────────────────────\n\ntype VaultSecretRow = typeof schema.vaultSecrets.$inferSelect;\n\nexport function credentialStoreScopeForVaultCtx(ctx: VaultCtx): {\n scope: Extract<SecretScope, \"org\" | \"workspace\">;\n scopeId: string;\n} {\n if (ctx.orgId) return { scope: \"org\", scopeId: ctx.orgId };\n return { scope: \"workspace\", scopeId: `solo:${ctx.ownerEmail}` };\n}\n\nexport async function syncSecretsToCredentialStore(\n secrets: VaultSecretRow[],\n ctx: VaultCtx,\n) {\n const target = credentialStoreScopeForVaultCtx(ctx);\n const syncedKeys: string[] = [];\n\n for (const secret of secrets) {\n if (!secret.credentialKey || !secret.value) continue;\n await writeAppSecret({\n key: secret.credentialKey,\n value: secret.value,\n scope: target.scope,\n scopeId: target.scopeId,\n description: `Synced from Dispatch vault: ${secret.name}`,\n });\n syncedKeys.push(secret.credentialKey);\n }\n\n return { ...target, keys: syncedKeys };\n}\n\n// ─── Sync ──────────────────────────────────────────────────────\n\nexport async function syncGrantsToApp(\n appId: string,\n ctx: VaultCtx = requireVaultCtx(),\n) {\n const db = getDb();\n const access = await getVaultAccessSettings();\n const agents = await discoverAgents(\"dispatch\");\n const agent = agents.find((a) => a.id === appId);\n if (!agent) throw new Error(`App \"${appId}\" not found in agent registry`);\n\n const secretsToSync: VaultSecretRow[] = [];\n const activeGrants =\n access.mode === \"manual\"\n ? (await listGrants({ appId })).filter((g) => g.status === \"active\")\n : [];\n\n if (access.mode === \"all-apps\") {\n const secrets = await listSecrets();\n for (const secret of secrets) {\n secretsToSync.push(secret);\n }\n } else {\n for (const grant of activeGrants) {\n const secret = await getSecret(grant.secretId, ctx);\n if (secret) {\n secretsToSync.push(secret);\n }\n }\n }\n\n if (secretsToSync.length === 0) {\n return { appId, accessMode: access.mode, synced: 0, keys: [] };\n }\n\n const credentialStoreSync = await syncSecretsToCredentialStore(\n secretsToSync,\n ctx,\n );\n const vars = secretsToSync.map((secret) => ({\n key: secret.credentialKey,\n value: secret.value,\n }));\n let envVarSync:\n | { status: \"synced\"; keys: string[] }\n | { status: \"skipped\"; reason: string }\n | { status: \"failed\"; reason: string };\n\n // Best-effort push to the app's env-vars endpoint for local/dev apps that\n // still read process.env directly. Production/shared-DB apps intentionally\n // reject env writes; the encrypted app_secrets sync above is the canonical\n // path for request-scoped credentials.\n try {\n const res = await fetch(`${agent.url}/_agent-native/env-vars`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ vars }),\n });\n\n if (res.ok) {\n const result = await res.json();\n envVarSync = { status: \"synced\", keys: result.saved || [] };\n } else {\n const err = await res.text().catch(() => \"Unknown error\");\n envVarSync = { status: \"skipped\", reason: err };\n }\n } catch (err) {\n envVarSync = {\n status: \"failed\",\n reason: err instanceof Error ? err.message : String(err),\n };\n }\n\n const syncedKeys = credentialStoreSync.keys;\n const timestamp = now();\n\n // Update syncedAt on grants that were successfully pushed to the shared\n // credential store. All-apps mode has no explicit grant rows to update.\n for (const grant of activeGrants) {\n const secret = await getSecret(grant.secretId, ctx);\n if (secret && syncedKeys.includes(secret.credentialKey)) {\n await db\n .update(schema.vaultGrants)\n .set({ syncedAt: timestamp, updatedAt: timestamp })\n .where(eq(schema.vaultGrants.id, grant.id));\n }\n }\n\n await recordVaultAudit({\n action: \"secret.synced\",\n appId,\n summary: `Synced ${syncedKeys.length} secret(s) to ${appId}: ${syncedKeys.join(\", \")}`,\n metadata: {\n syncedKeys,\n accessMode: access.mode,\n credentialStore: {\n scope: credentialStoreSync.scope,\n scopeId: credentialStoreSync.scopeId,\n },\n envVars: envVarSync,\n },\n });\n\n return {\n appId,\n accessMode: access.mode,\n synced: syncedKeys.length,\n keys: syncedKeys,\n credentialStore: {\n scope: credentialStoreSync.scope,\n scopeId: credentialStoreSync.scopeId,\n synced: credentialStoreSync.keys.length,\n },\n envVars: envVarSync,\n };\n}\n\n// ─── Requests ──────────────────────────────────────────────────────\n\nexport async function listRequests(filter?: { status?: string }) {\n const db = getDb();\n const conditions = [scopedFilter(schema.vaultRequests)];\n if (filter?.status) {\n conditions.push(eq(schema.vaultRequests.status, filter.status) as any);\n }\n return db\n .select()\n .from(schema.vaultRequests)\n .where(and(...conditions))\n .orderBy(desc(schema.vaultRequests.updatedAt));\n}\n\nexport async function getRequest(\n requestId: string,\n ctx: VaultCtx = requireVaultCtx(),\n) {\n const db = getDb();\n const [row] = await db\n .select()\n .from(schema.vaultRequests)\n .where(\n and(\n eq(schema.vaultRequests.id, requestId),\n ctxScope(schema.vaultRequests, ctx),\n ),\n )\n .limit(1);\n return row ?? null;\n}\n\nexport async function createRequest(input: {\n credentialKey: string;\n appId: string;\n reason?: string | null;\n}) {\n const db = getDb();\n const timestamp = now();\n const requestId = id();\n const actor = currentOwnerEmail();\n\n await db.insert(schema.vaultRequests).values({\n id: requestId,\n ownerEmail: actor,\n orgId: currentOrgId(),\n credentialKey: input.credentialKey,\n appId: input.appId,\n reason: input.reason || null,\n requestedBy: actor,\n status: \"pending\",\n reviewedBy: null,\n reviewedAt: null,\n createdAt: timestamp,\n updatedAt: timestamp,\n });\n\n await recordVaultAudit({\n action: \"request.created\",\n appId: input.appId,\n summary: `${actor} requested ${input.credentialKey} for ${input.appId}`,\n metadata: { requestId, reason: input.reason },\n });\n\n await notifyAdminsOfRequest(requestId, input);\n\n return getRequest(requestId);\n}\n\nexport async function approveRequest(\n requestId: string,\n secretValue: string,\n secretName?: string,\n ctx: VaultCtx = requireVaultCtx(),\n) {\n const db = getDb();\n const request = await getRequest(requestId, ctx);\n if (!request) throw new Error(\"Request not found\");\n if (request.status !== \"pending\") {\n throw new Error(\"Only pending requests can be approved\");\n }\n\n const timestamp = now();\n const reviewer = ctx.ownerEmail;\n\n // Update request status — scoped to caller's tenant.\n await db\n .update(schema.vaultRequests)\n .set({\n status: \"approved\",\n reviewedBy: reviewer,\n reviewedAt: timestamp,\n updatedAt: timestamp,\n })\n .where(\n and(\n eq(schema.vaultRequests.id, requestId),\n ctxScope(schema.vaultRequests, ctx),\n ),\n );\n\n // Secret + grant must land in the REQUEST's tenant, not the approver's\n // (the approver may be acting on behalf of another user in the same org).\n const requestCtx = ctxForRow(request);\n\n // Check if secret already exists in the request's tenant for this key.\n const existingSecrets = await db\n .select()\n .from(schema.vaultSecrets)\n .where(\n and(\n eq(schema.vaultSecrets.credentialKey, request.credentialKey),\n ctxScope(schema.vaultSecrets, requestCtx),\n ),\n );\n let secret = existingSecrets[0] ?? null;\n\n if (!secret) {\n secret = await createSecret(\n {\n credentialKey: request.credentialKey,\n value: secretValue,\n name: secretName || request.credentialKey,\n },\n requestCtx,\n );\n }\n\n if (secret) {\n // Create the grant in the request's tenant as well.\n await createGrant(secret.id, request.appId, requestCtx);\n }\n\n await recordVaultAudit({\n action: \"request.approved\",\n appId: request.appId,\n summary: `Approved ${request.credentialKey} for ${request.appId} (requested by ${request.requestedBy})`,\n metadata: { requestId, reviewer },\n });\n\n return getRequest(requestId, ctx);\n}\n\nexport async function denyRequest(\n requestId: string,\n reason?: string | null,\n ctx: VaultCtx = requireVaultCtx(),\n) {\n const db = getDb();\n const request = await getRequest(requestId, ctx);\n if (!request) throw new Error(\"Request not found\");\n if (request.status !== \"pending\") {\n throw new Error(\"Only pending requests can be denied\");\n }\n\n const timestamp = now();\n const reviewer = ctx.ownerEmail;\n\n await db\n .update(schema.vaultRequests)\n .set({\n status: \"denied\",\n reviewedBy: reviewer,\n reviewedAt: timestamp,\n updatedAt: timestamp,\n })\n .where(\n and(\n eq(schema.vaultRequests.id, requestId),\n ctxScope(schema.vaultRequests, ctx),\n ),\n );\n\n await recordVaultAudit({\n action: \"request.denied\",\n appId: request.appId,\n summary: `Denied ${request.credentialKey} for ${request.appId} (requested by ${request.requestedBy})`,\n metadata: { requestId, reviewer, reason },\n });\n\n return getRequest(requestId, ctx);\n}\n\n// ─── Integrations Catalog ────────────────────────────────────────\n\nexport interface IntegrationEntry {\n key: string;\n label: string;\n required: boolean;\n configured: boolean;\n vaultGranted: boolean;\n vaultSecretId?: string;\n}\n\nexport interface AppIntegrations {\n appId: string;\n appName: string;\n url: string;\n color: string;\n integrations: IntegrationEntry[];\n vaultAccessMode: VaultAccessMode;\n reachable: boolean;\n}\n\nexport async function listIntegrationsCatalog(): Promise<AppIntegrations[]> {\n const access = await getVaultAccessSettings();\n const agents = await discoverAgents(\"dispatch\");\n const grants = await listGrants();\n const secrets = await listSecrets();\n\n const secretByKey = new Map(secrets.map((s) => [s.credentialKey, s]));\n\n const results: AppIntegrations[] = [];\n\n for (const agent of agents) {\n try {\n const res = await fetch(`${agent.url}/_agent-native/env-status`, {\n signal: AbortSignal.timeout(3000),\n });\n if (!res.ok) {\n results.push({\n appId: agent.id,\n appName: agent.name,\n url: agent.url,\n color: agent.color,\n integrations: [],\n vaultAccessMode: access.mode,\n reachable: false,\n });\n continue;\n }\n\n const envStatus: Array<{\n key: string;\n label: string;\n required: boolean;\n configured: boolean;\n }> = await res.json();\n\n const appGrants = grants.filter(\n (g) => g.appId === agent.id && g.status === \"active\",\n );\n const grantedSecretIds = new Set(appGrants.map((g) => g.secretId));\n\n const integrations: IntegrationEntry[] = envStatus.map((env) => {\n const matchingSecret = secretByKey.get(env.key);\n return {\n key: env.key,\n label: env.label,\n required: env.required,\n configured: env.configured,\n vaultGranted:\n !!matchingSecret &&\n (access.mode === \"all-apps\" ||\n grantedSecretIds.has(matchingSecret.id)),\n vaultSecretId: matchingSecret?.id,\n };\n });\n\n results.push({\n appId: agent.id,\n appName: agent.name,\n url: agent.url,\n color: agent.color,\n integrations,\n vaultAccessMode: access.mode,\n reachable: true,\n });\n } catch {\n results.push({\n appId: agent.id,\n appName: agent.name,\n url: agent.url,\n color: agent.color,\n integrations: [],\n vaultAccessMode: access.mode,\n reachable: false,\n });\n }\n }\n\n return results;\n}\n\n// ─── Vault Overview (for dashboard) ──────────────────────────────\n\nexport async function listVaultOverview() {\n const [secrets, grants, requests, access] = await Promise.all([\n listSecrets(),\n listGrants(),\n listRequests(),\n getVaultAccessSettings(),\n ]);\n const manualGrantCount = grants.filter((g) => g.status === \"active\").length;\n\n return {\n accessMode: access.mode,\n secretCount: secrets.length,\n activeGrantCount:\n access.mode === \"all-apps\" ? secrets.length : manualGrantCount,\n manualGrantCount,\n pendingRequestCount: requests.filter((r) => r.status === \"pending\").length,\n };\n}\n\n// ─── SendGrid Notifications ──────────────────────────────────────\n\nasync function notifyAdminsOfRequest(\n requestId: string,\n input: { credentialKey: string; appId: string; reason?: string | null },\n) {\n const apiKey = process.env.SENDGRID_API_KEY;\n const from = process.env.SENDGRID_FROM_EMAIL;\n const appUrl = process.env.APP_URL;\n if (!apiKey || !from || !appUrl) return;\n\n // Use approval policy approver emails as admin notification targets\n const { getApprovalPolicy } = await import(\"./dispatch-store.js\");\n const policy = await getApprovalPolicy();\n if (policy.approverEmails.length === 0) return;\n\n const body = [\n `Secret request: ${input.credentialKey} for ${input.appId}`,\n input.reason ? `Reason: ${input.reason}` : \"\",\n `Requested by: ${currentOwnerEmail()}`,\n \"\",\n `Review it here: ${appUrl}/vault`,\n ]\n .filter(Boolean)\n .join(\"\\n\");\n\n await fetch(\"https://api.sendgrid.com/v3/mail/send\", {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n personalizations: [\n {\n to: policy.approverEmails.map((email) => ({ email })),\n subject: `Vault request: ${input.credentialKey} for ${input.appId}`,\n },\n ],\n from: { email: from },\n content: [{ type: \"text/plain\", value: body }],\n custom_args: { requestId },\n }),\n }).catch(() => {});\n}\n"]}
|
|
1
|
+
{"version":3,"file":"vault-store.js","sourceRoot":"","sources":["../../../src/server/lib/vault-store.ts"],"names":[],"mappings":"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","sourcesContent":["import crypto from \"node:crypto\";\nimport { and, desc, eq, isNull, or } from \"drizzle-orm\";\nimport { discoverAgents } from \"@agent-native/core/server/agent-discovery\";\nimport {\n deleteAppSecret,\n listAppSecretsForScope,\n writeAppSecret,\n type SecretScope,\n} from \"@agent-native/core/secrets\";\nimport {\n getOrgSetting,\n getUserSetting,\n putOrgSetting,\n putUserSetting,\n} from \"@agent-native/core/settings\";\nimport { getDb, schema } from \"../../db/index.js\";\nimport {\n currentOwnerEmail,\n currentOrgId,\n recordAudit,\n} from \"./dispatch-store.js\";\n\nconst VAULT_ACCESS_SETTINGS_KEY = \"dispatch-vault-access-settings\";\nconst VAULT_SYNC_DESCRIPTION_PREFIX = \"Synced from Dispatch vault:\";\n\nexport type VaultAccessMode = \"all-apps\" | \"manual\";\n\nexport interface VaultAccessSettings {\n mode: VaultAccessMode;\n scope: \"org\" | \"user\";\n scopeId: string;\n}\n\n/**\n * Caller-supplied access context for vault operations.\n *\n * Every getSecret / updateSecret / deleteSecret / createGrant call must\n * pass the ctx of the *current request* so the row is scoped to that\n * caller's tenant. Looking up a vault secret by id alone is unsafe — UUIDs\n * are not authorization. A row matches the ctx if either the caller owns\n * it or it lives in the caller's active org.\n */\nexport interface VaultCtx {\n ownerEmail: string;\n orgId: string | null;\n}\n\n/**\n * Build a VaultCtx from the current request. Throws if the request is\n * unauthenticated — the previous behavior of falling back to \"local@localhost\"\n * leaked rows across tenants when a misconfigured environment skipped auth.\n */\nexport function requireVaultCtx(): VaultCtx {\n const ownerEmail = currentOwnerEmail();\n if (!ownerEmail) {\n throw new Error(\"Vault operation requires an authenticated user\");\n }\n return { ownerEmail, orgId: currentOrgId() };\n}\n\n/** WHERE clause that limits a vault row to the caller's ownership scope. */\nfunction ctxScope<T extends { ownerEmail: any; orgId: any }>(\n table: T,\n ctx: VaultCtx,\n) {\n if (!ctx.orgId) {\n return and(eq(table.ownerEmail, ctx.ownerEmail), isNull(table.orgId));\n }\n return or(eq(table.ownerEmail, ctx.ownerEmail), eq(table.orgId, ctx.orgId));\n}\n\n/** Build a ctx that scopes to a specific row's owner/org (used when a\n * request approver acts on behalf of the original requester so the\n * created secret lands in the request's org). */\nfunction ctxForRow(row: {\n ownerEmail: string;\n orgId: string | null;\n}): VaultCtx {\n return { ownerEmail: row.ownerEmail, orgId: row.orgId };\n}\n\nfunction id() {\n return crypto.randomUUID();\n}\n\nfunction now() {\n return Date.now();\n}\n\nfunction safeJson(value: unknown) {\n return JSON.stringify(value ?? null);\n}\n\nfunction scopedFilter<T extends { ownerEmail: any; orgId: any }>(table: T) {\n return ctxScope(table, requireVaultCtx());\n}\n\nfunction normalizeCredentialKey(value: string) {\n return value.trim();\n}\n\nfunction vaultAccessScope() {\n const orgId = currentOrgId();\n if (orgId) return { scope: \"org\" as const, scopeId: orgId };\n return { scope: \"user\" as const, scopeId: currentOwnerEmail() };\n}\n\nfunction parseVaultAccessMode(value: unknown): VaultAccessMode {\n return value === \"manual\" ? \"manual\" : \"all-apps\";\n}\n\nexport async function getVaultAccessSettings(): Promise<VaultAccessSettings> {\n const scope = vaultAccessScope();\n const raw =\n scope.scope === \"org\"\n ? await getOrgSetting(scope.scopeId, VAULT_ACCESS_SETTINGS_KEY)\n : await getUserSetting(scope.scopeId, VAULT_ACCESS_SETTINGS_KEY);\n return {\n ...scope,\n mode: parseVaultAccessMode(raw?.mode),\n };\n}\n\nexport async function setVaultAccessSettings(input: {\n mode: VaultAccessMode;\n}): Promise<VaultAccessSettings> {\n const scope = vaultAccessScope();\n const next = { mode: parseVaultAccessMode(input.mode) };\n if (scope.scope === \"org\") {\n await putOrgSetting(scope.scopeId, VAULT_ACCESS_SETTINGS_KEY, next);\n } else {\n await putUserSetting(scope.scopeId, VAULT_ACCESS_SETTINGS_KEY, next);\n }\n await recordAudit({\n action: \"vault.access-settings.updated\",\n targetType: \"vault-settings\",\n targetId: VAULT_ACCESS_SETTINGS_KEY,\n summary:\n next.mode === \"all-apps\"\n ? \"Set vault access to all workspace apps\"\n : \"Set vault access to manual per-app grants\",\n metadata: next,\n });\n return getVaultAccessSettings();\n}\n\n// ─── Vault Audit ──────────────────────────────────────────────────\n\nexport async function recordVaultAudit(input: {\n action: string;\n secretId?: string | null;\n appId?: string | null;\n summary: string;\n metadata?: unknown;\n actor?: string;\n}) {\n const db = getDb();\n await db.insert(schema.vaultAuditLog).values({\n id: id(),\n ownerEmail: currentOwnerEmail(),\n orgId: currentOrgId(),\n secretId: input.secretId || null,\n appId: input.appId || null,\n action: input.action,\n actor: input.actor || currentOwnerEmail(),\n summary: input.summary,\n metadata: input.metadata ? safeJson(input.metadata) : null,\n createdAt: now(),\n });\n}\n\nexport async function listVaultAudit(limit = 50) {\n const db = getDb();\n return db\n .select()\n .from(schema.vaultAuditLog)\n .where(scopedFilter(schema.vaultAuditLog))\n .orderBy(desc(schema.vaultAuditLog.createdAt))\n .limit(limit);\n}\n\n// ─── Secrets ──────────────────────────────────────────────────────\n\nexport async function listSecrets() {\n const db = getDb();\n return db\n .select()\n .from(schema.vaultSecrets)\n .where(scopedFilter(schema.vaultSecrets))\n .orderBy(desc(schema.vaultSecrets.updatedAt));\n}\n\nexport async function getSecret(secretId: string, ctx: VaultCtx) {\n const db = getDb();\n const [row] = await db\n .select()\n .from(schema.vaultSecrets)\n .where(\n and(\n eq(schema.vaultSecrets.id, secretId),\n ctxScope(schema.vaultSecrets, ctx),\n ),\n )\n .limit(1);\n return row ?? null;\n}\n\nexport async function createSecret(\n input: {\n credentialKey: string;\n value: string;\n name: string;\n provider?: string | null;\n description?: string | null;\n },\n ctx: VaultCtx = requireVaultCtx(),\n) {\n const db = getDb();\n const timestamp = now();\n const credentialKey = normalizeCredentialKey(input.credentialKey);\n if (!credentialKey) throw new Error(\"Credential key is required\");\n const existing = await db\n .select()\n .from(schema.vaultSecrets)\n .where(\n and(\n eq(schema.vaultSecrets.credentialKey, credentialKey),\n ctxScope(schema.vaultSecrets, ctx),\n ),\n )\n .orderBy(desc(schema.vaultSecrets.updatedAt))\n .limit(1);\n\n if (existing[0]) {\n await db\n .update(schema.vaultSecrets)\n .set({\n name: input.name,\n credentialKey,\n value: input.value,\n provider: input.provider || null,\n description: input.description || null,\n updatedAt: timestamp,\n })\n .where(\n and(\n eq(schema.vaultSecrets.id, existing[0].id),\n ctxScope(schema.vaultSecrets, ctx),\n ),\n );\n\n await recordVaultAudit({\n action: \"secret.updated\",\n secretId: existing[0].id,\n summary: `Updated secret \"${input.name}\" (${credentialKey})`,\n metadata: { credentialKey, provider: input.provider },\n });\n\n await recordAudit({\n action: \"vault.secret.updated\",\n targetType: \"vault-secret\",\n targetId: existing[0].id,\n summary: `Updated vault secret \"${input.name}\" (${credentialKey})`,\n });\n\n const updated = await getSecret(existing[0].id, ctx);\n if (updated) await syncSecretsToCredentialStore([updated], ctx);\n return updated;\n }\n\n const secretId = id();\n const actor = ctx.ownerEmail;\n\n await db.insert(schema.vaultSecrets).values({\n id: secretId,\n ownerEmail: actor,\n orgId: ctx.orgId,\n name: input.name,\n credentialKey,\n value: input.value,\n provider: input.provider || null,\n description: input.description || null,\n createdBy: actor,\n createdAt: timestamp,\n updatedAt: timestamp,\n });\n\n await recordVaultAudit({\n action: \"secret.created\",\n secretId,\n summary: `Created secret \"${input.name}\" (${credentialKey})`,\n metadata: { credentialKey, provider: input.provider },\n });\n\n await recordAudit({\n action: \"vault.secret.created\",\n targetType: \"vault-secret\",\n targetId: secretId,\n summary: `Created vault secret \"${input.name}\" (${credentialKey})`,\n });\n\n const created = await getSecret(secretId, ctx);\n if (created) await syncSecretsToCredentialStore([created], ctx);\n return created;\n}\n\nexport async function updateSecret(\n secretId: string,\n input:\n | string\n | {\n credentialKey?: string;\n value?: string;\n name?: string;\n provider?: string | null;\n description?: string | null;\n },\n ctx: VaultCtx = requireVaultCtx(),\n) {\n const db = getDb();\n const existing = await getSecret(secretId, ctx);\n if (!existing) throw new Error(\"Secret not found\");\n const patch = typeof input === \"string\" ? { value: input } : input;\n const credentialKey =\n patch.credentialKey !== undefined\n ? normalizeCredentialKey(patch.credentialKey)\n : existing.credentialKey;\n if (!credentialKey) throw new Error(\"Credential key is required\");\n const name = patch.name !== undefined ? patch.name.trim() : existing.name;\n if (!name) throw new Error(\"Secret name is required\");\n const value = patch.value !== undefined ? patch.value : existing.value;\n if (!value) throw new Error(\"Secret value is required\");\n const provider =\n patch.provider !== undefined ? patch.provider || null : existing.provider;\n const description =\n patch.description !== undefined\n ? patch.description || null\n : existing.description;\n\n if (credentialKey !== existing.credentialKey) {\n const conflict = await db\n .select({ id: schema.vaultSecrets.id })\n .from(schema.vaultSecrets)\n .where(\n and(\n eq(schema.vaultSecrets.credentialKey, credentialKey),\n ctxScope(schema.vaultSecrets, ctx),\n ),\n )\n .limit(1);\n if (conflict[0] && conflict[0].id !== secretId) {\n throw new Error(`Credential key \"${credentialKey}\" is already in use`);\n }\n }\n\n await db\n .update(schema.vaultSecrets)\n .set({\n name,\n credentialKey,\n value,\n provider,\n description,\n updatedAt: now(),\n })\n .where(\n and(\n eq(schema.vaultSecrets.id, secretId),\n ctxScope(schema.vaultSecrets, ctx),\n ),\n );\n\n const auditMetadata = {\n name,\n previousName: name !== existing.name ? existing.name : undefined,\n credentialKey,\n previousCredentialKey:\n credentialKey !== existing.credentialKey\n ? existing.credentialKey\n : undefined,\n provider,\n previousProvider:\n provider !== existing.provider ? existing.provider : undefined,\n description,\n previousDescription:\n description !== existing.description ? existing.description : undefined,\n valueChanged: value !== existing.value ? true : undefined,\n };\n\n await recordVaultAudit({\n action: \"secret.updated\",\n secretId,\n summary: `Updated secret \"${name}\" (${credentialKey})`,\n metadata: auditMetadata,\n });\n\n await recordAudit({\n action: \"vault.secret.updated\",\n targetType: \"vault-secret\",\n targetId: secretId,\n summary: `Updated vault secret \"${name}\" (${credentialKey})`,\n metadata: auditMetadata,\n });\n\n const updated = await getSecret(secretId, ctx);\n if (updated) await syncSecretsToCredentialStore([updated], ctx);\n if (updated && credentialKey !== existing.credentialKey) {\n await cleanupSyncedCredentialKeysIfUnused(ctx, [existing.credentialKey]);\n } else if (patch.credentialKey !== undefined) {\n await cleanupSyncedCredentialKeysIfUnused(ctx);\n }\n return updated;\n}\n\nexport async function deleteSecret(\n secretId: string,\n ctx: VaultCtx = requireVaultCtx(),\n) {\n const db = getDb();\n const existing = await getSecret(secretId, ctx);\n if (!existing) throw new Error(\"Secret not found\");\n\n // Revoke all active grants first\n const grants = await listGrants({ secretId });\n for (const grant of grants) {\n if (grant.status === \"active\") {\n await revokeGrant(grant.id, ctx);\n }\n }\n\n await db\n .delete(schema.vaultSecrets)\n .where(\n and(\n eq(schema.vaultSecrets.id, secretId),\n ctxScope(schema.vaultSecrets, ctx),\n ),\n );\n await cleanupSyncedCredentialKeysIfUnused(ctx, [existing.credentialKey]);\n\n await recordVaultAudit({\n action: \"secret.deleted\",\n secretId,\n summary: `Deleted secret \"${existing.name}\" (${existing.credentialKey})`,\n });\n\n await recordAudit({\n action: \"vault.secret.deleted\",\n targetType: \"vault-secret\",\n targetId: secretId,\n summary: `Deleted vault secret \"${existing.name}\" (${existing.credentialKey})`,\n });\n\n return existing;\n}\n\n// ─── Grants ──────────────────────────────────────────────────────\n\nexport async function listGrants(filter?: {\n secretId?: string;\n appId?: string;\n}) {\n const db = getDb();\n const conditions = [scopedFilter(schema.vaultGrants)];\n if (filter?.secretId) {\n conditions.push(eq(schema.vaultGrants.secretId, filter.secretId) as any);\n }\n if (filter?.appId) {\n conditions.push(eq(schema.vaultGrants.appId, filter.appId) as any);\n }\n return db\n .select()\n .from(schema.vaultGrants)\n .where(and(...conditions))\n .orderBy(desc(schema.vaultGrants.updatedAt));\n}\n\nexport async function getGrant(\n grantId: string,\n ctx: VaultCtx = requireVaultCtx(),\n) {\n const db = getDb();\n const [row] = await db\n .select()\n .from(schema.vaultGrants)\n .where(\n and(\n eq(schema.vaultGrants.id, grantId),\n ctxScope(schema.vaultGrants, ctx),\n ),\n )\n .limit(1);\n return row ?? null;\n}\n\nexport async function createGrant(\n secretId: string,\n appId: string,\n ctx: VaultCtx = requireVaultCtx(),\n) {\n const db = getDb();\n const secret = await getSecret(secretId, ctx);\n if (!secret) throw new Error(\"Secret not found\");\n\n const timestamp = now();\n const grantId = id();\n const actor = ctx.ownerEmail;\n\n await db.insert(schema.vaultGrants).values({\n id: grantId,\n ownerEmail: actor,\n orgId: ctx.orgId,\n secretId,\n appId,\n grantedBy: actor,\n status: \"active\",\n syncedAt: null,\n createdAt: timestamp,\n updatedAt: timestamp,\n });\n\n await recordVaultAudit({\n action: \"grant.created\",\n secretId,\n appId,\n summary: `Granted \"${secret.name}\" (${secret.credentialKey}) to ${appId}`,\n metadata: { grantId },\n });\n\n await recordAudit({\n action: \"vault.grant.created\",\n targetType: \"vault-grant\",\n targetId: grantId,\n summary: `Granted vault secret \"${secret.name}\" to ${appId}`,\n });\n\n return getGrant(grantId);\n}\n\nexport async function grantSecretsToApp(\n secretIds: string[],\n appId: string,\n ctx: VaultCtx = requireVaultCtx(),\n) {\n const access = await getVaultAccessSettings();\n const uniqueSecretIds = Array.from(new Set(secretIds));\n if (access.mode === \"all-apps\") {\n return {\n appId,\n accessMode: access.mode,\n created: [],\n skipped: uniqueSecretIds,\n };\n }\n const existingActive = (await listGrants({ appId })).filter(\n (grant) => grant.status === \"active\",\n );\n const existingSecretIds = new Set(\n existingActive.map((grant) => grant.secretId),\n );\n const created = [];\n const skipped: string[] = [];\n\n for (const secretId of uniqueSecretIds) {\n if (existingSecretIds.has(secretId)) {\n skipped.push(secretId);\n continue;\n }\n const grant = await createGrant(secretId, appId, ctx);\n if (grant) {\n created.push(grant);\n existingSecretIds.add(secretId);\n }\n }\n\n return { appId, accessMode: access.mode, created, skipped };\n}\n\nexport async function revokeGrant(\n grantId: string,\n ctx: VaultCtx = requireVaultCtx(),\n) {\n const db = getDb();\n const grant = await getGrant(grantId, ctx);\n if (!grant) throw new Error(\"Grant not found\");\n\n const secret = await getSecret(grant.secretId, ctx);\n\n await db\n .update(schema.vaultGrants)\n .set({ status: \"revoked\", updatedAt: now() })\n .where(\n and(\n eq(schema.vaultGrants.id, grantId),\n ctxScope(schema.vaultGrants, ctx),\n ),\n );\n\n await recordVaultAudit({\n action: \"grant.revoked\",\n secretId: grant.secretId,\n appId: grant.appId,\n summary: `Revoked ${secret?.credentialKey || grant.secretId} from ${grant.appId}`,\n metadata: { grantId },\n });\n\n await recordAudit({\n action: \"vault.grant.revoked\",\n targetType: \"vault-grant\",\n targetId: grantId,\n summary: `Revoked vault secret \"${secret?.name || grant.secretId}\" from ${grant.appId}`,\n });\n\n return getGrant(grantId, ctx);\n}\n\n// ─── Shared Credential Store Sync ─────────────────────────────────\n\ntype VaultSecretRow = typeof schema.vaultSecrets.$inferSelect;\n\nexport function credentialStoreScopeForVaultCtx(ctx: VaultCtx): {\n scope: Extract<SecretScope, \"org\" | \"workspace\">;\n scopeId: string;\n} {\n if (ctx.orgId) return { scope: \"org\", scopeId: ctx.orgId };\n return { scope: \"workspace\", scopeId: `solo:${ctx.ownerEmail}` };\n}\n\nexport async function syncSecretsToCredentialStore(\n secrets: VaultSecretRow[],\n ctx: VaultCtx,\n) {\n const target = credentialStoreScopeForVaultCtx(ctx);\n const syncedKeys: string[] = [];\n\n for (const secret of secrets) {\n if (!secret.credentialKey || !secret.value) continue;\n await writeAppSecret({\n key: secret.credentialKey,\n value: secret.value,\n scope: target.scope,\n scopeId: target.scopeId,\n description: `${VAULT_SYNC_DESCRIPTION_PREFIX} ${secret.name}`,\n });\n syncedKeys.push(secret.credentialKey);\n }\n\n return { ...target, keys: syncedKeys };\n}\n\nexport async function cleanupSyncedCredentialKeysIfUnused(\n ctx: VaultCtx,\n candidateKeys?: string[],\n) {\n const db = getDb();\n const target = credentialStoreScopeForVaultCtx(ctx);\n const keys = candidateKeys\n ? candidateKeys\n : (await listAppSecretsForScope(target.scope, target.scopeId))\n .filter((secret) =>\n secret.description?.startsWith(VAULT_SYNC_DESCRIPTION_PREFIX),\n )\n .map((secret) => secret.key);\n\n for (const key of new Set(keys.filter(Boolean))) {\n const stillUsesKey = await db\n .select({ id: schema.vaultSecrets.id })\n .from(schema.vaultSecrets)\n .where(\n and(\n eq(schema.vaultSecrets.credentialKey, key),\n ctxScope(schema.vaultSecrets, ctx),\n ),\n )\n .limit(1);\n if (!stillUsesKey[0]) {\n await deleteAppSecret({\n key,\n scope: target.scope,\n scopeId: target.scopeId,\n });\n }\n }\n}\n\n// ─── Sync ──────────────────────────────────────────────────────\n\nexport async function syncGrantsToApp(\n appId: string,\n ctx: VaultCtx = requireVaultCtx(),\n) {\n const db = getDb();\n const access = await getVaultAccessSettings();\n const agents = await discoverAgents(\"dispatch\");\n const agent = agents.find((a) => a.id === appId);\n if (!agent) throw new Error(`App \"${appId}\" not found in agent registry`);\n\n const secretsToSync: VaultSecretRow[] = [];\n const activeGrants =\n access.mode === \"manual\"\n ? (await listGrants({ appId })).filter((g) => g.status === \"active\")\n : [];\n\n if (access.mode === \"all-apps\") {\n const secrets = await listSecrets();\n for (const secret of secrets) {\n secretsToSync.push(secret);\n }\n } else {\n for (const grant of activeGrants) {\n const secret = await getSecret(grant.secretId, ctx);\n if (secret) {\n secretsToSync.push(secret);\n }\n }\n }\n\n if (secretsToSync.length === 0) {\n return { appId, accessMode: access.mode, synced: 0, keys: [] };\n }\n\n const credentialStoreSync = await syncSecretsToCredentialStore(\n secretsToSync,\n ctx,\n );\n const vars = secretsToSync.map((secret) => ({\n key: secret.credentialKey,\n value: secret.value,\n }));\n let envVarSync:\n | { status: \"synced\"; keys: string[] }\n | { status: \"skipped\"; reason: string }\n | { status: \"failed\"; reason: string };\n\n // Best-effort push to the app's env-vars endpoint for local/dev apps that\n // still read process.env directly. Production/shared-DB apps intentionally\n // reject env writes; the encrypted app_secrets sync above is the canonical\n // path for request-scoped credentials.\n try {\n const res = await fetch(`${agent.url}/_agent-native/env-vars`, {\n method: \"POST\",\n headers: { \"Content-Type\": \"application/json\" },\n body: JSON.stringify({ vars }),\n });\n\n if (res.ok) {\n const result = await res.json();\n envVarSync = { status: \"synced\", keys: result.saved || [] };\n } else {\n const err = await res.text().catch(() => \"Unknown error\");\n envVarSync = { status: \"skipped\", reason: err };\n }\n } catch (err) {\n envVarSync = {\n status: \"failed\",\n reason: err instanceof Error ? err.message : String(err),\n };\n }\n\n const syncedKeys = credentialStoreSync.keys;\n const timestamp = now();\n\n // Update syncedAt on grants that were successfully pushed to the shared\n // credential store. All-apps mode has no explicit grant rows to update.\n for (const grant of activeGrants) {\n const secret = await getSecret(grant.secretId, ctx);\n if (secret && syncedKeys.includes(secret.credentialKey)) {\n await db\n .update(schema.vaultGrants)\n .set({ syncedAt: timestamp, updatedAt: timestamp })\n .where(eq(schema.vaultGrants.id, grant.id));\n }\n }\n\n await recordVaultAudit({\n action: \"secret.synced\",\n appId,\n summary: `Synced ${syncedKeys.length} secret(s) to ${appId}: ${syncedKeys.join(\", \")}`,\n metadata: {\n syncedKeys,\n accessMode: access.mode,\n credentialStore: {\n scope: credentialStoreSync.scope,\n scopeId: credentialStoreSync.scopeId,\n },\n envVars: envVarSync,\n },\n });\n\n return {\n appId,\n accessMode: access.mode,\n synced: syncedKeys.length,\n keys: syncedKeys,\n credentialStore: {\n scope: credentialStoreSync.scope,\n scopeId: credentialStoreSync.scopeId,\n synced: credentialStoreSync.keys.length,\n },\n envVars: envVarSync,\n };\n}\n\n// ─── Requests ──────────────────────────────────────────────────────\n\nexport async function listRequests(filter?: { status?: string }) {\n const db = getDb();\n const conditions = [scopedFilter(schema.vaultRequests)];\n if (filter?.status) {\n conditions.push(eq(schema.vaultRequests.status, filter.status) as any);\n }\n return db\n .select()\n .from(schema.vaultRequests)\n .where(and(...conditions))\n .orderBy(desc(schema.vaultRequests.updatedAt));\n}\n\nexport async function getRequest(\n requestId: string,\n ctx: VaultCtx = requireVaultCtx(),\n) {\n const db = getDb();\n const [row] = await db\n .select()\n .from(schema.vaultRequests)\n .where(\n and(\n eq(schema.vaultRequests.id, requestId),\n ctxScope(schema.vaultRequests, ctx),\n ),\n )\n .limit(1);\n return row ?? null;\n}\n\nexport async function createRequest(input: {\n credentialKey: string;\n appId: string;\n reason?: string | null;\n}) {\n const db = getDb();\n const timestamp = now();\n const requestId = id();\n const actor = currentOwnerEmail();\n\n await db.insert(schema.vaultRequests).values({\n id: requestId,\n ownerEmail: actor,\n orgId: currentOrgId(),\n credentialKey: input.credentialKey,\n appId: input.appId,\n reason: input.reason || null,\n requestedBy: actor,\n status: \"pending\",\n reviewedBy: null,\n reviewedAt: null,\n createdAt: timestamp,\n updatedAt: timestamp,\n });\n\n await recordVaultAudit({\n action: \"request.created\",\n appId: input.appId,\n summary: `${actor} requested ${input.credentialKey} for ${input.appId}`,\n metadata: { requestId, reason: input.reason },\n });\n\n await notifyAdminsOfRequest(requestId, input);\n\n return getRequest(requestId);\n}\n\nexport async function approveRequest(\n requestId: string,\n secretValue: string,\n secretName?: string,\n ctx: VaultCtx = requireVaultCtx(),\n) {\n const db = getDb();\n const request = await getRequest(requestId, ctx);\n if (!request) throw new Error(\"Request not found\");\n if (request.status !== \"pending\") {\n throw new Error(\"Only pending requests can be approved\");\n }\n\n const timestamp = now();\n const reviewer = ctx.ownerEmail;\n\n // Update request status — scoped to caller's tenant.\n await db\n .update(schema.vaultRequests)\n .set({\n status: \"approved\",\n reviewedBy: reviewer,\n reviewedAt: timestamp,\n updatedAt: timestamp,\n })\n .where(\n and(\n eq(schema.vaultRequests.id, requestId),\n ctxScope(schema.vaultRequests, ctx),\n ),\n );\n\n // Secret + grant must land in the REQUEST's tenant, not the approver's\n // (the approver may be acting on behalf of another user in the same org).\n const requestCtx = ctxForRow(request);\n\n // Check if secret already exists in the request's tenant for this key.\n const existingSecrets = await db\n .select()\n .from(schema.vaultSecrets)\n .where(\n and(\n eq(schema.vaultSecrets.credentialKey, request.credentialKey),\n ctxScope(schema.vaultSecrets, requestCtx),\n ),\n );\n let secret = existingSecrets[0] ?? null;\n\n if (!secret) {\n secret = await createSecret(\n {\n credentialKey: request.credentialKey,\n value: secretValue,\n name: secretName || request.credentialKey,\n },\n requestCtx,\n );\n }\n\n if (secret) {\n // Create the grant in the request's tenant as well.\n await createGrant(secret.id, request.appId, requestCtx);\n }\n\n await recordVaultAudit({\n action: \"request.approved\",\n appId: request.appId,\n summary: `Approved ${request.credentialKey} for ${request.appId} (requested by ${request.requestedBy})`,\n metadata: { requestId, reviewer },\n });\n\n return getRequest(requestId, ctx);\n}\n\nexport async function denyRequest(\n requestId: string,\n reason?: string | null,\n ctx: VaultCtx = requireVaultCtx(),\n) {\n const db = getDb();\n const request = await getRequest(requestId, ctx);\n if (!request) throw new Error(\"Request not found\");\n if (request.status !== \"pending\") {\n throw new Error(\"Only pending requests can be denied\");\n }\n\n const timestamp = now();\n const reviewer = ctx.ownerEmail;\n\n await db\n .update(schema.vaultRequests)\n .set({\n status: \"denied\",\n reviewedBy: reviewer,\n reviewedAt: timestamp,\n updatedAt: timestamp,\n })\n .where(\n and(\n eq(schema.vaultRequests.id, requestId),\n ctxScope(schema.vaultRequests, ctx),\n ),\n );\n\n await recordVaultAudit({\n action: \"request.denied\",\n appId: request.appId,\n summary: `Denied ${request.credentialKey} for ${request.appId} (requested by ${request.requestedBy})`,\n metadata: { requestId, reviewer, reason },\n });\n\n return getRequest(requestId, ctx);\n}\n\n// ─── Integrations Catalog ────────────────────────────────────────\n\nexport interface IntegrationEntry {\n key: string;\n label: string;\n required: boolean;\n configured: boolean;\n vaultGranted: boolean;\n vaultSecretId?: string;\n}\n\nexport interface AppIntegrations {\n appId: string;\n appName: string;\n url: string;\n color: string;\n integrations: IntegrationEntry[];\n vaultAccessMode: VaultAccessMode;\n reachable: boolean;\n}\n\nexport async function listIntegrationsCatalog(): Promise<AppIntegrations[]> {\n const access = await getVaultAccessSettings();\n const agents = await discoverAgents(\"dispatch\");\n const grants = await listGrants();\n const secrets = await listSecrets();\n\n const secretByKey = new Map(secrets.map((s) => [s.credentialKey, s]));\n\n const results: AppIntegrations[] = [];\n\n for (const agent of agents) {\n try {\n const res = await fetch(`${agent.url}/_agent-native/env-status`, {\n signal: AbortSignal.timeout(3000),\n });\n if (!res.ok) {\n results.push({\n appId: agent.id,\n appName: agent.name,\n url: agent.url,\n color: agent.color,\n integrations: [],\n vaultAccessMode: access.mode,\n reachable: false,\n });\n continue;\n }\n\n const envStatus: Array<{\n key: string;\n label: string;\n required: boolean;\n configured: boolean;\n }> = await res.json();\n\n const appGrants = grants.filter(\n (g) => g.appId === agent.id && g.status === \"active\",\n );\n const grantedSecretIds = new Set(appGrants.map((g) => g.secretId));\n\n const integrations: IntegrationEntry[] = envStatus.map((env) => {\n const matchingSecret = secretByKey.get(env.key);\n return {\n key: env.key,\n label: env.label,\n required: env.required,\n configured: env.configured,\n vaultGranted:\n !!matchingSecret &&\n (access.mode === \"all-apps\" ||\n grantedSecretIds.has(matchingSecret.id)),\n vaultSecretId: matchingSecret?.id,\n };\n });\n\n results.push({\n appId: agent.id,\n appName: agent.name,\n url: agent.url,\n color: agent.color,\n integrations,\n vaultAccessMode: access.mode,\n reachable: true,\n });\n } catch {\n results.push({\n appId: agent.id,\n appName: agent.name,\n url: agent.url,\n color: agent.color,\n integrations: [],\n vaultAccessMode: access.mode,\n reachable: false,\n });\n }\n }\n\n return results;\n}\n\n// ─── Vault Overview (for dashboard) ──────────────────────────────\n\nexport async function listVaultOverview() {\n const [secrets, grants, requests, access] = await Promise.all([\n listSecrets(),\n listGrants(),\n listRequests(),\n getVaultAccessSettings(),\n ]);\n const manualGrantCount = grants.filter((g) => g.status === \"active\").length;\n\n return {\n accessMode: access.mode,\n secretCount: secrets.length,\n activeGrantCount:\n access.mode === \"all-apps\" ? secrets.length : manualGrantCount,\n manualGrantCount,\n pendingRequestCount: requests.filter((r) => r.status === \"pending\").length,\n };\n}\n\n// ─── SendGrid Notifications ──────────────────────────────────────\n\nasync function notifyAdminsOfRequest(\n requestId: string,\n input: { credentialKey: string; appId: string; reason?: string | null },\n) {\n const apiKey = process.env.SENDGRID_API_KEY;\n const from = process.env.SENDGRID_FROM_EMAIL;\n const appUrl = process.env.APP_URL;\n if (!apiKey || !from || !appUrl) return;\n\n // Use approval policy approver emails as admin notification targets\n const { getApprovalPolicy } = await import(\"./dispatch-store.js\");\n const policy = await getApprovalPolicy();\n if (policy.approverEmails.length === 0) return;\n\n const body = [\n `Secret request: ${input.credentialKey} for ${input.appId}`,\n input.reason ? `Reason: ${input.reason}` : \"\",\n `Requested by: ${currentOwnerEmail()}`,\n \"\",\n `Review it here: ${appUrl}/vault`,\n ]\n .filter(Boolean)\n .join(\"\\n\");\n\n await fetch(\"https://api.sendgrid.com/v3/mail/send\", {\n method: \"POST\",\n headers: {\n Authorization: `Bearer ${apiKey}`,\n \"Content-Type\": \"application/json\",\n },\n body: JSON.stringify({\n personalizations: [\n {\n to: policy.approverEmails.map((email) => ({ email })),\n subject: `Vault request: ${input.credentialKey} for ${input.appId}`,\n },\n ],\n from: { email: from },\n content: [{ type: \"text/plain\", value: body }],\n custom_args: { requestId },\n }),\n }).catch(() => {});\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agent-native/dispatch",
|
|
3
|
-
"version": "0.8.
|
|
3
|
+
"version": "0.8.4",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Dispatch — workspace control plane for agent-native apps. Vault, integrations, destinations, scheduled jobs, and cross-app delegation, shipped as a single drop-in package.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -3,10 +3,43 @@ import { z } from "zod";
|
|
|
3
3
|
import { updateSecret } from "../server/lib/vault-store.js";
|
|
4
4
|
|
|
5
5
|
export default defineAction({
|
|
6
|
-
description:
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
6
|
+
description:
|
|
7
|
+
"Update an existing vault secret's label, credential key, value, provider, or description. Admin only.",
|
|
8
|
+
schema: z
|
|
9
|
+
.object({
|
|
10
|
+
id: z.string().min(1).describe("Secret ID"),
|
|
11
|
+
credentialKey: z
|
|
12
|
+
.string()
|
|
13
|
+
.trim()
|
|
14
|
+
.min(1)
|
|
15
|
+
.optional()
|
|
16
|
+
.describe("Environment variable name, e.g. GOOGLE_CLIENT_ID"),
|
|
17
|
+
value: z.string().min(1).optional().describe("New secret value"),
|
|
18
|
+
name: z
|
|
19
|
+
.string()
|
|
20
|
+
.trim()
|
|
21
|
+
.min(1)
|
|
22
|
+
.optional()
|
|
23
|
+
.describe("Human-readable label for this secret"),
|
|
24
|
+
provider: z
|
|
25
|
+
.string()
|
|
26
|
+
.nullable()
|
|
27
|
+
.optional()
|
|
28
|
+
.describe("Provider grouping tag, e.g. google, sendgrid, slack"),
|
|
29
|
+
description: z
|
|
30
|
+
.string()
|
|
31
|
+
.nullable()
|
|
32
|
+
.optional()
|
|
33
|
+
.describe("Optional description"),
|
|
34
|
+
})
|
|
35
|
+
.refine(
|
|
36
|
+
({ credentialKey, value, name, provider, description }) =>
|
|
37
|
+
credentialKey !== undefined ||
|
|
38
|
+
value !== undefined ||
|
|
39
|
+
name !== undefined ||
|
|
40
|
+
provider !== undefined ||
|
|
41
|
+
description !== undefined,
|
|
42
|
+
"At least one secret field must be updated",
|
|
43
|
+
),
|
|
44
|
+
run: async (args) => updateSecret(args.id, args),
|
|
12
45
|
});
|
package/src/routes/index.ts
CHANGED
|
@@ -51,6 +51,7 @@ export const dispatchRoutes: RouteConfig = [
|
|
|
51
51
|
route("team", "./pages/team.js"),
|
|
52
52
|
route("extensions", "./pages/extensions._index.js"),
|
|
53
53
|
route("extensions/:id", "./pages/extensions.$id.js"),
|
|
54
|
+
route("extensions/:id/:slug", "./pages/extensions.$id.js"),
|
|
54
55
|
// Catch-all for /:appId — bounces /dispatch/<appId> to /<appId> when the
|
|
55
56
|
// segment names a workspace app sibling (e.g. Builder.io routing a "go to
|
|
56
57
|
// /todo" call through Dispatch's mount). Declared last so React Router 7's
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ExtensionViewerPage } from "@agent-native/core/client/extensions";
|
|
2
|
+
|
|
3
|
+
export function meta() {
|
|
4
|
+
return [{ title: "Extension \u2014 Dispatch" }];
|
|
5
|
+
}
|
|
2
6
|
|
|
3
7
|
export default function ExtensionViewerRoute() {
|
|
4
|
-
return <
|
|
8
|
+
return <ExtensionViewerPage />;
|
|
5
9
|
}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ExtensionsListPage } from "@agent-native/core/client/extensions";
|
|
2
|
+
|
|
3
|
+
export function meta() {
|
|
4
|
+
return [{ title: "Extensions \u2014 Dispatch" }];
|
|
5
|
+
}
|
|
2
6
|
|
|
3
7
|
export default function ExtensionsRoute() {
|
|
4
|
-
return <
|
|
8
|
+
return <ExtensionsListPage />;
|
|
5
9
|
}
|