@kavachos/hono 0.0.2
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 +21 -0
- package/README.md +74 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.js +669 -0
- package/dist/index.js.map +1 -0
- package/package.json +52 -0
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.
|
package/README.md
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# @kavachos/hono
|
|
2
|
+
|
|
3
|
+
Hono adapter for KavachOS.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@kavachos/hono)
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
pnpm add kavachos @kavachos/hono
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## Usage
|
|
14
|
+
|
|
15
|
+
```typescript
|
|
16
|
+
import { serve } from '@hono/node-server';
|
|
17
|
+
import { Hono } from 'hono';
|
|
18
|
+
import { createKavach } from 'kavachos';
|
|
19
|
+
import { kavachHono } from '@kavachos/hono';
|
|
20
|
+
|
|
21
|
+
const kavach = createKavach({
|
|
22
|
+
database: { provider: 'sqlite', url: 'kavach.db' },
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
const app = new Hono();
|
|
26
|
+
|
|
27
|
+
// Mount all KavachOS routes at /api/kavach
|
|
28
|
+
app.route('/api/kavach', kavachHono(kavach));
|
|
29
|
+
|
|
30
|
+
serve({ fetch: app.fetch, port: 3000 });
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
This mounts the full KavachOS REST API: agent CRUD, authorization, delegations, audit logs, and dashboard stats.
|
|
34
|
+
|
|
35
|
+
### With MCP OAuth 2.1
|
|
36
|
+
|
|
37
|
+
```typescript
|
|
38
|
+
import { createMcpModule } from 'kavachos/mcp';
|
|
39
|
+
import { kavachHono } from '@kavachos/hono';
|
|
40
|
+
|
|
41
|
+
const mcp = createMcpModule({
|
|
42
|
+
issuer: 'https://your-app.com',
|
|
43
|
+
// ...
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
app.route('/api/kavach', kavachHono(kavach, { mcp }));
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
When `mcp` is provided, the OAuth 2.1 endpoints are enabled:
|
|
50
|
+
|
|
51
|
+
- `GET /.well-known/oauth-authorization-server`
|
|
52
|
+
- `GET /.well-known/oauth-protected-resource`
|
|
53
|
+
- `POST /mcp/register`
|
|
54
|
+
- `GET /mcp/authorize`
|
|
55
|
+
- `POST /mcp/token`
|
|
56
|
+
|
|
57
|
+
## API surface
|
|
58
|
+
|
|
59
|
+
`kavachHono(kavach, options?)` returns a `Hono` instance with all routes registered. Pass it to `app.route()` with your chosen prefix.
|
|
60
|
+
|
|
61
|
+
| Option | Type | Description |
|
|
62
|
+
|--------|------|-------------|
|
|
63
|
+
| `mcp` | `McpAuthModule` | Enables MCP OAuth 2.1 endpoints |
|
|
64
|
+
|
|
65
|
+
For full docs on agent identity, permissions, delegation, and audit, see the main [kavachos](https://www.npmjs.com/package/kavachos) package.
|
|
66
|
+
|
|
67
|
+
## Links
|
|
68
|
+
|
|
69
|
+
- [Documentation](https://kavachos.dev/docs)
|
|
70
|
+
- [GitHub](https://github.com/kavachos/kavachos)
|
|
71
|
+
|
|
72
|
+
## License
|
|
73
|
+
|
|
74
|
+
MIT
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { Hono } from 'hono';
|
|
2
|
+
import { Kavach } from 'kavachos';
|
|
3
|
+
import { McpAuthModule } from 'kavachos/mcp';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Create a Hono app with all KavachOS REST API routes mounted.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```typescript
|
|
10
|
+
* import { createKavach } from 'kavachos';
|
|
11
|
+
* import { kavachHono } from '@kavachos/hono';
|
|
12
|
+
* import { serve } from '@hono/node-server';
|
|
13
|
+
*
|
|
14
|
+
* const kavach = createKavach({ database: { provider: 'sqlite', url: 'kavach.db' } });
|
|
15
|
+
* const app = kavachHono(kavach);
|
|
16
|
+
* serve({ fetch: app.fetch, port: 3000 });
|
|
17
|
+
* ```
|
|
18
|
+
*
|
|
19
|
+
* With MCP OAuth 2.1:
|
|
20
|
+
* ```typescript
|
|
21
|
+
* import { createMcpModule } from 'kavachos/mcp';
|
|
22
|
+
* const mcp = createMcpModule({ ... });
|
|
23
|
+
* const app = kavachHono(kavach, { mcp });
|
|
24
|
+
* ```
|
|
25
|
+
*/
|
|
26
|
+
declare function kavachHono(kavach: Kavach, options?: {
|
|
27
|
+
mcp?: McpAuthModule;
|
|
28
|
+
}): Hono;
|
|
29
|
+
|
|
30
|
+
export { kavachHono };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,669 @@
|
|
|
1
|
+
import { Hono } from 'hono';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
|
|
4
|
+
// src/adapter.ts
|
|
5
|
+
var PermissionConstraintsSchema = z.object({
|
|
6
|
+
maxCallsPerHour: z.number().int().positive().optional(),
|
|
7
|
+
allowedArgPatterns: z.array(z.string()).optional(),
|
|
8
|
+
requireApproval: z.boolean().optional(),
|
|
9
|
+
timeWindow: z.object({
|
|
10
|
+
start: z.string(),
|
|
11
|
+
end: z.string()
|
|
12
|
+
}).optional(),
|
|
13
|
+
ipAllowlist: z.array(z.string()).optional()
|
|
14
|
+
});
|
|
15
|
+
var PermissionSchema = z.object({
|
|
16
|
+
resource: z.string().min(1),
|
|
17
|
+
actions: z.array(z.string().min(1)).min(1),
|
|
18
|
+
constraints: PermissionConstraintsSchema.optional()
|
|
19
|
+
});
|
|
20
|
+
var CreateAgentSchema = z.object({
|
|
21
|
+
ownerId: z.string().min(1),
|
|
22
|
+
name: z.string().min(1),
|
|
23
|
+
type: z.enum(["autonomous", "delegated", "service"]),
|
|
24
|
+
permissions: z.array(PermissionSchema).min(1),
|
|
25
|
+
expiresAt: z.coerce.date().optional(),
|
|
26
|
+
metadata: z.record(z.unknown()).optional()
|
|
27
|
+
});
|
|
28
|
+
var UpdateAgentSchema = z.object({
|
|
29
|
+
name: z.string().min(1).optional(),
|
|
30
|
+
permissions: z.array(PermissionSchema).optional(),
|
|
31
|
+
expiresAt: z.coerce.date().optional(),
|
|
32
|
+
metadata: z.record(z.unknown()).optional()
|
|
33
|
+
});
|
|
34
|
+
var AuthorizeSchema = z.object({
|
|
35
|
+
agentId: z.string().min(1),
|
|
36
|
+
action: z.string().min(1),
|
|
37
|
+
resource: z.string().min(1),
|
|
38
|
+
arguments: z.record(z.unknown()).optional()
|
|
39
|
+
});
|
|
40
|
+
var AuthorizeByTokenSchema = z.object({
|
|
41
|
+
action: z.string().min(1),
|
|
42
|
+
resource: z.string().min(1),
|
|
43
|
+
arguments: z.record(z.unknown()).optional()
|
|
44
|
+
});
|
|
45
|
+
var DelegateSchema = z.object({
|
|
46
|
+
fromAgent: z.string().min(1),
|
|
47
|
+
toAgent: z.string().min(1),
|
|
48
|
+
permissions: z.array(PermissionSchema).min(1),
|
|
49
|
+
expiresAt: z.coerce.date(),
|
|
50
|
+
maxDepth: z.number().int().positive().optional()
|
|
51
|
+
});
|
|
52
|
+
function ok(data, status = 200) {
|
|
53
|
+
return new Response(JSON.stringify({ data }), {
|
|
54
|
+
status,
|
|
55
|
+
headers: { "Content-Type": "application/json" }
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
function created(data) {
|
|
59
|
+
return ok(data, 201);
|
|
60
|
+
}
|
|
61
|
+
function errorResponse(code, message, status) {
|
|
62
|
+
return new Response(JSON.stringify({ error: { code, message } }), {
|
|
63
|
+
status,
|
|
64
|
+
headers: { "Content-Type": "application/json" }
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
function badRequest(message) {
|
|
68
|
+
return errorResponse("BAD_REQUEST", message, 400);
|
|
69
|
+
}
|
|
70
|
+
function unauthorized(message = "Unauthorized") {
|
|
71
|
+
return errorResponse("UNAUTHORIZED", message, 401);
|
|
72
|
+
}
|
|
73
|
+
function notFound(message = "Not found") {
|
|
74
|
+
return errorResponse("NOT_FOUND", message, 404);
|
|
75
|
+
}
|
|
76
|
+
function internalError(message = "Internal server error") {
|
|
77
|
+
return errorResponse("INTERNAL_ERROR", message, 500);
|
|
78
|
+
}
|
|
79
|
+
function validationError(issues) {
|
|
80
|
+
const message = issues.map((i) => `${i.path.join(".")}: ${i.message}`).join(", ");
|
|
81
|
+
return badRequest(`Validation failed: ${message}`);
|
|
82
|
+
}
|
|
83
|
+
var MCP_CORS_HEADERS = {
|
|
84
|
+
"Access-Control-Allow-Origin": "*",
|
|
85
|
+
"Access-Control-Allow-Methods": "GET, POST, OPTIONS",
|
|
86
|
+
"Access-Control-Allow-Headers": "Content-Type, Authorization",
|
|
87
|
+
"Access-Control-Max-Age": "86400"
|
|
88
|
+
};
|
|
89
|
+
function mcpOk(data, status = 200) {
|
|
90
|
+
return new Response(JSON.stringify(data), {
|
|
91
|
+
status,
|
|
92
|
+
headers: { "Content-Type": "application/json", ...MCP_CORS_HEADERS }
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
function mcpError(code, message, status) {
|
|
96
|
+
return new Response(JSON.stringify({ error: code, error_description: message }), {
|
|
97
|
+
status,
|
|
98
|
+
headers: { "Content-Type": "application/json", ...MCP_CORS_HEADERS }
|
|
99
|
+
});
|
|
100
|
+
}
|
|
101
|
+
function mcpNoStore(data, status = 200) {
|
|
102
|
+
return new Response(JSON.stringify(data), {
|
|
103
|
+
status,
|
|
104
|
+
headers: {
|
|
105
|
+
"Content-Type": "application/json",
|
|
106
|
+
"Cache-Control": "no-store",
|
|
107
|
+
Pragma: "no-cache",
|
|
108
|
+
...MCP_CORS_HEADERS
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
function kavachHono(kavach, options) {
|
|
113
|
+
const app = new Hono();
|
|
114
|
+
const mcp = options?.mcp;
|
|
115
|
+
app.post("/agents", async (c) => {
|
|
116
|
+
let body;
|
|
117
|
+
try {
|
|
118
|
+
body = await c.req.json();
|
|
119
|
+
} catch {
|
|
120
|
+
const res = badRequest("Invalid JSON body");
|
|
121
|
+
return c.newResponse(res.body, res);
|
|
122
|
+
}
|
|
123
|
+
const parsed = CreateAgentSchema.safeParse(body);
|
|
124
|
+
if (!parsed.success) {
|
|
125
|
+
const res = validationError(parsed.error.issues);
|
|
126
|
+
return c.newResponse(res.body, res);
|
|
127
|
+
}
|
|
128
|
+
try {
|
|
129
|
+
const input = {
|
|
130
|
+
...parsed.data,
|
|
131
|
+
permissions: parsed.data.permissions
|
|
132
|
+
};
|
|
133
|
+
const agent = await kavach.agent.create(input);
|
|
134
|
+
const res = created(agent);
|
|
135
|
+
return c.newResponse(res.body, res);
|
|
136
|
+
} catch (err) {
|
|
137
|
+
const message = err instanceof Error ? err.message : "Failed to create agent";
|
|
138
|
+
const res = internalError(message);
|
|
139
|
+
return c.newResponse(res.body, res);
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
app.get("/agents", async (c) => {
|
|
143
|
+
const userId = c.req.query("userId");
|
|
144
|
+
const statusRaw = c.req.query("status");
|
|
145
|
+
const typeRaw = c.req.query("type");
|
|
146
|
+
const filter = {};
|
|
147
|
+
if (userId) filter.userId = userId;
|
|
148
|
+
if (statusRaw === "active" || statusRaw === "revoked" || statusRaw === "expired") {
|
|
149
|
+
filter.status = statusRaw;
|
|
150
|
+
}
|
|
151
|
+
if (typeRaw === "autonomous" || typeRaw === "delegated" || typeRaw === "service") {
|
|
152
|
+
filter.type = typeRaw;
|
|
153
|
+
}
|
|
154
|
+
try {
|
|
155
|
+
const agents = await kavach.agent.list(filter);
|
|
156
|
+
const res = ok(agents);
|
|
157
|
+
return c.newResponse(res.body, res);
|
|
158
|
+
} catch (err) {
|
|
159
|
+
const message = err instanceof Error ? err.message : "Failed to list agents";
|
|
160
|
+
const res = internalError(message);
|
|
161
|
+
return c.newResponse(res.body, res);
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
app.get("/agents/:id", async (c) => {
|
|
165
|
+
const id = c.req.param("id");
|
|
166
|
+
try {
|
|
167
|
+
const agent = await kavach.agent.get(id);
|
|
168
|
+
if (!agent) {
|
|
169
|
+
const res2 = notFound(`Agent "${id}" not found`);
|
|
170
|
+
return c.newResponse(res2.body, res2);
|
|
171
|
+
}
|
|
172
|
+
const res = ok(agent);
|
|
173
|
+
return c.newResponse(res.body, res);
|
|
174
|
+
} catch (err) {
|
|
175
|
+
const message = err instanceof Error ? err.message : "Failed to get agent";
|
|
176
|
+
const res = internalError(message);
|
|
177
|
+
return c.newResponse(res.body, res);
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
app.patch("/agents/:id", async (c) => {
|
|
181
|
+
const id = c.req.param("id");
|
|
182
|
+
let body;
|
|
183
|
+
try {
|
|
184
|
+
body = await c.req.json();
|
|
185
|
+
} catch {
|
|
186
|
+
const res = badRequest("Invalid JSON body");
|
|
187
|
+
return c.newResponse(res.body, res);
|
|
188
|
+
}
|
|
189
|
+
const parsed = UpdateAgentSchema.safeParse(body);
|
|
190
|
+
if (!parsed.success) {
|
|
191
|
+
const res = validationError(parsed.error.issues);
|
|
192
|
+
return c.newResponse(res.body, res);
|
|
193
|
+
}
|
|
194
|
+
try {
|
|
195
|
+
const input = {
|
|
196
|
+
...parsed.data,
|
|
197
|
+
permissions: parsed.data.permissions
|
|
198
|
+
};
|
|
199
|
+
const agent = await kavach.agent.update(id, input);
|
|
200
|
+
const res = ok(agent);
|
|
201
|
+
return c.newResponse(res.body, res);
|
|
202
|
+
} catch (err) {
|
|
203
|
+
const message = err instanceof Error ? err.message : "Failed to update agent";
|
|
204
|
+
if (message.includes("not found")) {
|
|
205
|
+
const res2 = notFound(message);
|
|
206
|
+
return c.newResponse(res2.body, res2);
|
|
207
|
+
}
|
|
208
|
+
const res = internalError(message);
|
|
209
|
+
return c.newResponse(res.body, res);
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
app.delete("/agents/:id", async (c) => {
|
|
213
|
+
const id = c.req.param("id");
|
|
214
|
+
try {
|
|
215
|
+
await kavach.agent.revoke(id);
|
|
216
|
+
return new Response(null, { status: 204 });
|
|
217
|
+
} catch (err) {
|
|
218
|
+
const message = err instanceof Error ? err.message : "Failed to revoke agent";
|
|
219
|
+
if (message.includes("not found")) {
|
|
220
|
+
const res2 = notFound(message);
|
|
221
|
+
return c.newResponse(res2.body, res2);
|
|
222
|
+
}
|
|
223
|
+
const res = internalError(message);
|
|
224
|
+
return c.newResponse(res.body, res);
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
app.post("/agents/:id/rotate", async (c) => {
|
|
228
|
+
const id = c.req.param("id");
|
|
229
|
+
try {
|
|
230
|
+
const agent = await kavach.agent.rotate(id);
|
|
231
|
+
const res = ok(agent);
|
|
232
|
+
return c.newResponse(res.body, res);
|
|
233
|
+
} catch (err) {
|
|
234
|
+
const message = err instanceof Error ? err.message : "Failed to rotate agent token";
|
|
235
|
+
if (message.includes("not found")) {
|
|
236
|
+
const res2 = notFound(message);
|
|
237
|
+
return c.newResponse(res2.body, res2);
|
|
238
|
+
}
|
|
239
|
+
const res = internalError(message);
|
|
240
|
+
return c.newResponse(res.body, res);
|
|
241
|
+
}
|
|
242
|
+
});
|
|
243
|
+
app.post("/authorize", async (c) => {
|
|
244
|
+
let body;
|
|
245
|
+
try {
|
|
246
|
+
body = await c.req.json();
|
|
247
|
+
} catch {
|
|
248
|
+
const res = badRequest("Invalid JSON body");
|
|
249
|
+
return c.newResponse(res.body, res);
|
|
250
|
+
}
|
|
251
|
+
const parsed = AuthorizeSchema.safeParse(body);
|
|
252
|
+
if (!parsed.success) {
|
|
253
|
+
const res = validationError(parsed.error.issues);
|
|
254
|
+
return c.newResponse(res.body, res);
|
|
255
|
+
}
|
|
256
|
+
try {
|
|
257
|
+
const ip = c.req.header("x-forwarded-for")?.split(",")[0]?.trim() ?? c.req.header("x-real-ip") ?? void 0;
|
|
258
|
+
const userAgent = c.req.header("user-agent") ?? void 0;
|
|
259
|
+
const result = await kavach.authorize(
|
|
260
|
+
parsed.data.agentId,
|
|
261
|
+
{
|
|
262
|
+
action: parsed.data.action,
|
|
263
|
+
resource: parsed.data.resource,
|
|
264
|
+
arguments: parsed.data.arguments
|
|
265
|
+
},
|
|
266
|
+
{ ip, userAgent }
|
|
267
|
+
);
|
|
268
|
+
const status = result.allowed ? 200 : 403;
|
|
269
|
+
const res = new Response(JSON.stringify({ data: result }), {
|
|
270
|
+
status,
|
|
271
|
+
headers: { "Content-Type": "application/json" }
|
|
272
|
+
});
|
|
273
|
+
return c.newResponse(res.body, res);
|
|
274
|
+
} catch (err) {
|
|
275
|
+
const message = err instanceof Error ? err.message : "Authorization check failed";
|
|
276
|
+
const res = internalError(message);
|
|
277
|
+
return c.newResponse(res.body, res);
|
|
278
|
+
}
|
|
279
|
+
});
|
|
280
|
+
app.post("/authorize/token", async (c) => {
|
|
281
|
+
const authHeader = c.req.header("Authorization");
|
|
282
|
+
if (!authHeader?.startsWith("Bearer ")) {
|
|
283
|
+
const res = unauthorized("Missing or invalid Authorization header");
|
|
284
|
+
return c.newResponse(res.body, res);
|
|
285
|
+
}
|
|
286
|
+
const token = authHeader.slice(7);
|
|
287
|
+
let body;
|
|
288
|
+
try {
|
|
289
|
+
body = await c.req.json();
|
|
290
|
+
} catch {
|
|
291
|
+
const res = badRequest("Invalid JSON body");
|
|
292
|
+
return c.newResponse(res.body, res);
|
|
293
|
+
}
|
|
294
|
+
const parsed = AuthorizeByTokenSchema.safeParse(body);
|
|
295
|
+
if (!parsed.success) {
|
|
296
|
+
const res = validationError(parsed.error.issues);
|
|
297
|
+
return c.newResponse(res.body, res);
|
|
298
|
+
}
|
|
299
|
+
try {
|
|
300
|
+
const ip = c.req.header("x-forwarded-for")?.split(",")[0]?.trim() ?? c.req.header("x-real-ip") ?? void 0;
|
|
301
|
+
const userAgent = c.req.header("user-agent") ?? void 0;
|
|
302
|
+
const result = await kavach.authorizeByToken(
|
|
303
|
+
token,
|
|
304
|
+
{
|
|
305
|
+
action: parsed.data.action,
|
|
306
|
+
resource: parsed.data.resource,
|
|
307
|
+
arguments: parsed.data.arguments
|
|
308
|
+
},
|
|
309
|
+
{ ip, userAgent }
|
|
310
|
+
);
|
|
311
|
+
const status = result.allowed ? 200 : 403;
|
|
312
|
+
const res = new Response(JSON.stringify({ data: result }), {
|
|
313
|
+
status,
|
|
314
|
+
headers: { "Content-Type": "application/json" }
|
|
315
|
+
});
|
|
316
|
+
return c.newResponse(res.body, res);
|
|
317
|
+
} catch (err) {
|
|
318
|
+
const message = err instanceof Error ? err.message : "Authorization check failed";
|
|
319
|
+
const res = internalError(message);
|
|
320
|
+
return c.newResponse(res.body, res);
|
|
321
|
+
}
|
|
322
|
+
});
|
|
323
|
+
app.post("/delegations", async (c) => {
|
|
324
|
+
let body;
|
|
325
|
+
try {
|
|
326
|
+
body = await c.req.json();
|
|
327
|
+
} catch {
|
|
328
|
+
const res = badRequest("Invalid JSON body");
|
|
329
|
+
return c.newResponse(res.body, res);
|
|
330
|
+
}
|
|
331
|
+
const parsed = DelegateSchema.safeParse(body);
|
|
332
|
+
if (!parsed.success) {
|
|
333
|
+
const res = validationError(parsed.error.issues);
|
|
334
|
+
return c.newResponse(res.body, res);
|
|
335
|
+
}
|
|
336
|
+
try {
|
|
337
|
+
const input = {
|
|
338
|
+
...parsed.data,
|
|
339
|
+
permissions: parsed.data.permissions
|
|
340
|
+
};
|
|
341
|
+
const chain = await kavach.delegate(input);
|
|
342
|
+
const res = created(chain);
|
|
343
|
+
return c.newResponse(res.body, res);
|
|
344
|
+
} catch (err) {
|
|
345
|
+
const message = err instanceof Error ? err.message : "Failed to create delegation";
|
|
346
|
+
if (message.includes("not found")) {
|
|
347
|
+
const res2 = notFound(message);
|
|
348
|
+
return c.newResponse(res2.body, res2);
|
|
349
|
+
}
|
|
350
|
+
if (message.includes("exceeds") || message.includes("depth")) {
|
|
351
|
+
const res2 = badRequest(message);
|
|
352
|
+
return c.newResponse(res2.body, res2);
|
|
353
|
+
}
|
|
354
|
+
const res = internalError(message);
|
|
355
|
+
return c.newResponse(res.body, res);
|
|
356
|
+
}
|
|
357
|
+
});
|
|
358
|
+
app.delete("/delegations/:id", async (c) => {
|
|
359
|
+
const id = c.req.param("id");
|
|
360
|
+
try {
|
|
361
|
+
await kavach.delegation.revoke(id);
|
|
362
|
+
return new Response(null, { status: 204 });
|
|
363
|
+
} catch (err) {
|
|
364
|
+
const message = err instanceof Error ? err.message : "Failed to revoke delegation";
|
|
365
|
+
if (message.includes("not found")) {
|
|
366
|
+
const res2 = notFound(message);
|
|
367
|
+
return c.newResponse(res2.body, res2);
|
|
368
|
+
}
|
|
369
|
+
const res = internalError(message);
|
|
370
|
+
return c.newResponse(res.body, res);
|
|
371
|
+
}
|
|
372
|
+
});
|
|
373
|
+
app.get("/delegations/:agentId", async (c) => {
|
|
374
|
+
const agentId = c.req.param("agentId");
|
|
375
|
+
try {
|
|
376
|
+
const chains = await kavach.delegation.listChains(agentId);
|
|
377
|
+
const res = ok(chains);
|
|
378
|
+
return c.newResponse(res.body, res);
|
|
379
|
+
} catch (err) {
|
|
380
|
+
const message = err instanceof Error ? err.message : "Failed to list delegation chains";
|
|
381
|
+
const res = internalError(message);
|
|
382
|
+
return c.newResponse(res.body, res);
|
|
383
|
+
}
|
|
384
|
+
});
|
|
385
|
+
app.get("/audit", async (c) => {
|
|
386
|
+
const filter = {};
|
|
387
|
+
const agentId = c.req.query("agentId");
|
|
388
|
+
const userId = c.req.query("userId");
|
|
389
|
+
const since = c.req.query("since");
|
|
390
|
+
const until = c.req.query("until");
|
|
391
|
+
const actions = c.req.query("actions");
|
|
392
|
+
const resultRaw = c.req.query("result");
|
|
393
|
+
const limit = c.req.query("limit");
|
|
394
|
+
const offset = c.req.query("offset");
|
|
395
|
+
if (agentId) filter.agentId = agentId;
|
|
396
|
+
if (userId) filter.userId = userId;
|
|
397
|
+
if (since) {
|
|
398
|
+
const d = new Date(since);
|
|
399
|
+
if (!Number.isNaN(d.getTime())) filter.since = d;
|
|
400
|
+
}
|
|
401
|
+
if (until) {
|
|
402
|
+
const d = new Date(until);
|
|
403
|
+
if (!Number.isNaN(d.getTime())) filter.until = d;
|
|
404
|
+
}
|
|
405
|
+
if (actions) filter.actions = actions.split(",").map((a) => a.trim());
|
|
406
|
+
if (resultRaw === "allowed" || resultRaw === "denied" || resultRaw === "rate_limited") {
|
|
407
|
+
filter.result = resultRaw;
|
|
408
|
+
}
|
|
409
|
+
if (limit) {
|
|
410
|
+
const n = Number.parseInt(limit, 10);
|
|
411
|
+
if (!Number.isNaN(n) && n > 0) filter.limit = n;
|
|
412
|
+
}
|
|
413
|
+
if (offset) {
|
|
414
|
+
const n = Number.parseInt(offset, 10);
|
|
415
|
+
if (!Number.isNaN(n) && n >= 0) filter.offset = n;
|
|
416
|
+
}
|
|
417
|
+
try {
|
|
418
|
+
const entries = await kavach.audit.query(filter);
|
|
419
|
+
const res = ok(entries);
|
|
420
|
+
return c.newResponse(res.body, res);
|
|
421
|
+
} catch (err) {
|
|
422
|
+
const message = err instanceof Error ? err.message : "Failed to query audit logs";
|
|
423
|
+
const res = internalError(message);
|
|
424
|
+
return c.newResponse(res.body, res);
|
|
425
|
+
}
|
|
426
|
+
});
|
|
427
|
+
app.get("/audit/export", async (c) => {
|
|
428
|
+
const format = c.req.query("format") ?? "json";
|
|
429
|
+
if (format !== "json" && format !== "csv") {
|
|
430
|
+
const res = badRequest('format must be "json" or "csv"');
|
|
431
|
+
return c.newResponse(res.body, res);
|
|
432
|
+
}
|
|
433
|
+
const since = c.req.query("since");
|
|
434
|
+
const until = c.req.query("until");
|
|
435
|
+
const options2 = { format };
|
|
436
|
+
if (since) {
|
|
437
|
+
const d = new Date(since);
|
|
438
|
+
if (!Number.isNaN(d.getTime())) options2.since = d;
|
|
439
|
+
}
|
|
440
|
+
if (until) {
|
|
441
|
+
const d = new Date(until);
|
|
442
|
+
if (!Number.isNaN(d.getTime())) options2.until = d;
|
|
443
|
+
}
|
|
444
|
+
try {
|
|
445
|
+
const exported = await kavach.audit.export(options2);
|
|
446
|
+
const contentType = format === "csv" ? "text/csv" : "application/json";
|
|
447
|
+
return new Response(exported, {
|
|
448
|
+
status: 200,
|
|
449
|
+
headers: {
|
|
450
|
+
"Content-Type": contentType,
|
|
451
|
+
"Content-Disposition": `attachment; filename="audit-export.${format}"`
|
|
452
|
+
}
|
|
453
|
+
});
|
|
454
|
+
} catch (err) {
|
|
455
|
+
const message = err instanceof Error ? err.message : "Failed to export audit logs";
|
|
456
|
+
const res = internalError(message);
|
|
457
|
+
return c.newResponse(res.body, res);
|
|
458
|
+
}
|
|
459
|
+
});
|
|
460
|
+
app.options("/mcp/*", (_c) => {
|
|
461
|
+
return new Response(null, { status: 204, headers: MCP_CORS_HEADERS });
|
|
462
|
+
});
|
|
463
|
+
app.options("/.well-known/*", (_c) => {
|
|
464
|
+
return new Response(null, { status: 204, headers: MCP_CORS_HEADERS });
|
|
465
|
+
});
|
|
466
|
+
app.get("/.well-known/oauth-authorization-server", (c) => {
|
|
467
|
+
if (!mcp) {
|
|
468
|
+
const res = notFound("MCP module not configured");
|
|
469
|
+
return c.newResponse(res.body, res);
|
|
470
|
+
}
|
|
471
|
+
const metadata = mcp.getMetadata();
|
|
472
|
+
return c.newResponse(mcpOk(metadata).body, mcpOk(metadata));
|
|
473
|
+
});
|
|
474
|
+
app.get("/.well-known/oauth-protected-resource", (c) => {
|
|
475
|
+
if (!mcp) {
|
|
476
|
+
const res = notFound("MCP module not configured");
|
|
477
|
+
return c.newResponse(res.body, res);
|
|
478
|
+
}
|
|
479
|
+
const metadata = mcp.getProtectedResourceMetadata();
|
|
480
|
+
return c.newResponse(mcpOk(metadata).body, mcpOk(metadata));
|
|
481
|
+
});
|
|
482
|
+
app.post("/mcp/register", async (c) => {
|
|
483
|
+
if (!mcp) {
|
|
484
|
+
const res = notFound("MCP module not configured");
|
|
485
|
+
return c.newResponse(res.body, res);
|
|
486
|
+
}
|
|
487
|
+
let body;
|
|
488
|
+
try {
|
|
489
|
+
body = await c.req.json();
|
|
490
|
+
} catch {
|
|
491
|
+
const res = mcpError("invalid_request", "Invalid JSON body", 400);
|
|
492
|
+
return c.newResponse(res.body, res);
|
|
493
|
+
}
|
|
494
|
+
try {
|
|
495
|
+
const result = await mcp.registerClient(body);
|
|
496
|
+
if (!result.success) {
|
|
497
|
+
const res2 = mcpError("invalid_client_metadata", result.error.message, 400);
|
|
498
|
+
return c.newResponse(res2.body, res2);
|
|
499
|
+
}
|
|
500
|
+
const res = mcpNoStore(result.data, 201);
|
|
501
|
+
return c.newResponse(res.body, res);
|
|
502
|
+
} catch (err) {
|
|
503
|
+
const message = err instanceof Error ? err.message : "Registration failed";
|
|
504
|
+
const res = mcpError("server_error", message, 500);
|
|
505
|
+
return c.newResponse(res.body, res);
|
|
506
|
+
}
|
|
507
|
+
});
|
|
508
|
+
app.get("/mcp/authorize", async (c) => {
|
|
509
|
+
if (!mcp) {
|
|
510
|
+
const res = notFound("MCP module not configured");
|
|
511
|
+
return c.newResponse(res.body, res);
|
|
512
|
+
}
|
|
513
|
+
try {
|
|
514
|
+
const result = await mcp.authorize(c.req.raw);
|
|
515
|
+
if (!result.success) {
|
|
516
|
+
if (result.error.code === "LOGIN_REQUIRED") {
|
|
517
|
+
const details = result.error.details;
|
|
518
|
+
if (details?.loginPage) {
|
|
519
|
+
const loginUrl = new URL(details.loginPage);
|
|
520
|
+
if (details.returnTo) {
|
|
521
|
+
loginUrl.searchParams.set("returnTo", details.returnTo);
|
|
522
|
+
}
|
|
523
|
+
return c.redirect(loginUrl.toString(), 302);
|
|
524
|
+
}
|
|
525
|
+
}
|
|
526
|
+
const res = mcpError(result.error.code.toLowerCase(), result.error.message, 400);
|
|
527
|
+
return c.newResponse(res.body, res);
|
|
528
|
+
}
|
|
529
|
+
return c.redirect(result.data.redirectUri, 302);
|
|
530
|
+
} catch (err) {
|
|
531
|
+
const message = err instanceof Error ? err.message : "Authorization failed";
|
|
532
|
+
const res = mcpError("server_error", message, 500);
|
|
533
|
+
return c.newResponse(res.body, res);
|
|
534
|
+
}
|
|
535
|
+
});
|
|
536
|
+
app.post("/mcp/token", async (c) => {
|
|
537
|
+
if (!mcp) {
|
|
538
|
+
const res = notFound("MCP module not configured");
|
|
539
|
+
return c.newResponse(res.body, res);
|
|
540
|
+
}
|
|
541
|
+
try {
|
|
542
|
+
const result = await mcp.token(c.req.raw);
|
|
543
|
+
if (!result.success) {
|
|
544
|
+
const status = result.error.code === "INVALID_CLIENT" ? 401 : 400;
|
|
545
|
+
const res = mcpNoStore(
|
|
546
|
+
{
|
|
547
|
+
error: result.error.code.toLowerCase(),
|
|
548
|
+
error_description: result.error.message
|
|
549
|
+
},
|
|
550
|
+
status
|
|
551
|
+
);
|
|
552
|
+
return c.newResponse(res.body, res);
|
|
553
|
+
}
|
|
554
|
+
const successRes = mcpNoStore(result.data);
|
|
555
|
+
return c.newResponse(successRes.body, successRes);
|
|
556
|
+
} catch (err) {
|
|
557
|
+
const message = err instanceof Error ? err.message : "Token exchange failed";
|
|
558
|
+
const res = mcpNoStore({ error: "server_error", error_description: message }, 500);
|
|
559
|
+
return c.newResponse(res.body, res);
|
|
560
|
+
}
|
|
561
|
+
});
|
|
562
|
+
app.get("/dashboard/stats", async (c) => {
|
|
563
|
+
try {
|
|
564
|
+
const [agents, recentAudit] = await Promise.all([
|
|
565
|
+
kavach.agent.list(),
|
|
566
|
+
kavach.audit.query({
|
|
567
|
+
since: new Date(Date.now() - 24 * 60 * 60 * 1e3),
|
|
568
|
+
limit: 1e3
|
|
569
|
+
})
|
|
570
|
+
]);
|
|
571
|
+
const ownerIds = new Set(agents.map((a) => a.ownerId));
|
|
572
|
+
const activeAgents = agents.filter((a) => a.status === "active");
|
|
573
|
+
const revokedAgents = agents.filter((a) => a.status === "revoked");
|
|
574
|
+
const expiredAgents = agents.filter((a) => a.status === "expired");
|
|
575
|
+
const stats = {
|
|
576
|
+
agents: {
|
|
577
|
+
total: agents.length,
|
|
578
|
+
active: activeAgents.length,
|
|
579
|
+
revoked: revokedAgents.length,
|
|
580
|
+
expired: expiredAgents.length
|
|
581
|
+
},
|
|
582
|
+
users: {
|
|
583
|
+
total: ownerIds.size
|
|
584
|
+
},
|
|
585
|
+
audit: {
|
|
586
|
+
last24h: recentAudit.length,
|
|
587
|
+
allowed: recentAudit.filter((e) => e.result === "allowed").length,
|
|
588
|
+
denied: recentAudit.filter((e) => e.result === "denied").length,
|
|
589
|
+
rateLimited: recentAudit.filter((e) => e.result === "rate_limited").length
|
|
590
|
+
}
|
|
591
|
+
};
|
|
592
|
+
const res = ok(stats);
|
|
593
|
+
return c.newResponse(res.body, res);
|
|
594
|
+
} catch (err) {
|
|
595
|
+
const message = err instanceof Error ? err.message : "Failed to fetch dashboard stats";
|
|
596
|
+
const res = internalError(message);
|
|
597
|
+
return c.newResponse(res.body, res);
|
|
598
|
+
}
|
|
599
|
+
});
|
|
600
|
+
app.get("/dashboard/agents", async (c) => {
|
|
601
|
+
const userId = c.req.query("userId");
|
|
602
|
+
const statusRaw = c.req.query("status");
|
|
603
|
+
const typeRaw = c.req.query("type");
|
|
604
|
+
const filter = {};
|
|
605
|
+
if (userId) filter.userId = userId;
|
|
606
|
+
if (statusRaw === "active" || statusRaw === "revoked" || statusRaw === "expired") {
|
|
607
|
+
filter.status = statusRaw;
|
|
608
|
+
}
|
|
609
|
+
if (typeRaw === "autonomous" || typeRaw === "delegated" || typeRaw === "service") {
|
|
610
|
+
filter.type = typeRaw;
|
|
611
|
+
}
|
|
612
|
+
try {
|
|
613
|
+
const agents = await kavach.agent.list(filter);
|
|
614
|
+
const res = ok(agents);
|
|
615
|
+
return c.newResponse(res.body, res);
|
|
616
|
+
} catch (err) {
|
|
617
|
+
const message = err instanceof Error ? err.message : "Failed to list agents";
|
|
618
|
+
const res = internalError(message);
|
|
619
|
+
return c.newResponse(res.body, res);
|
|
620
|
+
}
|
|
621
|
+
});
|
|
622
|
+
app.get("/dashboard/audit", async (c) => {
|
|
623
|
+
const filter = {};
|
|
624
|
+
const agentId = c.req.query("agentId");
|
|
625
|
+
const userId = c.req.query("userId");
|
|
626
|
+
const since = c.req.query("since");
|
|
627
|
+
const until = c.req.query("until");
|
|
628
|
+
const actions = c.req.query("actions");
|
|
629
|
+
const resultRaw = c.req.query("result");
|
|
630
|
+
const limit = c.req.query("limit");
|
|
631
|
+
const offset = c.req.query("offset");
|
|
632
|
+
if (agentId) filter.agentId = agentId;
|
|
633
|
+
if (userId) filter.userId = userId;
|
|
634
|
+
if (since) {
|
|
635
|
+
const d = new Date(since);
|
|
636
|
+
if (!Number.isNaN(d.getTime())) filter.since = d;
|
|
637
|
+
}
|
|
638
|
+
if (until) {
|
|
639
|
+
const d = new Date(until);
|
|
640
|
+
if (!Number.isNaN(d.getTime())) filter.until = d;
|
|
641
|
+
}
|
|
642
|
+
if (actions) filter.actions = actions.split(",").map((a) => a.trim());
|
|
643
|
+
if (resultRaw === "allowed" || resultRaw === "denied" || resultRaw === "rate_limited") {
|
|
644
|
+
filter.result = resultRaw;
|
|
645
|
+
}
|
|
646
|
+
if (limit) {
|
|
647
|
+
const n = Number.parseInt(limit, 10);
|
|
648
|
+
if (!Number.isNaN(n) && n > 0) filter.limit = n;
|
|
649
|
+
}
|
|
650
|
+
if (offset) {
|
|
651
|
+
const n = Number.parseInt(offset, 10);
|
|
652
|
+
if (!Number.isNaN(n) && n >= 0) filter.offset = n;
|
|
653
|
+
}
|
|
654
|
+
try {
|
|
655
|
+
const entries = await kavach.audit.query(filter);
|
|
656
|
+
const res = ok(entries);
|
|
657
|
+
return c.newResponse(res.body, res);
|
|
658
|
+
} catch (err) {
|
|
659
|
+
const message = err instanceof Error ? err.message : "Failed to query audit logs";
|
|
660
|
+
const res = internalError(message);
|
|
661
|
+
return c.newResponse(res.body, res);
|
|
662
|
+
}
|
|
663
|
+
});
|
|
664
|
+
return app;
|
|
665
|
+
}
|
|
666
|
+
|
|
667
|
+
export { kavachHono };
|
|
668
|
+
//# sourceMappingURL=index.js.map
|
|
669
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/adapter.ts"],"names":["res","options"],"mappings":"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","file":"index.js","sourcesContent":["import { Hono } from \"hono\";\nimport type {\n\tAgentFilter,\n\tAuditFilter,\n\tCreateAgentInput,\n\tDelegateInput,\n\tKavach,\n\tPermission,\n\tUpdateAgentInput,\n} from \"kavachos\";\nimport type { McpAuthModule } from \"kavachos/mcp\";\nimport { z } from \"zod\";\n\n// ─── Zod Validation Schemas ──────────────────────────────────────────────────\n\nconst PermissionConstraintsSchema = z.object({\n\tmaxCallsPerHour: z.number().int().positive().optional(),\n\tallowedArgPatterns: z.array(z.string()).optional(),\n\trequireApproval: z.boolean().optional(),\n\ttimeWindow: z\n\t\t.object({\n\t\t\tstart: z.string(),\n\t\t\tend: z.string(),\n\t\t})\n\t\t.optional(),\n\tipAllowlist: z.array(z.string()).optional(),\n});\n\nconst PermissionSchema = z.object({\n\tresource: z.string().min(1),\n\tactions: z.array(z.string().min(1)).min(1),\n\tconstraints: PermissionConstraintsSchema.optional(),\n});\n\nconst CreateAgentSchema = z.object({\n\townerId: z.string().min(1),\n\tname: z.string().min(1),\n\ttype: z.enum([\"autonomous\", \"delegated\", \"service\"]),\n\tpermissions: z.array(PermissionSchema).min(1),\n\texpiresAt: z.coerce.date().optional(),\n\tmetadata: z.record(z.unknown()).optional(),\n});\n\nconst UpdateAgentSchema = z.object({\n\tname: z.string().min(1).optional(),\n\tpermissions: z.array(PermissionSchema).optional(),\n\texpiresAt: z.coerce.date().optional(),\n\tmetadata: z.record(z.unknown()).optional(),\n});\n\nconst AuthorizeSchema = z.object({\n\tagentId: z.string().min(1),\n\taction: z.string().min(1),\n\tresource: z.string().min(1),\n\targuments: z.record(z.unknown()).optional(),\n});\n\nconst AuthorizeByTokenSchema = z.object({\n\taction: z.string().min(1),\n\tresource: z.string().min(1),\n\targuments: z.record(z.unknown()).optional(),\n});\n\nconst DelegateSchema = z.object({\n\tfromAgent: z.string().min(1),\n\ttoAgent: z.string().min(1),\n\tpermissions: z.array(PermissionSchema).min(1),\n\texpiresAt: z.coerce.date(),\n\tmaxDepth: z.number().int().positive().optional(),\n});\n\n// ─── Response Helpers ────────────────────────────────────────────────────────\n\nfunction ok<T>(data: T, status = 200) {\n\treturn new Response(JSON.stringify({ data }), {\n\t\tstatus,\n\t\theaders: { \"Content-Type\": \"application/json\" },\n\t});\n}\n\nfunction created<T>(data: T) {\n\treturn ok(data, 201);\n}\n\nfunction errorResponse(code: string, message: string, status: number) {\n\treturn new Response(JSON.stringify({ error: { code, message } }), {\n\t\tstatus,\n\t\theaders: { \"Content-Type\": \"application/json\" },\n\t});\n}\n\nfunction badRequest(message: string) {\n\treturn errorResponse(\"BAD_REQUEST\", message, 400);\n}\n\nfunction unauthorized(message = \"Unauthorized\") {\n\treturn errorResponse(\"UNAUTHORIZED\", message, 401);\n}\n\nfunction notFound(message = \"Not found\") {\n\treturn errorResponse(\"NOT_FOUND\", message, 404);\n}\n\nfunction internalError(message = \"Internal server error\") {\n\treturn errorResponse(\"INTERNAL_ERROR\", message, 500);\n}\n\nfunction validationError(issues: z.ZodIssue[]) {\n\tconst message = issues.map((i) => `${i.path.join(\".\")}: ${i.message}`).join(\", \");\n\treturn badRequest(`Validation failed: ${message}`);\n}\n\n// ─── MCP CORS Headers ────────────────────────────────────────────────────────\n\nconst MCP_CORS_HEADERS = {\n\t\"Access-Control-Allow-Origin\": \"*\",\n\t\"Access-Control-Allow-Methods\": \"GET, POST, OPTIONS\",\n\t\"Access-Control-Allow-Headers\": \"Content-Type, Authorization\",\n\t\"Access-Control-Max-Age\": \"86400\",\n};\n\nfunction mcpOk<T>(data: T, status = 200) {\n\treturn new Response(JSON.stringify(data), {\n\t\tstatus,\n\t\theaders: { \"Content-Type\": \"application/json\", ...MCP_CORS_HEADERS },\n\t});\n}\n\nfunction mcpError(code: string, message: string, status: number) {\n\treturn new Response(JSON.stringify({ error: code, error_description: message }), {\n\t\tstatus,\n\t\theaders: { \"Content-Type\": \"application/json\", ...MCP_CORS_HEADERS },\n\t});\n}\n\nfunction mcpNoStore<T>(data: T, status = 200) {\n\treturn new Response(JSON.stringify(data), {\n\t\tstatus,\n\t\theaders: {\n\t\t\t\"Content-Type\": \"application/json\",\n\t\t\t\"Cache-Control\": \"no-store\",\n\t\t\tPragma: \"no-cache\",\n\t\t\t...MCP_CORS_HEADERS,\n\t\t},\n\t});\n}\n\n// ─── Adapter Factory ─────────────────────────────────────────────────────────\n\n/**\n * Create a Hono app with all KavachOS REST API routes mounted.\n *\n * @example\n * ```typescript\n * import { createKavach } from 'kavachos';\n * import { kavachHono } from '@kavachos/hono';\n * import { serve } from '@hono/node-server';\n *\n * const kavach = createKavach({ database: { provider: 'sqlite', url: 'kavach.db' } });\n * const app = kavachHono(kavach);\n * serve({ fetch: app.fetch, port: 3000 });\n * ```\n *\n * With MCP OAuth 2.1:\n * ```typescript\n * import { createMcpModule } from 'kavachos/mcp';\n * const mcp = createMcpModule({ ... });\n * const app = kavachHono(kavach, { mcp });\n * ```\n */\nexport function kavachHono(kavach: Kavach, options?: { mcp?: McpAuthModule }): Hono {\n\tconst app = new Hono();\n\tconst mcp = options?.mcp;\n\n\t// ── Agent REST API ──────────────────────────────────────────────\n\n\t// POST /agents - create agent\n\tapp.post(\"/agents\", async (c) => {\n\t\tlet body: unknown;\n\t\ttry {\n\t\t\tbody = await c.req.json();\n\t\t} catch {\n\t\t\tconst res = badRequest(\"Invalid JSON body\");\n\t\t\treturn c.newResponse(res.body, res);\n\t\t}\n\t\tconst parsed = CreateAgentSchema.safeParse(body);\n\t\tif (!parsed.success) {\n\t\t\tconst res = validationError(parsed.error.issues);\n\t\t\treturn c.newResponse(res.body, res);\n\t\t}\n\t\ttry {\n\t\t\tconst input: CreateAgentInput = {\n\t\t\t\t...parsed.data,\n\t\t\t\tpermissions: parsed.data.permissions as Permission[],\n\t\t\t};\n\t\t\tconst agent = await kavach.agent.create(input);\n\t\t\tconst res = created(agent);\n\t\t\treturn c.newResponse(res.body, res);\n\t\t} catch (err) {\n\t\t\tconst message = err instanceof Error ? err.message : \"Failed to create agent\";\n\t\t\tconst res = internalError(message);\n\t\t\treturn c.newResponse(res.body, res);\n\t\t}\n\t});\n\n\t// GET /agents - list agents\n\tapp.get(\"/agents\", async (c) => {\n\t\tconst userId = c.req.query(\"userId\");\n\t\tconst statusRaw = c.req.query(\"status\");\n\t\tconst typeRaw = c.req.query(\"type\");\n\n\t\tconst filter: AgentFilter = {};\n\t\tif (userId) filter.userId = userId;\n\t\tif (statusRaw === \"active\" || statusRaw === \"revoked\" || statusRaw === \"expired\") {\n\t\t\tfilter.status = statusRaw;\n\t\t}\n\t\tif (typeRaw === \"autonomous\" || typeRaw === \"delegated\" || typeRaw === \"service\") {\n\t\t\tfilter.type = typeRaw;\n\t\t}\n\n\t\ttry {\n\t\t\tconst agents = await kavach.agent.list(filter);\n\t\t\tconst res = ok(agents);\n\t\t\treturn c.newResponse(res.body, res);\n\t\t} catch (err) {\n\t\t\tconst message = err instanceof Error ? err.message : \"Failed to list agents\";\n\t\t\tconst res = internalError(message);\n\t\t\treturn c.newResponse(res.body, res);\n\t\t}\n\t});\n\n\t// GET /agents/:id - get agent\n\tapp.get(\"/agents/:id\", async (c) => {\n\t\tconst id = c.req.param(\"id\");\n\t\ttry {\n\t\t\tconst agent = await kavach.agent.get(id);\n\t\t\tif (!agent) {\n\t\t\t\tconst res = notFound(`Agent \"${id}\" not found`);\n\t\t\t\treturn c.newResponse(res.body, res);\n\t\t\t}\n\t\t\tconst res = ok(agent);\n\t\t\treturn c.newResponse(res.body, res);\n\t\t} catch (err) {\n\t\t\tconst message = err instanceof Error ? err.message : \"Failed to get agent\";\n\t\t\tconst res = internalError(message);\n\t\t\treturn c.newResponse(res.body, res);\n\t\t}\n\t});\n\n\t// PATCH /agents/:id - update agent\n\tapp.patch(\"/agents/:id\", async (c) => {\n\t\tconst id = c.req.param(\"id\");\n\t\tlet body: unknown;\n\t\ttry {\n\t\t\tbody = await c.req.json();\n\t\t} catch {\n\t\t\tconst res = badRequest(\"Invalid JSON body\");\n\t\t\treturn c.newResponse(res.body, res);\n\t\t}\n\t\tconst parsed = UpdateAgentSchema.safeParse(body);\n\t\tif (!parsed.success) {\n\t\t\tconst res = validationError(parsed.error.issues);\n\t\t\treturn c.newResponse(res.body, res);\n\t\t}\n\t\ttry {\n\t\t\tconst input: UpdateAgentInput = {\n\t\t\t\t...parsed.data,\n\t\t\t\tpermissions: parsed.data.permissions as Permission[] | undefined,\n\t\t\t};\n\t\t\tconst agent = await kavach.agent.update(id, input);\n\t\t\tconst res = ok(agent);\n\t\t\treturn c.newResponse(res.body, res);\n\t\t} catch (err) {\n\t\t\tconst message = err instanceof Error ? err.message : \"Failed to update agent\";\n\t\t\tif (message.includes(\"not found\")) {\n\t\t\t\tconst res = notFound(message);\n\t\t\t\treturn c.newResponse(res.body, res);\n\t\t\t}\n\t\t\tconst res = internalError(message);\n\t\t\treturn c.newResponse(res.body, res);\n\t\t}\n\t});\n\n\t// DELETE /agents/:id - revoke agent\n\tapp.delete(\"/agents/:id\", async (c) => {\n\t\tconst id = c.req.param(\"id\");\n\t\ttry {\n\t\t\tawait kavach.agent.revoke(id);\n\t\t\treturn new Response(null, { status: 204 });\n\t\t} catch (err) {\n\t\t\tconst message = err instanceof Error ? err.message : \"Failed to revoke agent\";\n\t\t\tif (message.includes(\"not found\")) {\n\t\t\t\tconst res = notFound(message);\n\t\t\t\treturn c.newResponse(res.body, res);\n\t\t\t}\n\t\t\tconst res = internalError(message);\n\t\t\treturn c.newResponse(res.body, res);\n\t\t}\n\t});\n\n\t// POST /agents/:id/rotate - rotate token\n\tapp.post(\"/agents/:id/rotate\", async (c) => {\n\t\tconst id = c.req.param(\"id\");\n\t\ttry {\n\t\t\tconst agent = await kavach.agent.rotate(id);\n\t\t\tconst res = ok(agent);\n\t\t\treturn c.newResponse(res.body, res);\n\t\t} catch (err) {\n\t\t\tconst message = err instanceof Error ? err.message : \"Failed to rotate agent token\";\n\t\t\tif (message.includes(\"not found\")) {\n\t\t\t\tconst res = notFound(message);\n\t\t\t\treturn c.newResponse(res.body, res);\n\t\t\t}\n\t\t\tconst res = internalError(message);\n\t\t\treturn c.newResponse(res.body, res);\n\t\t}\n\t});\n\n\t// ── Authorization ───────────────────────────────────────────────\n\n\t// POST /authorize - authorize action by agentId\n\tapp.post(\"/authorize\", async (c) => {\n\t\tlet body: unknown;\n\t\ttry {\n\t\t\tbody = await c.req.json();\n\t\t} catch {\n\t\t\tconst res = badRequest(\"Invalid JSON body\");\n\t\t\treturn c.newResponse(res.body, res);\n\t\t}\n\t\tconst parsed = AuthorizeSchema.safeParse(body);\n\t\tif (!parsed.success) {\n\t\t\tconst res = validationError(parsed.error.issues);\n\t\t\treturn c.newResponse(res.body, res);\n\t\t}\n\t\ttry {\n\t\t\tconst ip =\n\t\t\t\tc.req.header(\"x-forwarded-for\")?.split(\",\")[0]?.trim() ??\n\t\t\t\tc.req.header(\"x-real-ip\") ??\n\t\t\t\tundefined;\n\t\t\tconst userAgent = c.req.header(\"user-agent\") ?? undefined;\n\t\t\tconst result = await kavach.authorize(\n\t\t\t\tparsed.data.agentId,\n\t\t\t\t{\n\t\t\t\t\taction: parsed.data.action,\n\t\t\t\t\tresource: parsed.data.resource,\n\t\t\t\t\targuments: parsed.data.arguments,\n\t\t\t\t},\n\t\t\t\t{ ip, userAgent },\n\t\t\t);\n\t\t\tconst status = result.allowed ? 200 : 403;\n\t\t\tconst res = new Response(JSON.stringify({ data: result }), {\n\t\t\t\tstatus,\n\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t});\n\t\t\treturn c.newResponse(res.body, res);\n\t\t} catch (err) {\n\t\t\tconst message = err instanceof Error ? err.message : \"Authorization check failed\";\n\t\t\tconst res = internalError(message);\n\t\t\treturn c.newResponse(res.body, res);\n\t\t}\n\t});\n\n\t// POST /authorize/token - authorize by bearer token\n\tapp.post(\"/authorize/token\", async (c) => {\n\t\tconst authHeader = c.req.header(\"Authorization\");\n\t\tif (!authHeader?.startsWith(\"Bearer \")) {\n\t\t\tconst res = unauthorized(\"Missing or invalid Authorization header\");\n\t\t\treturn c.newResponse(res.body, res);\n\t\t}\n\t\tconst token = authHeader.slice(7);\n\n\t\tlet body: unknown;\n\t\ttry {\n\t\t\tbody = await c.req.json();\n\t\t} catch {\n\t\t\tconst res = badRequest(\"Invalid JSON body\");\n\t\t\treturn c.newResponse(res.body, res);\n\t\t}\n\t\tconst parsed = AuthorizeByTokenSchema.safeParse(body);\n\t\tif (!parsed.success) {\n\t\t\tconst res = validationError(parsed.error.issues);\n\t\t\treturn c.newResponse(res.body, res);\n\t\t}\n\t\ttry {\n\t\t\tconst ip =\n\t\t\t\tc.req.header(\"x-forwarded-for\")?.split(\",\")[0]?.trim() ??\n\t\t\t\tc.req.header(\"x-real-ip\") ??\n\t\t\t\tundefined;\n\t\t\tconst userAgent = c.req.header(\"user-agent\") ?? undefined;\n\t\t\tconst result = await kavach.authorizeByToken(\n\t\t\t\ttoken,\n\t\t\t\t{\n\t\t\t\t\taction: parsed.data.action,\n\t\t\t\t\tresource: parsed.data.resource,\n\t\t\t\t\targuments: parsed.data.arguments,\n\t\t\t\t},\n\t\t\t\t{ ip, userAgent },\n\t\t\t);\n\t\t\tconst status = result.allowed ? 200 : 403;\n\t\t\tconst res = new Response(JSON.stringify({ data: result }), {\n\t\t\t\tstatus,\n\t\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\t});\n\t\t\treturn c.newResponse(res.body, res);\n\t\t} catch (err) {\n\t\t\tconst message = err instanceof Error ? err.message : \"Authorization check failed\";\n\t\t\tconst res = internalError(message);\n\t\t\treturn c.newResponse(res.body, res);\n\t\t}\n\t});\n\n\t// ── Delegation ──────────────────────────────────────────────────\n\n\t// POST /delegations - create delegation\n\tapp.post(\"/delegations\", async (c) => {\n\t\tlet body: unknown;\n\t\ttry {\n\t\t\tbody = await c.req.json();\n\t\t} catch {\n\t\t\tconst res = badRequest(\"Invalid JSON body\");\n\t\t\treturn c.newResponse(res.body, res);\n\t\t}\n\t\tconst parsed = DelegateSchema.safeParse(body);\n\t\tif (!parsed.success) {\n\t\t\tconst res = validationError(parsed.error.issues);\n\t\t\treturn c.newResponse(res.body, res);\n\t\t}\n\t\ttry {\n\t\t\tconst input: DelegateInput = {\n\t\t\t\t...parsed.data,\n\t\t\t\tpermissions: parsed.data.permissions as Permission[],\n\t\t\t};\n\t\t\tconst chain = await kavach.delegate(input);\n\t\t\tconst res = created(chain);\n\t\t\treturn c.newResponse(res.body, res);\n\t\t} catch (err) {\n\t\t\tconst message = err instanceof Error ? err.message : \"Failed to create delegation\";\n\t\t\tif (message.includes(\"not found\")) {\n\t\t\t\tconst res = notFound(message);\n\t\t\t\treturn c.newResponse(res.body, res);\n\t\t\t}\n\t\t\tif (message.includes(\"exceeds\") || message.includes(\"depth\")) {\n\t\t\t\tconst res = badRequest(message);\n\t\t\t\treturn c.newResponse(res.body, res);\n\t\t\t}\n\t\t\tconst res = internalError(message);\n\t\t\treturn c.newResponse(res.body, res);\n\t\t}\n\t});\n\n\t// DELETE /delegations/:id - revoke delegation\n\tapp.delete(\"/delegations/:id\", async (c) => {\n\t\tconst id = c.req.param(\"id\");\n\t\ttry {\n\t\t\tawait kavach.delegation.revoke(id);\n\t\t\treturn new Response(null, { status: 204 });\n\t\t} catch (err) {\n\t\t\tconst message = err instanceof Error ? err.message : \"Failed to revoke delegation\";\n\t\t\tif (message.includes(\"not found\")) {\n\t\t\t\tconst res = notFound(message);\n\t\t\t\treturn c.newResponse(res.body, res);\n\t\t\t}\n\t\t\tconst res = internalError(message);\n\t\t\treturn c.newResponse(res.body, res);\n\t\t}\n\t});\n\n\t// GET /delegations/:agentId - list chains for agent\n\tapp.get(\"/delegations/:agentId\", async (c) => {\n\t\tconst agentId = c.req.param(\"agentId\");\n\t\ttry {\n\t\t\tconst chains = await kavach.delegation.listChains(agentId);\n\t\t\tconst res = ok(chains);\n\t\t\treturn c.newResponse(res.body, res);\n\t\t} catch (err) {\n\t\t\tconst message = err instanceof Error ? err.message : \"Failed to list delegation chains\";\n\t\t\tconst res = internalError(message);\n\t\t\treturn c.newResponse(res.body, res);\n\t\t}\n\t});\n\n\t// ── Audit ───────────────────────────────────────────────────────\n\n\t// GET /audit - query audit logs\n\tapp.get(\"/audit\", async (c) => {\n\t\tconst filter: AuditFilter = {};\n\n\t\tconst agentId = c.req.query(\"agentId\");\n\t\tconst userId = c.req.query(\"userId\");\n\t\tconst since = c.req.query(\"since\");\n\t\tconst until = c.req.query(\"until\");\n\t\tconst actions = c.req.query(\"actions\");\n\t\tconst resultRaw = c.req.query(\"result\");\n\t\tconst limit = c.req.query(\"limit\");\n\t\tconst offset = c.req.query(\"offset\");\n\n\t\tif (agentId) filter.agentId = agentId;\n\t\tif (userId) filter.userId = userId;\n\t\tif (since) {\n\t\t\tconst d = new Date(since);\n\t\t\tif (!Number.isNaN(d.getTime())) filter.since = d;\n\t\t}\n\t\tif (until) {\n\t\t\tconst d = new Date(until);\n\t\t\tif (!Number.isNaN(d.getTime())) filter.until = d;\n\t\t}\n\t\tif (actions) filter.actions = actions.split(\",\").map((a) => a.trim());\n\t\tif (resultRaw === \"allowed\" || resultRaw === \"denied\" || resultRaw === \"rate_limited\") {\n\t\t\tfilter.result = resultRaw;\n\t\t}\n\t\tif (limit) {\n\t\t\tconst n = Number.parseInt(limit, 10);\n\t\t\tif (!Number.isNaN(n) && n > 0) filter.limit = n;\n\t\t}\n\t\tif (offset) {\n\t\t\tconst n = Number.parseInt(offset, 10);\n\t\t\tif (!Number.isNaN(n) && n >= 0) filter.offset = n;\n\t\t}\n\n\t\ttry {\n\t\t\tconst entries = await kavach.audit.query(filter);\n\t\t\tconst res = ok(entries);\n\t\t\treturn c.newResponse(res.body, res);\n\t\t} catch (err) {\n\t\t\tconst message = err instanceof Error ? err.message : \"Failed to query audit logs\";\n\t\t\tconst res = internalError(message);\n\t\t\treturn c.newResponse(res.body, res);\n\t\t}\n\t});\n\n\t// GET /audit/export - export audit logs\n\tapp.get(\"/audit/export\", async (c) => {\n\t\tconst format = c.req.query(\"format\") ?? \"json\";\n\t\tif (format !== \"json\" && format !== \"csv\") {\n\t\t\tconst res = badRequest('format must be \"json\" or \"csv\"');\n\t\t\treturn c.newResponse(res.body, res);\n\t\t}\n\n\t\tconst since = c.req.query(\"since\");\n\t\tconst until = c.req.query(\"until\");\n\n\t\tconst options: { format: \"json\" | \"csv\"; since?: Date; until?: Date } = { format };\n\t\tif (since) {\n\t\t\tconst d = new Date(since);\n\t\t\tif (!Number.isNaN(d.getTime())) options.since = d;\n\t\t}\n\t\tif (until) {\n\t\t\tconst d = new Date(until);\n\t\t\tif (!Number.isNaN(d.getTime())) options.until = d;\n\t\t}\n\n\t\ttry {\n\t\t\tconst exported = await kavach.audit.export(options);\n\t\t\tconst contentType = format === \"csv\" ? \"text/csv\" : \"application/json\";\n\t\t\treturn new Response(exported, {\n\t\t\t\tstatus: 200,\n\t\t\t\theaders: {\n\t\t\t\t\t\"Content-Type\": contentType,\n\t\t\t\t\t\"Content-Disposition\": `attachment; filename=\"audit-export.${format}\"`,\n\t\t\t\t},\n\t\t\t});\n\t\t} catch (err) {\n\t\t\tconst message = err instanceof Error ? err.message : \"Failed to export audit logs\";\n\t\t\tconst res = internalError(message);\n\t\t\treturn c.newResponse(res.body, res);\n\t\t}\n\t});\n\n\t// ── MCP OAuth 2.1 Endpoints ─────────────────────────────────────\n\n\t// OPTIONS preflight for MCP routes\n\tapp.options(\"/mcp/*\", (_c) => {\n\t\treturn new Response(null, { status: 204, headers: MCP_CORS_HEADERS });\n\t});\n\n\tapp.options(\"/.well-known/*\", (_c) => {\n\t\treturn new Response(null, { status: 204, headers: MCP_CORS_HEADERS });\n\t});\n\n\t// GET /.well-known/oauth-authorization-server\n\tapp.get(\"/.well-known/oauth-authorization-server\", (c) => {\n\t\tif (!mcp) {\n\t\t\tconst res = notFound(\"MCP module not configured\");\n\t\t\treturn c.newResponse(res.body, res);\n\t\t}\n\t\tconst metadata = mcp.getMetadata();\n\t\treturn c.newResponse(mcpOk(metadata).body, mcpOk(metadata));\n\t});\n\n\t// GET /.well-known/oauth-protected-resource\n\tapp.get(\"/.well-known/oauth-protected-resource\", (c) => {\n\t\tif (!mcp) {\n\t\t\tconst res = notFound(\"MCP module not configured\");\n\t\t\treturn c.newResponse(res.body, res);\n\t\t}\n\t\tconst metadata = mcp.getProtectedResourceMetadata();\n\t\treturn c.newResponse(mcpOk(metadata).body, mcpOk(metadata));\n\t});\n\n\t// POST /mcp/register - dynamic client registration\n\tapp.post(\"/mcp/register\", async (c) => {\n\t\tif (!mcp) {\n\t\t\tconst res = notFound(\"MCP module not configured\");\n\t\t\treturn c.newResponse(res.body, res);\n\t\t}\n\t\tlet body: unknown;\n\t\ttry {\n\t\t\tbody = await c.req.json();\n\t\t} catch {\n\t\t\tconst res = mcpError(\"invalid_request\", \"Invalid JSON body\", 400);\n\t\t\treturn c.newResponse(res.body, res);\n\t\t}\n\t\ttry {\n\t\t\tconst result = await mcp.registerClient(body as Parameters<typeof mcp.registerClient>[0]);\n\t\t\tif (!result.success) {\n\t\t\t\tconst res = mcpError(\"invalid_client_metadata\", result.error.message, 400);\n\t\t\t\treturn c.newResponse(res.body, res);\n\t\t\t}\n\t\t\tconst res = mcpNoStore(result.data, 201);\n\t\t\treturn c.newResponse(res.body, res);\n\t\t} catch (err) {\n\t\t\tconst message = err instanceof Error ? err.message : \"Registration failed\";\n\t\t\tconst res = mcpError(\"server_error\", message, 500);\n\t\t\treturn c.newResponse(res.body, res);\n\t\t}\n\t});\n\n\t// GET /mcp/authorize - authorization endpoint\n\tapp.get(\"/mcp/authorize\", async (c) => {\n\t\tif (!mcp) {\n\t\t\tconst res = notFound(\"MCP module not configured\");\n\t\t\treturn c.newResponse(res.body, res);\n\t\t}\n\t\ttry {\n\t\t\tconst result = await mcp.authorize(c.req.raw);\n\t\t\tif (!result.success) {\n\t\t\t\tif (result.error.code === \"LOGIN_REQUIRED\") {\n\t\t\t\t\tconst details = result.error.details as\n\t\t\t\t\t\t| { loginPage?: string; returnTo?: string }\n\t\t\t\t\t\t| undefined;\n\t\t\t\t\tif (details?.loginPage) {\n\t\t\t\t\t\tconst loginUrl = new URL(details.loginPage);\n\t\t\t\t\t\tif (details.returnTo) {\n\t\t\t\t\t\t\tloginUrl.searchParams.set(\"returnTo\", details.returnTo);\n\t\t\t\t\t\t}\n\t\t\t\t\t\treturn c.redirect(loginUrl.toString(), 302);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst res = mcpError(result.error.code.toLowerCase(), result.error.message, 400);\n\t\t\t\treturn c.newResponse(res.body, res);\n\t\t\t}\n\t\t\treturn c.redirect(result.data.redirectUri, 302);\n\t\t} catch (err) {\n\t\t\tconst message = err instanceof Error ? err.message : \"Authorization failed\";\n\t\t\tconst res = mcpError(\"server_error\", message, 500);\n\t\t\treturn c.newResponse(res.body, res);\n\t\t}\n\t});\n\n\t// POST /mcp/token - token endpoint\n\tapp.post(\"/mcp/token\", async (c) => {\n\t\tif (!mcp) {\n\t\t\tconst res = notFound(\"MCP module not configured\");\n\t\t\treturn c.newResponse(res.body, res);\n\t\t}\n\t\ttry {\n\t\t\tconst result = await mcp.token(c.req.raw);\n\t\t\tif (!result.success) {\n\t\t\t\tconst status = result.error.code === \"INVALID_CLIENT\" ? 401 : 400;\n\t\t\t\tconst res = mcpNoStore(\n\t\t\t\t\t{\n\t\t\t\t\t\terror: result.error.code.toLowerCase(),\n\t\t\t\t\t\terror_description: result.error.message,\n\t\t\t\t\t},\n\t\t\t\t\tstatus,\n\t\t\t\t);\n\t\t\t\treturn c.newResponse(res.body, res);\n\t\t\t}\n\t\t\tconst successRes = mcpNoStore(result.data);\n\t\t\treturn c.newResponse(successRes.body, successRes);\n\t\t} catch (err) {\n\t\t\tconst message = err instanceof Error ? err.message : \"Token exchange failed\";\n\t\t\tconst res = mcpNoStore({ error: \"server_error\", error_description: message }, 500);\n\t\t\treturn c.newResponse(res.body, res);\n\t\t}\n\t});\n\n\t// ── Dashboard API ───────────────────────────────────────────────\n\n\t// GET /dashboard/stats\n\tapp.get(\"/dashboard/stats\", async (c) => {\n\t\ttry {\n\t\t\tconst [agents, recentAudit] = await Promise.all([\n\t\t\t\tkavach.agent.list(),\n\t\t\t\tkavach.audit.query({\n\t\t\t\t\tsince: new Date(Date.now() - 24 * 60 * 60 * 1000),\n\t\t\t\t\tlimit: 1000,\n\t\t\t\t}),\n\t\t\t]);\n\n\t\t\tconst ownerIds = new Set(agents.map((a) => a.ownerId));\n\t\t\tconst activeAgents = agents.filter((a) => a.status === \"active\");\n\t\t\tconst revokedAgents = agents.filter((a) => a.status === \"revoked\");\n\t\t\tconst expiredAgents = agents.filter((a) => a.status === \"expired\");\n\n\t\t\tconst stats = {\n\t\t\t\tagents: {\n\t\t\t\t\ttotal: agents.length,\n\t\t\t\t\tactive: activeAgents.length,\n\t\t\t\t\trevoked: revokedAgents.length,\n\t\t\t\t\texpired: expiredAgents.length,\n\t\t\t\t},\n\t\t\t\tusers: {\n\t\t\t\t\ttotal: ownerIds.size,\n\t\t\t\t},\n\t\t\t\taudit: {\n\t\t\t\t\tlast24h: recentAudit.length,\n\t\t\t\t\tallowed: recentAudit.filter((e) => e.result === \"allowed\").length,\n\t\t\t\t\tdenied: recentAudit.filter((e) => e.result === \"denied\").length,\n\t\t\t\t\trateLimited: recentAudit.filter((e) => e.result === \"rate_limited\").length,\n\t\t\t\t},\n\t\t\t};\n\t\t\tconst res = ok(stats);\n\t\t\treturn c.newResponse(res.body, res);\n\t\t} catch (err) {\n\t\t\tconst message = err instanceof Error ? err.message : \"Failed to fetch dashboard stats\";\n\t\t\tconst res = internalError(message);\n\t\t\treturn c.newResponse(res.body, res);\n\t\t}\n\t});\n\n\t// GET /dashboard/agents - agents with stats\n\tapp.get(\"/dashboard/agents\", async (c) => {\n\t\tconst userId = c.req.query(\"userId\");\n\t\tconst statusRaw = c.req.query(\"status\");\n\t\tconst typeRaw = c.req.query(\"type\");\n\n\t\tconst filter: AgentFilter = {};\n\t\tif (userId) filter.userId = userId;\n\t\tif (statusRaw === \"active\" || statusRaw === \"revoked\" || statusRaw === \"expired\") {\n\t\t\tfilter.status = statusRaw;\n\t\t}\n\t\tif (typeRaw === \"autonomous\" || typeRaw === \"delegated\" || typeRaw === \"service\") {\n\t\t\tfilter.type = typeRaw;\n\t\t}\n\n\t\ttry {\n\t\t\tconst agents = await kavach.agent.list(filter);\n\t\t\tconst res = ok(agents);\n\t\t\treturn c.newResponse(res.body, res);\n\t\t} catch (err) {\n\t\t\tconst message = err instanceof Error ? err.message : \"Failed to list agents\";\n\t\t\tconst res = internalError(message);\n\t\t\treturn c.newResponse(res.body, res);\n\t\t}\n\t});\n\n\t// GET /dashboard/audit - same as GET /audit\n\tapp.get(\"/dashboard/audit\", async (c) => {\n\t\tconst filter: AuditFilter = {};\n\n\t\tconst agentId = c.req.query(\"agentId\");\n\t\tconst userId = c.req.query(\"userId\");\n\t\tconst since = c.req.query(\"since\");\n\t\tconst until = c.req.query(\"until\");\n\t\tconst actions = c.req.query(\"actions\");\n\t\tconst resultRaw = c.req.query(\"result\");\n\t\tconst limit = c.req.query(\"limit\");\n\t\tconst offset = c.req.query(\"offset\");\n\n\t\tif (agentId) filter.agentId = agentId;\n\t\tif (userId) filter.userId = userId;\n\t\tif (since) {\n\t\t\tconst d = new Date(since);\n\t\t\tif (!Number.isNaN(d.getTime())) filter.since = d;\n\t\t}\n\t\tif (until) {\n\t\t\tconst d = new Date(until);\n\t\t\tif (!Number.isNaN(d.getTime())) filter.until = d;\n\t\t}\n\t\tif (actions) filter.actions = actions.split(\",\").map((a) => a.trim());\n\t\tif (resultRaw === \"allowed\" || resultRaw === \"denied\" || resultRaw === \"rate_limited\") {\n\t\t\tfilter.result = resultRaw;\n\t\t}\n\t\tif (limit) {\n\t\t\tconst n = Number.parseInt(limit, 10);\n\t\t\tif (!Number.isNaN(n) && n > 0) filter.limit = n;\n\t\t}\n\t\tif (offset) {\n\t\t\tconst n = Number.parseInt(offset, 10);\n\t\t\tif (!Number.isNaN(n) && n >= 0) filter.offset = n;\n\t\t}\n\n\t\ttry {\n\t\t\tconst entries = await kavach.audit.query(filter);\n\t\t\tconst res = ok(entries);\n\t\t\treturn c.newResponse(res.body, res);\n\t\t} catch (err) {\n\t\t\tconst message = err instanceof Error ? err.message : \"Failed to query audit logs\";\n\t\t\tconst res = internalError(message);\n\t\t\treturn c.newResponse(res.body, res);\n\t\t}\n\t});\n\n\treturn app;\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@kavachos/hono",
|
|
3
|
+
"version": "0.0.2",
|
|
4
|
+
"description": "Hono adapter for KavachOS - exposes agent auth as HTTP REST endpoints",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "dist/index.js",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.js"
|
|
12
|
+
}
|
|
13
|
+
},
|
|
14
|
+
"files": [
|
|
15
|
+
"dist"
|
|
16
|
+
],
|
|
17
|
+
"keywords": [
|
|
18
|
+
"kavachos",
|
|
19
|
+
"hono",
|
|
20
|
+
"auth",
|
|
21
|
+
"agent",
|
|
22
|
+
"mcp"
|
|
23
|
+
],
|
|
24
|
+
"author": "KavachOS <hello@kavachos.com>",
|
|
25
|
+
"license": "MIT",
|
|
26
|
+
"repository": {
|
|
27
|
+
"type": "git",
|
|
28
|
+
"url": "https://github.com/kavachos/kavachos.git",
|
|
29
|
+
"directory": "packages/adapters/hono"
|
|
30
|
+
},
|
|
31
|
+
"peerDependencies": {
|
|
32
|
+
"hono": ">=4.0.0",
|
|
33
|
+
"zod": ">=3.0.0",
|
|
34
|
+
"kavachos": "0.0.2"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@types/better-sqlite3": "^7.6.13",
|
|
38
|
+
"better-sqlite3": "^11.0.0",
|
|
39
|
+
"hono": "^4.7.0",
|
|
40
|
+
"tsup": "^8.4.0",
|
|
41
|
+
"typescript": "^5.8.0",
|
|
42
|
+
"vitest": "^3.0.0",
|
|
43
|
+
"zod": "^3.24.0",
|
|
44
|
+
"kavachos": "0.0.2"
|
|
45
|
+
},
|
|
46
|
+
"scripts": {
|
|
47
|
+
"build": "tsup",
|
|
48
|
+
"typecheck": "tsc --noEmit",
|
|
49
|
+
"test": "vitest run",
|
|
50
|
+
"test:watch": "vitest watch"
|
|
51
|
+
}
|
|
52
|
+
}
|