kavachos 0.0.1

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 KavachOS
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,32 @@
1
+ import { D as Database, C as CreateAgentInput, A as AgentIdentity, d as AgentFilter, U as UpdateAgentInput } from '../types-fHHAt3tt.js';
2
+ export { j as AgentConfig } from '../types-fHHAt3tt.js';
3
+ import 'drizzle-orm/better-sqlite3';
4
+ import 'drizzle-orm/sqlite-core';
5
+ import '../types-C5htunW6.js';
6
+ import 'zod';
7
+
8
+ interface AgentModuleConfig {
9
+ db: Database;
10
+ maxPerUser: number;
11
+ defaultPermissions: string[];
12
+ tokenExpiry: string;
13
+ }
14
+ /**
15
+ * Create the agent identity module.
16
+ * Handles CRUD operations for AI agent identities.
17
+ */
18
+ declare function createAgentModule(config: AgentModuleConfig): {
19
+ create: (input: CreateAgentInput) => Promise<AgentIdentity & {
20
+ token: string;
21
+ }>;
22
+ get: (agentId: string) => Promise<AgentIdentity | null>;
23
+ list: (filter?: AgentFilter) => Promise<AgentIdentity[]>;
24
+ update: (agentId: string, input: UpdateAgentInput) => Promise<AgentIdentity>;
25
+ revoke: (agentId: string) => Promise<void>;
26
+ rotate: (agentId: string) => Promise<AgentIdentity & {
27
+ token: string;
28
+ }>;
29
+ validateToken: (token: string) => Promise<AgentIdentity | null>;
30
+ };
31
+
32
+ export { createAgentModule };
@@ -0,0 +1,5 @@
1
+ export { createAgentModule } from '../chunk-DTCKF26N.js';
2
+ import '../chunk-XSYYQH75.js';
3
+ import '../chunk-PZ5AY32C.js';
4
+ //# sourceMappingURL=index.js.map
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
@@ -0,0 +1,19 @@
1
+ import { D as Database, g as AuditFilter, h as AuditEntry, i as AuditExportOptions } from '../types-fHHAt3tt.js';
2
+ import 'drizzle-orm/better-sqlite3';
3
+ import 'drizzle-orm/sqlite-core';
4
+ import '../types-C5htunW6.js';
5
+ import 'zod';
6
+
7
+ interface AuditModuleConfig {
8
+ db: Database;
9
+ }
10
+ /**
11
+ * Create the audit log module.
12
+ * Provides query and export capabilities for the immutable audit trail.
13
+ */
14
+ declare function createAuditModule(config: AuditModuleConfig): {
15
+ query: (filter: AuditFilter) => Promise<AuditEntry[]>;
16
+ export: (options: AuditExportOptions) => Promise<string>;
17
+ };
18
+
19
+ export { AuditEntry, AuditExportOptions, AuditFilter, createAuditModule };
@@ -0,0 +1,5 @@
1
+ export { createAuditModule } from '../chunk-XW2X3O53.js';
2
+ import '../chunk-XSYYQH75.js';
3
+ import '../chunk-PZ5AY32C.js';
4
+ //# sourceMappingURL=index.js.map
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
@@ -0,0 +1,2 @@
1
+
2
+ export { }
@@ -0,0 +1,3 @@
1
+
2
+ //# sourceMappingURL=index.js.map
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
@@ -0,0 +1,207 @@
1
+ import { auditLogs, rateLimits } from './chunk-XSYYQH75.js';
2
+ import { randomUUID } from 'crypto';
3
+ import { and, eq, gte } from 'drizzle-orm';
4
+
5
+ function matchResource(pattern, resource) {
6
+ if (pattern === "*") return true;
7
+ const patternParts = pattern.split(":");
8
+ const resourceParts = resource.split(":");
9
+ for (let i = 0; i < patternParts.length; i++) {
10
+ const part = patternParts[i];
11
+ if (part === "*") return true;
12
+ if (part !== resourceParts[i]) return false;
13
+ }
14
+ return patternParts.length === resourceParts.length;
15
+ }
16
+ function matchAction(allowedActions, requestedAction) {
17
+ return allowedActions.includes(requestedAction) || allowedActions.includes("*");
18
+ }
19
+ function validateArgPatterns(patterns, args) {
20
+ for (const pattern of patterns) {
21
+ const regex = new RegExp(pattern);
22
+ for (const [key, value] of Object.entries(args)) {
23
+ if (typeof value === "string" && !regex.test(value)) {
24
+ return {
25
+ valid: false,
26
+ reason: `Argument "${key}" value "${value}" does not match pattern "${pattern}"`
27
+ };
28
+ }
29
+ }
30
+ }
31
+ return { valid: true };
32
+ }
33
+ async function checkRateLimit(db, agentId, resource, maxCallsPerHour) {
34
+ const oneHourAgo = new Date(Date.now() - 60 * 60 * 1e3);
35
+ const rows = await db.select().from(rateLimits).where(
36
+ and(
37
+ eq(rateLimits.agentId, agentId),
38
+ eq(rateLimits.resource, resource),
39
+ gte(rateLimits.windowStart, oneHourAgo)
40
+ )
41
+ );
42
+ const totalCalls = rows.reduce((sum, r) => sum + r.count, 0);
43
+ if (totalCalls >= maxCallsPerHour) {
44
+ return {
45
+ allowed: false,
46
+ reason: `Rate limit exceeded: ${totalCalls}/${maxCallsPerHour} calls per hour for resource "${resource}"`
47
+ };
48
+ }
49
+ const currentWindow = new Date(Math.floor(Date.now() / (5 * 60 * 1e3)) * (5 * 60 * 1e3));
50
+ const existing = rows.find((r) => r.windowStart.getTime() === currentWindow.getTime());
51
+ if (existing) {
52
+ await db.update(rateLimits).set({ count: existing.count + 1 }).where(eq(rateLimits.id, existing.id));
53
+ } else {
54
+ await db.insert(rateLimits).values({
55
+ id: randomUUID(),
56
+ agentId,
57
+ resource,
58
+ windowStart: currentWindow,
59
+ count: 1
60
+ });
61
+ }
62
+ return { allowed: true };
63
+ }
64
+ function createPermissionEngine(config) {
65
+ const { db, auditAll } = config;
66
+ async function authorize(agent, request) {
67
+ const startTime = performance.now();
68
+ const auditId = randomUUID();
69
+ const matchingPermission = agent.permissions.find(
70
+ (p) => matchResource(p.resource, request.resource) && matchAction(p.actions, request.action)
71
+ );
72
+ if (!matchingPermission) {
73
+ const result2 = {
74
+ allowed: false,
75
+ reason: `No permission grants agent "${agent.name}" access to "${request.action}" on "${request.resource}"`,
76
+ auditId
77
+ };
78
+ if (auditAll) {
79
+ await writeAuditLog(db, agent, request, result2, startTime, auditId);
80
+ }
81
+ return result2;
82
+ }
83
+ if (matchingPermission.constraints) {
84
+ const constraintResult = await evaluateConstraints(
85
+ db,
86
+ agent,
87
+ request,
88
+ matchingPermission.constraints
89
+ );
90
+ if (!constraintResult.allowed) {
91
+ const result2 = {
92
+ allowed: false,
93
+ reason: constraintResult.reason,
94
+ auditId
95
+ };
96
+ if (auditAll) {
97
+ await writeAuditLog(db, agent, request, result2, startTime, auditId);
98
+ }
99
+ return result2;
100
+ }
101
+ }
102
+ const result = { allowed: true, auditId };
103
+ if (auditAll) {
104
+ await writeAuditLog(db, agent, request, result, startTime, auditId);
105
+ }
106
+ return result;
107
+ }
108
+ return { authorize };
109
+ }
110
+ async function evaluateConstraints(db, agent, request, constraints) {
111
+ if (constraints.maxCallsPerHour) {
112
+ const rateResult = await checkRateLimit(
113
+ db,
114
+ agent.id,
115
+ request.resource,
116
+ constraints.maxCallsPerHour
117
+ );
118
+ if (!rateResult.allowed) {
119
+ return rateResult;
120
+ }
121
+ }
122
+ if (constraints.allowedArgPatterns && request.arguments) {
123
+ const patternResult = validateArgPatterns(constraints.allowedArgPatterns, request.arguments);
124
+ if (!patternResult.valid) {
125
+ return { allowed: false, reason: patternResult.reason };
126
+ }
127
+ }
128
+ if (constraints.requireApproval) {
129
+ return {
130
+ allowed: false,
131
+ reason: "This action requires human approval before execution"
132
+ };
133
+ }
134
+ if (constraints.timeWindow) {
135
+ const now = /* @__PURE__ */ new Date();
136
+ const hours = now.getHours();
137
+ const minutes = now.getMinutes();
138
+ const currentTime = `${String(hours).padStart(2, "0")}:${String(minutes).padStart(2, "0")}`;
139
+ if (currentTime < constraints.timeWindow.start || currentTime > constraints.timeWindow.end) {
140
+ return {
141
+ allowed: false,
142
+ reason: `Action is only allowed between ${constraints.timeWindow.start} and ${constraints.timeWindow.end}`
143
+ };
144
+ }
145
+ }
146
+ return { allowed: true };
147
+ }
148
+ async function writeAuditLog(db, agent, request, result, startTime, auditId) {
149
+ const durationMs = Math.round(performance.now() - startTime);
150
+ await db.insert(auditLogs).values({
151
+ id: auditId,
152
+ agentId: agent.id,
153
+ userId: agent.ownerId,
154
+ action: request.action,
155
+ resource: request.resource,
156
+ parameters: request.arguments ?? {},
157
+ result: result.allowed ? "allowed" : "denied",
158
+ reason: result.reason ?? null,
159
+ durationMs,
160
+ timestamp: /* @__PURE__ */ new Date()
161
+ });
162
+ }
163
+
164
+ // src/permission/templates.ts
165
+ var permissionTemplates = {
166
+ /** Read-only access to all resources */
167
+ readonly: [{ resource: "*", actions: ["read"] }],
168
+ /** Read and write access to all resources */
169
+ readwrite: [{ resource: "*", actions: ["read", "write"] }],
170
+ /** Full access to all resources and actions */
171
+ admin: [{ resource: "*", actions: ["*"] }],
172
+ /** Standard MCP tool access - read + execute */
173
+ mcpBasic: [{ resource: "mcp:*", actions: ["read", "execute"] }],
174
+ /** MCP tool access with write - read + write + execute */
175
+ mcpFull: [{ resource: "mcp:*", actions: ["read", "write", "execute"] }],
176
+ /** Rate-limited read access (100 calls/hour) */
177
+ rateLimitedRead: [
178
+ {
179
+ resource: "*",
180
+ actions: ["read"],
181
+ constraints: { maxCallsPerHour: 100 }
182
+ }
183
+ ],
184
+ /** Approval-required access (human-in-the-loop for everything) */
185
+ approvalRequired: [
186
+ {
187
+ resource: "*",
188
+ actions: ["*"],
189
+ constraints: { requireApproval: true }
190
+ }
191
+ ],
192
+ /** Business hours only access (9am-5pm) */
193
+ businessHours: [
194
+ {
195
+ resource: "*",
196
+ actions: ["read", "write", "execute"],
197
+ constraints: { timeWindow: { start: "09:00", end: "17:00" } }
198
+ }
199
+ ]
200
+ };
201
+ function getPermissionTemplate(name) {
202
+ return JSON.parse(JSON.stringify(permissionTemplates[name]));
203
+ }
204
+
205
+ export { createPermissionEngine, getPermissionTemplate, permissionTemplates };
206
+ //# sourceMappingURL=chunk-D2LJLY7F.js.map
207
+ //# sourceMappingURL=chunk-D2LJLY7F.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/permission/engine.ts","../src/permission/templates.ts"],"names":["result"],"mappings":"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","file":"chunk-D2LJLY7F.js","sourcesContent":["import { randomUUID } from \"node:crypto\";\nimport { and, eq, gte } from \"drizzle-orm\";\nimport type { Database } from \"../db/database.js\";\nimport { auditLogs, rateLimits } from \"../db/schema.js\";\nimport type {\n\tAgentIdentity,\n\tAuthorizeRequest,\n\tAuthorizeResult,\n\tPermissionConstraints,\n} from \"../types.js\";\n\ninterface PermissionEngineConfig {\n\tdb: Database;\n\tauditAll: boolean;\n}\n\n/**\n * Match a resource pattern against a requested resource.\n *\n * Supports wildcards:\n * - \"mcp:github:*\" matches \"mcp:github:create_issue\"\n * - \"tool:*\" matches \"tool:file_read\"\n * - \"*\" matches everything\n */\nfunction matchResource(pattern: string, resource: string): boolean {\n\tif (pattern === \"*\") return true;\n\n\tconst patternParts = pattern.split(\":\");\n\tconst resourceParts = resource.split(\":\");\n\n\tfor (let i = 0; i < patternParts.length; i++) {\n\t\tconst part = patternParts[i];\n\t\tif (part === \"*\") return true;\n\t\tif (part !== resourceParts[i]) return false;\n\t}\n\n\treturn patternParts.length === resourceParts.length;\n}\n\n/**\n * Check if an action is allowed by a permission's actions list.\n */\nfunction matchAction(allowedActions: string[], requestedAction: string): boolean {\n\treturn allowedActions.includes(requestedAction) || allowedActions.includes(\"*\");\n}\n\n/**\n * Validate argument patterns against the request arguments.\n */\nfunction validateArgPatterns(\n\tpatterns: string[],\n\targs: Record<string, unknown>,\n): { valid: boolean; reason?: string } {\n\tfor (const pattern of patterns) {\n\t\tconst regex = new RegExp(pattern);\n\t\t// Check all string arguments against the pattern\n\t\tfor (const [key, value] of Object.entries(args)) {\n\t\t\tif (typeof value === \"string\" && !regex.test(value)) {\n\t\t\t\treturn {\n\t\t\t\t\tvalid: false,\n\t\t\t\t\treason: `Argument \"${key}\" value \"${value}\" does not match pattern \"${pattern}\"`,\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\t}\n\treturn { valid: true };\n}\n\n/**\n * Check rate limits for an agent on a specific resource.\n */\nasync function checkRateLimit(\n\tdb: Database,\n\tagentId: string,\n\tresource: string,\n\tmaxCallsPerHour: number,\n): Promise<{ allowed: boolean; reason?: string }> {\n\tconst oneHourAgo = new Date(Date.now() - 60 * 60 * 1000);\n\n\tconst rows = await db\n\t\t.select()\n\t\t.from(rateLimits)\n\t\t.where(\n\t\t\tand(\n\t\t\t\teq(rateLimits.agentId, agentId),\n\t\t\t\teq(rateLimits.resource, resource),\n\t\t\t\tgte(rateLimits.windowStart, oneHourAgo),\n\t\t\t),\n\t\t);\n\n\tconst totalCalls = rows.reduce((sum, r) => sum + r.count, 0);\n\n\tif (totalCalls >= maxCallsPerHour) {\n\t\treturn {\n\t\t\tallowed: false,\n\t\t\treason: `Rate limit exceeded: ${totalCalls}/${maxCallsPerHour} calls per hour for resource \"${resource}\"`,\n\t\t};\n\t}\n\n\t// Increment counter\n\tconst currentWindow = new Date(Math.floor(Date.now() / (5 * 60 * 1000)) * (5 * 60 * 1000)); // 5-min windows\n\tconst existing = rows.find((r) => r.windowStart.getTime() === currentWindow.getTime());\n\n\tif (existing) {\n\t\tawait db\n\t\t\t.update(rateLimits)\n\t\t\t.set({ count: existing.count + 1 })\n\t\t\t.where(eq(rateLimits.id, existing.id));\n\t} else {\n\t\tawait db.insert(rateLimits).values({\n\t\t\tid: randomUUID(),\n\t\t\tagentId,\n\t\t\tresource,\n\t\t\twindowStart: currentWindow,\n\t\t\tcount: 1,\n\t\t});\n\t}\n\n\treturn { allowed: true };\n}\n\n/**\n * Create the permission/authorization engine.\n */\nexport function createPermissionEngine(config: PermissionEngineConfig) {\n\tconst { db, auditAll } = config;\n\n\t/**\n\t * Check if an agent is authorized to perform an action.\n\t * This is the core authorization function.\n\t */\n\tasync function authorize(\n\t\tagent: AgentIdentity,\n\t\trequest: AuthorizeRequest,\n\t): Promise<AuthorizeResult> {\n\t\tconst startTime = performance.now();\n\t\tconst auditId = randomUUID();\n\n\t\t// Find matching permission\n\t\tconst matchingPermission = agent.permissions.find(\n\t\t\t(p) => matchResource(p.resource, request.resource) && matchAction(p.actions, request.action),\n\t\t);\n\n\t\tif (!matchingPermission) {\n\t\t\tconst result: AuthorizeResult = {\n\t\t\t\tallowed: false,\n\t\t\t\treason: `No permission grants agent \"${agent.name}\" access to \"${request.action}\" on \"${request.resource}\"`,\n\t\t\t\tauditId,\n\t\t\t};\n\t\t\tif (auditAll) {\n\t\t\t\tawait writeAuditLog(db, agent, request, result, startTime, auditId);\n\t\t\t}\n\t\t\treturn result;\n\t\t}\n\n\t\t// Check constraints\n\t\tif (matchingPermission.constraints) {\n\t\t\tconst constraintResult = await evaluateConstraints(\n\t\t\t\tdb,\n\t\t\t\tagent,\n\t\t\t\trequest,\n\t\t\t\tmatchingPermission.constraints,\n\t\t\t);\n\t\t\tif (!constraintResult.allowed) {\n\t\t\t\tconst result: AuthorizeResult = {\n\t\t\t\t\tallowed: false,\n\t\t\t\t\treason: constraintResult.reason,\n\t\t\t\t\tauditId,\n\t\t\t\t};\n\t\t\t\tif (auditAll) {\n\t\t\t\t\tawait writeAuditLog(db, agent, request, result, startTime, auditId);\n\t\t\t\t}\n\t\t\t\treturn result;\n\t\t\t}\n\t\t}\n\n\t\tconst result: AuthorizeResult = { allowed: true, auditId };\n\t\tif (auditAll) {\n\t\t\tawait writeAuditLog(db, agent, request, result, startTime, auditId);\n\t\t}\n\t\treturn result;\n\t}\n\n\treturn { authorize };\n}\n\nasync function evaluateConstraints(\n\tdb: Database,\n\tagent: AgentIdentity,\n\trequest: AuthorizeRequest,\n\tconstraints: PermissionConstraints,\n): Promise<{ allowed: boolean; reason?: string }> {\n\t// Rate limit check\n\tif (constraints.maxCallsPerHour) {\n\t\tconst rateResult = await checkRateLimit(\n\t\t\tdb,\n\t\t\tagent.id,\n\t\t\trequest.resource,\n\t\t\tconstraints.maxCallsPerHour,\n\t\t);\n\t\tif (!rateResult.allowed) {\n\t\t\treturn rateResult;\n\t\t}\n\t}\n\n\t// Argument pattern check\n\tif (constraints.allowedArgPatterns && request.arguments) {\n\t\tconst patternResult = validateArgPatterns(constraints.allowedArgPatterns, request.arguments);\n\t\tif (!patternResult.valid) {\n\t\t\treturn { allowed: false, reason: patternResult.reason };\n\t\t}\n\t}\n\n\t// Human-in-the-loop check\n\tif (constraints.requireApproval) {\n\t\treturn {\n\t\t\tallowed: false,\n\t\t\treason: \"This action requires human approval before execution\",\n\t\t};\n\t}\n\n\t// Time window check\n\tif (constraints.timeWindow) {\n\t\tconst now = new Date();\n\t\tconst hours = now.getHours();\n\t\tconst minutes = now.getMinutes();\n\t\tconst currentTime = `${String(hours).padStart(2, \"0\")}:${String(minutes).padStart(2, \"0\")}`;\n\n\t\tif (currentTime < constraints.timeWindow.start || currentTime > constraints.timeWindow.end) {\n\t\t\treturn {\n\t\t\t\tallowed: false,\n\t\t\t\treason: `Action is only allowed between ${constraints.timeWindow.start} and ${constraints.timeWindow.end}`,\n\t\t\t};\n\t\t}\n\t}\n\n\treturn { allowed: true };\n}\n\nasync function writeAuditLog(\n\tdb: Database,\n\tagent: AgentIdentity,\n\trequest: AuthorizeRequest,\n\tresult: AuthorizeResult,\n\tstartTime: number,\n\tauditId: string,\n): Promise<void> {\n\tconst durationMs = Math.round(performance.now() - startTime);\n\n\tawait db.insert(auditLogs).values({\n\t\tid: auditId,\n\t\tagentId: agent.id,\n\t\tuserId: agent.ownerId,\n\t\taction: request.action,\n\t\tresource: request.resource,\n\t\tparameters: request.arguments ?? {},\n\t\tresult: result.allowed ? \"allowed\" : \"denied\",\n\t\treason: result.reason ?? null,\n\t\tdurationMs,\n\t\ttimestamp: new Date(),\n\t});\n}\n","import type { Permission } from \"../types.js\";\n\n/**\n * Pre-built permission templates for common access patterns.\n * Use these as starting points when creating agents.\n */\nexport const permissionTemplates = {\n\t/** Read-only access to all resources */\n\treadonly: [{ resource: \"*\", actions: [\"read\"] }] satisfies Permission[],\n\n\t/** Read and write access to all resources */\n\treadwrite: [{ resource: \"*\", actions: [\"read\", \"write\"] }] satisfies Permission[],\n\n\t/** Full access to all resources and actions */\n\tadmin: [{ resource: \"*\", actions: [\"*\"] }] satisfies Permission[],\n\n\t/** Standard MCP tool access - read + execute */\n\tmcpBasic: [{ resource: \"mcp:*\", actions: [\"read\", \"execute\"] }] satisfies Permission[],\n\n\t/** MCP tool access with write - read + write + execute */\n\tmcpFull: [{ resource: \"mcp:*\", actions: [\"read\", \"write\", \"execute\"] }] satisfies Permission[],\n\n\t/** Rate-limited read access (100 calls/hour) */\n\trateLimitedRead: [\n\t\t{\n\t\t\tresource: \"*\",\n\t\t\tactions: [\"read\"],\n\t\t\tconstraints: { maxCallsPerHour: 100 },\n\t\t},\n\t] satisfies Permission[],\n\n\t/** Approval-required access (human-in-the-loop for everything) */\n\tapprovalRequired: [\n\t\t{\n\t\t\tresource: \"*\",\n\t\t\tactions: [\"*\"],\n\t\t\tconstraints: { requireApproval: true },\n\t\t},\n\t] satisfies Permission[],\n\n\t/** Business hours only access (9am-5pm) */\n\tbusinessHours: [\n\t\t{\n\t\t\tresource: \"*\",\n\t\t\tactions: [\"read\", \"write\", \"execute\"],\n\t\t\tconstraints: { timeWindow: { start: \"09:00\", end: \"17:00\" } },\n\t\t},\n\t] satisfies Permission[],\n} as const;\n\nexport type PermissionTemplateName = keyof typeof permissionTemplates;\n\n/**\n * Get a permission template by name.\n * Returns a fresh copy of the permissions array.\n */\nexport function getPermissionTemplate(name: PermissionTemplateName): Permission[] {\n\treturn JSON.parse(JSON.stringify(permissionTemplates[name])) as Permission[];\n}\n"]}
@@ -0,0 +1,208 @@
1
+ import { agents, permissions } from './chunk-XSYYQH75.js';
2
+ import { randomUUID, createHash, randomBytes } from 'crypto';
3
+ import { and, eq } from 'drizzle-orm';
4
+
5
+ function generateAgentToken() {
6
+ const tokenBytes = randomBytes(32);
7
+ const token = `kv_${tokenBytes.toString("base64url")}`;
8
+ const hash = createHash("sha256").update(token).digest("hex");
9
+ const prefix = token.slice(0, 11);
10
+ return { token, hash, prefix };
11
+ }
12
+ function parseTokenExpiry(expiry) {
13
+ const now = Date.now();
14
+ const match = expiry.match(/^(\d+)([smhd])$/);
15
+ if (!match) {
16
+ throw new Error(`Invalid token expiry format: ${expiry}. Use format like "24h", "7d", "30m".`);
17
+ }
18
+ const value = Number.parseInt(match[1], 10);
19
+ const unit = match[2];
20
+ const multipliers = {
21
+ s: 1e3,
22
+ m: 60 * 1e3,
23
+ h: 60 * 60 * 1e3,
24
+ d: 24 * 60 * 60 * 1e3
25
+ };
26
+ return new Date(now + value * (multipliers[unit] ?? 0));
27
+ }
28
+ function createAgentModule(config) {
29
+ const { db, maxPerUser, tokenExpiry } = config;
30
+ async function create(input) {
31
+ const existing = await db.select().from(agents).where(and(eq(agents.ownerId, input.ownerId), eq(agents.status, "active")));
32
+ if (existing.length >= maxPerUser) {
33
+ throw new Error(
34
+ `User ${input.ownerId} has reached the maximum of ${maxPerUser} active agents.`
35
+ );
36
+ }
37
+ const id = randomUUID();
38
+ const { token, hash, prefix } = generateAgentToken();
39
+ const now = /* @__PURE__ */ new Date();
40
+ const expires = input.expiresAt ?? parseTokenExpiry(tokenExpiry);
41
+ await db.insert(agents).values({
42
+ id,
43
+ ownerId: input.ownerId,
44
+ name: input.name,
45
+ type: input.type,
46
+ status: "active",
47
+ tokenHash: hash,
48
+ tokenPrefix: prefix,
49
+ expiresAt: expires,
50
+ metadata: input.metadata ?? {},
51
+ createdAt: now,
52
+ updatedAt: now
53
+ });
54
+ if (input.permissions.length > 0) {
55
+ await db.insert(permissions).values(
56
+ input.permissions.map((p) => ({
57
+ id: randomUUID(),
58
+ agentId: id,
59
+ resource: p.resource,
60
+ actions: p.actions,
61
+ constraints: p.constraints ?? null,
62
+ createdAt: now
63
+ }))
64
+ );
65
+ }
66
+ return {
67
+ id,
68
+ ownerId: input.ownerId,
69
+ name: input.name,
70
+ type: input.type,
71
+ token,
72
+ permissions: input.permissions,
73
+ status: "active",
74
+ expiresAt: expires,
75
+ createdAt: now,
76
+ updatedAt: now
77
+ };
78
+ }
79
+ async function get(agentId) {
80
+ const rows = await db.select().from(agents).where(eq(agents.id, agentId)).limit(1);
81
+ const agent = rows[0];
82
+ if (!agent) return null;
83
+ const perms = await db.select().from(permissions).where(eq(permissions.agentId, agentId));
84
+ return {
85
+ id: agent.id,
86
+ ownerId: agent.ownerId,
87
+ name: agent.name,
88
+ type: agent.type,
89
+ token: "",
90
+ // never return token after creation
91
+ permissions: perms.map(toPermission),
92
+ status: agent.status,
93
+ expiresAt: agent.expiresAt,
94
+ createdAt: agent.createdAt,
95
+ updatedAt: agent.updatedAt
96
+ };
97
+ }
98
+ async function list(filter) {
99
+ let query = db.select().from(agents).$dynamic();
100
+ const conditions = [];
101
+ if (filter?.userId) conditions.push(eq(agents.ownerId, filter.userId));
102
+ if (filter?.status) conditions.push(eq(agents.status, filter.status));
103
+ if (filter?.type) conditions.push(eq(agents.type, filter.type));
104
+ if (conditions.length > 0) {
105
+ query = query.where(and(...conditions));
106
+ }
107
+ const rows = await query;
108
+ const agentIds = rows.map((r) => r.id);
109
+ const permsByAgent = /* @__PURE__ */ new Map();
110
+ for (const id of agentIds) {
111
+ const perms = await db.select().from(permissions).where(eq(permissions.agentId, id));
112
+ permsByAgent.set(id, perms.map(toPermission));
113
+ }
114
+ return rows.map((agent) => ({
115
+ id: agent.id,
116
+ ownerId: agent.ownerId,
117
+ name: agent.name,
118
+ type: agent.type,
119
+ token: "",
120
+ permissions: permsByAgent.get(agent.id) ?? [],
121
+ status: agent.status,
122
+ expiresAt: agent.expiresAt,
123
+ createdAt: agent.createdAt,
124
+ updatedAt: agent.updatedAt
125
+ }));
126
+ }
127
+ async function update(agentId, input) {
128
+ const existing = await get(agentId);
129
+ if (!existing) throw new Error(`Agent ${agentId} not found.`);
130
+ const now = /* @__PURE__ */ new Date();
131
+ await db.update(agents).set({
132
+ name: input.name ?? existing.name,
133
+ expiresAt: input.expiresAt ?? existing.expiresAt,
134
+ metadata: input.metadata,
135
+ updatedAt: now
136
+ }).where(eq(agents.id, agentId));
137
+ if (input.permissions) {
138
+ await db.delete(permissions).where(eq(permissions.agentId, agentId));
139
+ if (input.permissions.length > 0) {
140
+ await db.insert(permissions).values(
141
+ input.permissions.map((p) => ({
142
+ id: randomUUID(),
143
+ agentId,
144
+ resource: p.resource,
145
+ actions: p.actions,
146
+ constraints: p.constraints ?? null,
147
+ createdAt: now
148
+ }))
149
+ );
150
+ }
151
+ }
152
+ const updated = await get(agentId);
153
+ if (!updated) throw new Error(`Agent ${agentId} disappeared after update.`);
154
+ return updated;
155
+ }
156
+ async function revoke(agentId) {
157
+ const existing = await get(agentId);
158
+ if (!existing) throw new Error(`Agent ${agentId} not found.`);
159
+ await db.update(agents).set({ status: "revoked", updatedAt: /* @__PURE__ */ new Date() }).where(eq(agents.id, agentId));
160
+ }
161
+ async function rotate(agentId) {
162
+ const existing = await get(agentId);
163
+ if (!existing) throw new Error(`Agent ${agentId} not found.`);
164
+ if (existing.status !== "active")
165
+ throw new Error(`Cannot rotate token for ${existing.status} agent.`);
166
+ const { token, hash, prefix } = generateAgentToken();
167
+ const now = /* @__PURE__ */ new Date();
168
+ await db.update(agents).set({ tokenHash: hash, tokenPrefix: prefix, updatedAt: now }).where(eq(agents.id, agentId));
169
+ return { ...existing, token, updatedAt: now };
170
+ }
171
+ async function validateToken(token) {
172
+ const hash = createHash("sha256").update(token).digest("hex");
173
+ const rows = await db.select().from(agents).where(eq(agents.tokenHash, hash)).limit(1);
174
+ const agent = rows[0];
175
+ if (!agent) return null;
176
+ if (agent.status !== "active") return null;
177
+ if (agent.expiresAt && agent.expiresAt < /* @__PURE__ */ new Date()) {
178
+ await db.update(agents).set({ status: "expired", updatedAt: /* @__PURE__ */ new Date() }).where(eq(agents.id, agent.id));
179
+ return null;
180
+ }
181
+ await db.update(agents).set({ lastActiveAt: /* @__PURE__ */ new Date() }).where(eq(agents.id, agent.id));
182
+ const perms = await db.select().from(permissions).where(eq(permissions.agentId, agent.id));
183
+ return {
184
+ id: agent.id,
185
+ ownerId: agent.ownerId,
186
+ name: agent.name,
187
+ type: agent.type,
188
+ token: "",
189
+ permissions: perms.map(toPermission),
190
+ status: "active",
191
+ expiresAt: agent.expiresAt,
192
+ createdAt: agent.createdAt,
193
+ updatedAt: agent.updatedAt
194
+ };
195
+ }
196
+ return { create, get, list, update, revoke, rotate, validateToken };
197
+ }
198
+ function toPermission(row) {
199
+ return {
200
+ resource: row.resource,
201
+ actions: row.actions,
202
+ constraints: row.constraints ?? void 0
203
+ };
204
+ }
205
+
206
+ export { createAgentModule };
207
+ //# sourceMappingURL=chunk-DTCKF26N.js.map
208
+ //# sourceMappingURL=chunk-DTCKF26N.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/agent/agent.ts"],"names":[],"mappings":"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","file":"chunk-DTCKF26N.js","sourcesContent":["import { createHash, randomBytes, randomUUID } from \"node:crypto\";\nimport { and, eq } from \"drizzle-orm\";\nimport type { Database } from \"../db/database.js\";\nimport { agents, permissions } from \"../db/schema.js\";\nimport type {\n\tAgentFilter,\n\tAgentIdentity,\n\tCreateAgentInput,\n\tPermission,\n\tUpdateAgentInput,\n} from \"../types.js\";\n\ninterface AgentModuleConfig {\n\tdb: Database;\n\tmaxPerUser: number;\n\tdefaultPermissions: string[];\n\ttokenExpiry: string;\n}\n\n/**\n * Generate a secure agent token.\n * Returns { token, hash, prefix } where:\n * - token: the full token (given to the agent, never stored)\n * - hash: SHA-256 hash (stored in DB)\n * - prefix: first 8 chars (for identification in logs/UI)\n */\nfunction generateAgentToken(): { token: string; hash: string; prefix: string } {\n\tconst tokenBytes = randomBytes(32);\n\tconst token = `kv_${tokenBytes.toString(\"base64url\")}`;\n\tconst hash = createHash(\"sha256\").update(token).digest(\"hex\");\n\tconst prefix = token.slice(0, 11); // \"kv_\" + 8 chars\n\treturn { token, hash, prefix };\n}\n\nfunction parseTokenExpiry(expiry: string): Date {\n\tconst now = Date.now();\n\tconst match = expiry.match(/^(\\d+)([smhd])$/);\n\tif (!match) {\n\t\tthrow new Error(`Invalid token expiry format: ${expiry}. Use format like \"24h\", \"7d\", \"30m\".`);\n\t}\n\tconst value = Number.parseInt(match[1] as string, 10);\n\tconst unit = match[2];\n\tconst multipliers: Record<string, number> = {\n\t\ts: 1000,\n\t\tm: 60 * 1000,\n\t\th: 60 * 60 * 1000,\n\t\td: 24 * 60 * 60 * 1000,\n\t};\n\treturn new Date(now + value * (multipliers[unit as string] ?? 0));\n}\n\n/**\n * Create the agent identity module.\n * Handles CRUD operations for AI agent identities.\n */\nexport function createAgentModule(config: AgentModuleConfig) {\n\tconst { db, maxPerUser, tokenExpiry } = config;\n\n\tasync function create(input: CreateAgentInput): Promise<AgentIdentity & { token: string }> {\n\t\t// Check max agents per user\n\t\tconst existing = await db\n\t\t\t.select()\n\t\t\t.from(agents)\n\t\t\t.where(and(eq(agents.ownerId, input.ownerId), eq(agents.status, \"active\")));\n\n\t\tif (existing.length >= maxPerUser) {\n\t\t\tthrow new Error(\n\t\t\t\t`User ${input.ownerId} has reached the maximum of ${maxPerUser} active agents.`,\n\t\t\t);\n\t\t}\n\n\t\tconst id = randomUUID();\n\t\tconst { token, hash, prefix } = generateAgentToken();\n\t\tconst now = new Date();\n\t\tconst expires = input.expiresAt ?? parseTokenExpiry(tokenExpiry);\n\n\t\t// Insert agent\n\t\tawait db.insert(agents).values({\n\t\t\tid,\n\t\t\townerId: input.ownerId,\n\t\t\tname: input.name,\n\t\t\ttype: input.type,\n\t\t\tstatus: \"active\",\n\t\t\ttokenHash: hash,\n\t\t\ttokenPrefix: prefix,\n\t\t\texpiresAt: expires,\n\t\t\tmetadata: input.metadata ?? {},\n\t\t\tcreatedAt: now,\n\t\t\tupdatedAt: now,\n\t\t});\n\n\t\t// Insert permissions\n\t\tif (input.permissions.length > 0) {\n\t\t\tawait db.insert(permissions).values(\n\t\t\t\tinput.permissions.map((p) => ({\n\t\t\t\t\tid: randomUUID(),\n\t\t\t\t\tagentId: id,\n\t\t\t\t\tresource: p.resource,\n\t\t\t\t\tactions: p.actions,\n\t\t\t\t\tconstraints: p.constraints ?? null,\n\t\t\t\t\tcreatedAt: now,\n\t\t\t\t})),\n\t\t\t);\n\t\t}\n\n\t\treturn {\n\t\t\tid,\n\t\t\townerId: input.ownerId,\n\t\t\tname: input.name,\n\t\t\ttype: input.type,\n\t\t\ttoken,\n\t\t\tpermissions: input.permissions,\n\t\t\tstatus: \"active\",\n\t\t\texpiresAt: expires,\n\t\t\tcreatedAt: now,\n\t\t\tupdatedAt: now,\n\t\t};\n\t}\n\n\tasync function get(agentId: string): Promise<AgentIdentity | null> {\n\t\tconst rows = await db.select().from(agents).where(eq(agents.id, agentId)).limit(1);\n\t\tconst agent = rows[0];\n\t\tif (!agent) return null;\n\n\t\tconst perms = await db.select().from(permissions).where(eq(permissions.agentId, agentId));\n\n\t\treturn {\n\t\t\tid: agent.id,\n\t\t\townerId: agent.ownerId,\n\t\t\tname: agent.name,\n\t\t\ttype: agent.type as AgentIdentity[\"type\"],\n\t\t\ttoken: \"\", // never return token after creation\n\t\t\tpermissions: perms.map(toPermission),\n\t\t\tstatus: agent.status as AgentIdentity[\"status\"],\n\t\t\texpiresAt: agent.expiresAt,\n\t\t\tcreatedAt: agent.createdAt,\n\t\t\tupdatedAt: agent.updatedAt,\n\t\t};\n\t}\n\n\tasync function list(filter?: AgentFilter): Promise<AgentIdentity[]> {\n\t\tlet query = db.select().from(agents).$dynamic();\n\n\t\tconst conditions = [];\n\t\tif (filter?.userId) conditions.push(eq(agents.ownerId, filter.userId));\n\t\tif (filter?.status) conditions.push(eq(agents.status, filter.status));\n\t\tif (filter?.type) conditions.push(eq(agents.type, filter.type));\n\n\t\tif (conditions.length > 0) {\n\t\t\tquery = query.where(and(...conditions));\n\t\t}\n\n\t\tconst rows = await query;\n\n\t\t// Load permissions for all agents\n\t\tconst agentIds = rows.map((r) => r.id);\n\t\tconst permsByAgent = new Map<string, Permission[]>();\n\t\tfor (const id of agentIds) {\n\t\t\tconst perms = await db.select().from(permissions).where(eq(permissions.agentId, id));\n\t\t\tpermsByAgent.set(id, perms.map(toPermission));\n\t\t}\n\n\t\treturn rows.map((agent) => ({\n\t\t\tid: agent.id,\n\t\t\townerId: agent.ownerId,\n\t\t\tname: agent.name,\n\t\t\ttype: agent.type as AgentIdentity[\"type\"],\n\t\t\ttoken: \"\",\n\t\t\tpermissions: permsByAgent.get(agent.id) ?? [],\n\t\t\tstatus: agent.status as AgentIdentity[\"status\"],\n\t\t\texpiresAt: agent.expiresAt,\n\t\t\tcreatedAt: agent.createdAt,\n\t\t\tupdatedAt: agent.updatedAt,\n\t\t}));\n\t}\n\n\tasync function update(agentId: string, input: UpdateAgentInput): Promise<AgentIdentity> {\n\t\tconst existing = await get(agentId);\n\t\tif (!existing) throw new Error(`Agent ${agentId} not found.`);\n\n\t\tconst now = new Date();\n\n\t\tawait db\n\t\t\t.update(agents)\n\t\t\t.set({\n\t\t\t\tname: input.name ?? existing.name,\n\t\t\t\texpiresAt: input.expiresAt ?? existing.expiresAt,\n\t\t\t\tmetadata: input.metadata,\n\t\t\t\tupdatedAt: now,\n\t\t\t})\n\t\t\t.where(eq(agents.id, agentId));\n\n\t\t// Replace permissions if provided\n\t\tif (input.permissions) {\n\t\t\tawait db.delete(permissions).where(eq(permissions.agentId, agentId));\n\t\t\tif (input.permissions.length > 0) {\n\t\t\t\tawait db.insert(permissions).values(\n\t\t\t\t\tinput.permissions.map((p) => ({\n\t\t\t\t\t\tid: randomUUID(),\n\t\t\t\t\t\tagentId,\n\t\t\t\t\t\tresource: p.resource,\n\t\t\t\t\t\tactions: p.actions,\n\t\t\t\t\t\tconstraints: p.constraints ?? null,\n\t\t\t\t\t\tcreatedAt: now,\n\t\t\t\t\t})),\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tconst updated = await get(agentId);\n\t\tif (!updated) throw new Error(`Agent ${agentId} disappeared after update.`);\n\t\treturn updated;\n\t}\n\n\tasync function revoke(agentId: string): Promise<void> {\n\t\tconst existing = await get(agentId);\n\t\tif (!existing) throw new Error(`Agent ${agentId} not found.`);\n\n\t\tawait db\n\t\t\t.update(agents)\n\t\t\t.set({ status: \"revoked\", updatedAt: new Date() })\n\t\t\t.where(eq(agents.id, agentId));\n\t}\n\n\tasync function rotate(agentId: string): Promise<AgentIdentity & { token: string }> {\n\t\tconst existing = await get(agentId);\n\t\tif (!existing) throw new Error(`Agent ${agentId} not found.`);\n\t\tif (existing.status !== \"active\")\n\t\t\tthrow new Error(`Cannot rotate token for ${existing.status} agent.`);\n\n\t\tconst { token, hash, prefix } = generateAgentToken();\n\t\tconst now = new Date();\n\n\t\tawait db\n\t\t\t.update(agents)\n\t\t\t.set({ tokenHash: hash, tokenPrefix: prefix, updatedAt: now })\n\t\t\t.where(eq(agents.id, agentId));\n\n\t\treturn { ...existing, token, updatedAt: now };\n\t}\n\n\t/**\n\t * Validate an agent token and return the agent identity.\n\t * Used internally by the authorization engine.\n\t */\n\tasync function validateToken(token: string): Promise<AgentIdentity | null> {\n\t\tconst hash = createHash(\"sha256\").update(token).digest(\"hex\");\n\t\tconst rows = await db.select().from(agents).where(eq(agents.tokenHash, hash)).limit(1);\n\t\tconst agent = rows[0];\n\t\tif (!agent) return null;\n\n\t\t// Check status\n\t\tif (agent.status !== \"active\") return null;\n\n\t\t// Check expiry\n\t\tif (agent.expiresAt && agent.expiresAt < new Date()) {\n\t\t\tawait db\n\t\t\t\t.update(agents)\n\t\t\t\t.set({ status: \"expired\", updatedAt: new Date() })\n\t\t\t\t.where(eq(agents.id, agent.id));\n\t\t\treturn null;\n\t\t}\n\n\t\t// Update last active\n\t\tawait db.update(agents).set({ lastActiveAt: new Date() }).where(eq(agents.id, agent.id));\n\n\t\tconst perms = await db.select().from(permissions).where(eq(permissions.agentId, agent.id));\n\n\t\treturn {\n\t\t\tid: agent.id,\n\t\t\townerId: agent.ownerId,\n\t\t\tname: agent.name,\n\t\t\ttype: agent.type as AgentIdentity[\"type\"],\n\t\t\ttoken: \"\",\n\t\t\tpermissions: perms.map(toPermission),\n\t\t\tstatus: \"active\",\n\t\t\texpiresAt: agent.expiresAt,\n\t\t\tcreatedAt: agent.createdAt,\n\t\t\tupdatedAt: agent.updatedAt,\n\t\t};\n\t}\n\n\treturn { create, get, list, update, revoke, rotate, validateToken };\n}\n\nfunction toPermission(row: {\n\tresource: string;\n\tactions: string[];\n\tconstraints: unknown;\n}): Permission {\n\treturn {\n\t\tresource: row.resource,\n\t\tactions: row.actions,\n\t\tconstraints: (row.constraints as Permission[\"constraints\"]) ?? undefined,\n\t};\n}\n"]}
@@ -0,0 +1,9 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __export = (target, all) => {
3
+ for (var name in all)
4
+ __defProp(target, name, { get: all[name], enumerable: true });
5
+ };
6
+
7
+ export { __export };
8
+ //# sourceMappingURL=chunk-PZ5AY32C.js.map
9
+ //# sourceMappingURL=chunk-PZ5AY32C.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"names":[],"mappings":"","file":"chunk-PZ5AY32C.js"}