ai-agent-guardrails 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/README.md ADDED
@@ -0,0 +1,155 @@
1
+ # ai-agent-guardrails
2
+
3
+ [![npm version](https://img.shields.io/npm/v/ai-agent-guardrails.svg)](https://www.npmjs.com/package/ai-agent-guardrails)
4
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
+
6
+ Security middleware for AI SDK that adds production-grade controls to agent tool calling.
7
+
8
+ ## Features
9
+
10
+ - Policy Enforcement: Allowlists, denylists, and risk-based tool classification
11
+ - Human Approval Gates: Require user confirmation for high-risk operations
12
+ - Budget Controls: Max tool calls, time limits, per-tool timeouts
13
+ - Audit Logging: Structured events compatible with OpenTelemetry
14
+ - Secret Redaction: Automatic PII/secret removal from logs
15
+ - MCP Integration: Works with Model Context Protocol tools
16
+
17
+ ## Installation
18
+
19
+ ```bash
20
+ npm install ai-agent-guardrails ai zod
21
+ # or
22
+ pnpm add ai-agent-guardrails ai zod
23
+ ```
24
+
25
+ ## Quick Start
26
+
27
+ ```typescript
28
+ import { streamText } from 'ai';
29
+ import { openai } from '@ai-sdk/openai';
30
+ import { guardTools, createSimplePolicy, ConsoleAuditSink } from 'ai-agent-guardrails';
31
+
32
+ // Define policy
33
+ const policy = createSimplePolicy({
34
+ denylist: ['delete_database'], // Block dangerous tools
35
+ requireApprovalForRisk: ['write', 'admin'], // Require approval for these
36
+ });
37
+
38
+ // Wrap tools with guardrails
39
+ const tools = guardTools(myTools, {
40
+ policy,
41
+ audit: new ConsoleAuditSink(),
42
+ timeoutMs: 10_000,
43
+ });
44
+
45
+ // Use in AI SDK
46
+ const result = streamText({
47
+ model: openai('gpt-4o-mini'),
48
+ messages,
49
+ tools, // ← Guarded tools
50
+ });
51
+ ```
52
+
53
+ ## With MCP Tools
54
+
55
+ ```typescript
56
+ import { createMCPClient } from '@ai-sdk/mcp';
57
+ import { guardTools, createSimplePolicy } from 'ai-agent-guardrails';
58
+
59
+ // Connect to MCP server
60
+ const mcp = await createMCPClient({ transport: ... });
61
+ const mcpTools = await mcp.tools();
62
+
63
+ // Apply guardrails
64
+ const policy = createSimplePolicy({
65
+ requireApprovalForRisk: ['write', 'admin'],
66
+ });
67
+
68
+ const tools = guardTools(mcpTools, { policy });
69
+ ```
70
+
71
+ ## Approval Flow (React)
72
+
73
+ ```tsx
74
+ 'use client';
75
+
76
+ import { useChat } from '@ai-sdk/react';
77
+
78
+ export default function Chat() {
79
+ const { messages, addToolApprovalResponse } = useChat();
80
+
81
+ return (
82
+ <>
83
+ {messages.map(m =>
84
+ m.parts?.map(part => {
85
+ if (part.state === 'approval-requested') {
86
+ return (
87
+ <div>
88
+ <p>Tool requires approval: {part.type}</p>
89
+ <button onClick={() => addToolApprovalResponse({ id: part.approval.id, approved: true })}>
90
+ Approve
91
+ </button>
92
+ <button onClick={() => addToolApprovalResponse({ id: part.approval.id, approved: false })}>
93
+ Deny
94
+ </button>
95
+ </div>
96
+ );
97
+ }
98
+ })
99
+ )}
100
+ </>
101
+ );
102
+ }
103
+ ```
104
+
105
+ ## Budget Controls
106
+
107
+ ```typescript
108
+ import { createDefaultContext } from 'ai-agent-guardrails';
109
+
110
+ const ctx = createDefaultContext();
111
+ ctx.maxToolCalls = 5; // Limit to 5 tool calls
112
+ ctx.maxDurationMs = 30_000; // 30 second timeout
113
+
114
+ const tools = guardTools(myTools, { policy, ctx });
115
+ ```
116
+
117
+ ## Audit Logging
118
+
119
+ ```typescript
120
+ import { InMemoryAuditSink, ConsoleAuditSink, FileAuditSink } from 'ai-agent-guardrails';
121
+
122
+ // Console (dev)
123
+ const audit = new ConsoleAuditSink();
124
+
125
+ // Memory (testing)
126
+ const audit = new InMemoryAuditSink();
127
+ const events = audit.getEvents();
128
+
129
+ // File (production)
130
+ const audit = new FileAuditSink('./audit.jsonl');
131
+ ```
132
+
133
+ ## Redaction
134
+
135
+ ```typescript
136
+ import { createDefaultRedactor, createFieldRedactor } from 'ai-agent-guardrails';
137
+
138
+ // Automatic pattern-based redaction
139
+ const redactor = createDefaultRedactor();
140
+
141
+ // Field-based redaction
142
+ const redactor = createFieldRedactor(['password', 'apiKey', 'secret']);
143
+
144
+ const tools = guardTools(myTools, { policy, redactor });
145
+ ```
146
+
147
+ ## Documentation
148
+
149
+ - [Full Documentation](https://github.com/yourusername/agent-guardrails-mcp)
150
+ - [Threat Model](https://github.com/yourusername/agent-guardrails-mcp/blob/main/docs/THREAT_MODEL.md)
151
+ - [Demo App](https://agent-guardrails-demo.vercel.app)
152
+
153
+ ## License
154
+
155
+ MIT © Krish Gupta
@@ -0,0 +1,246 @@
1
+ /**
2
+ * Risk classification for tools
3
+ */
4
+ type Risk = 'read' | 'write' | 'admin';
5
+ /**
6
+ * Decision outcome from policy evaluation
7
+ */
8
+ type GuardDecision = {
9
+ allow: true;
10
+ } | {
11
+ allow: false;
12
+ reason: string;
13
+ } | {
14
+ allow: true;
15
+ needsApproval: true;
16
+ reason: string;
17
+ };
18
+ /**
19
+ * Context passed through guard execution
20
+ */
21
+ type GuardContext = {
22
+ requestId: string;
23
+ toolCalls: number;
24
+ maxToolCalls: number;
25
+ startTime: number;
26
+ maxDurationMs?: number;
27
+ };
28
+ /**
29
+ * Tool-like interface that matches AI SDK tool structure
30
+ */
31
+ type ToolLike = {
32
+ description?: string;
33
+ inputSchema?: unknown;
34
+ parameters?: unknown;
35
+ needsApproval?: boolean | ((input: any) => boolean | Promise<boolean>);
36
+ execute?: (input: any) => Promise<any>;
37
+ };
38
+ /**
39
+ * Policy interface for classification and decision making
40
+ */
41
+ type GuardPolicy = {
42
+ /**
43
+ * Classify a tool call by risk level
44
+ */
45
+ classify: (toolName: string, input: unknown) => Promise<{
46
+ risk: Risk;
47
+ reason?: string;
48
+ }> | {
49
+ risk: Risk;
50
+ reason?: string;
51
+ };
52
+ /**
53
+ * Decide whether to allow, block, or require approval
54
+ */
55
+ decide: (args: {
56
+ toolName: string;
57
+ input: unknown;
58
+ ctx: GuardContext;
59
+ risk: Risk;
60
+ reason?: string;
61
+ }) => Promise<GuardDecision> | GuardDecision;
62
+ };
63
+ /**
64
+ * Audit event types
65
+ */
66
+ type AuditEvent = {
67
+ type: 'tool_call_attempted';
68
+ toolName: string;
69
+ input: unknown;
70
+ requestId: string;
71
+ timestamp: number;
72
+ } | {
73
+ type: 'tool_call_blocked';
74
+ toolName: string;
75
+ reason: string;
76
+ requestId: string;
77
+ timestamp: number;
78
+ } | {
79
+ type: 'tool_call_needs_approval';
80
+ toolName: string;
81
+ reason: string;
82
+ requestId: string;
83
+ timestamp: number;
84
+ } | {
85
+ type: 'tool_call_executed';
86
+ toolName: string;
87
+ durationMs: number;
88
+ requestId: string;
89
+ timestamp: number;
90
+ } | {
91
+ type: 'tool_call_timeout';
92
+ toolName: string;
93
+ timeoutMs: number;
94
+ requestId: string;
95
+ timestamp: number;
96
+ } | {
97
+ type: 'budget_exceeded';
98
+ reason: string;
99
+ requestId: string;
100
+ timestamp: number;
101
+ };
102
+ /**
103
+ * Audit sink interface for logging events
104
+ */
105
+ type AuditSink = {
106
+ emit: (event: AuditEvent) => void | Promise<void>;
107
+ };
108
+ /**
109
+ * Options for guardTools wrapper
110
+ */
111
+ type GuardToolsOptions = {
112
+ policy: GuardPolicy;
113
+ ctx?: GuardContext;
114
+ audit?: AuditSink;
115
+ timeoutMs?: number;
116
+ redactor?: Redactor;
117
+ };
118
+ /**
119
+ * Redactor interface for PII/secret removal
120
+ */
121
+ type Redactor = {
122
+ redact: (value: unknown) => unknown;
123
+ };
124
+
125
+ /**
126
+ * Wrap a toolset with guardrails enforcement
127
+ *
128
+ * This is the main entry point for the guardrails package. It wraps AI SDK tools
129
+ * with policy enforcement, budget checks, timeouts, and audit logging.
130
+ *
131
+ * @example
132
+ * ```ts
133
+ * const tools = guardTools(mcpTools, {
134
+ * policy: createSimplePolicy({ requireApprovalForRisk: ['write', 'admin'] }),
135
+ * audit: new ConsoleAuditSink(),
136
+ * timeoutMs: 10_000,
137
+ * });
138
+ * ```
139
+ */
140
+ declare function guardTools<T extends Record<string, ToolLike>>(tools: T, opts: GuardToolsOptions): T;
141
+
142
+ /**
143
+ * Create a default guard context with budget limits
144
+ */
145
+ declare function createDefaultContext(requestId?: string): GuardContext;
146
+ /**
147
+ * Wrap a promise with a timeout
148
+ */
149
+ declare function withTimeout<T>(promise: Promise<T>, ms: number): Promise<T>;
150
+
151
+ /**
152
+ * Create a simple policy with allowlist/denylist
153
+ */
154
+ declare function createSimplePolicy(options: {
155
+ allowlist?: string[];
156
+ denylist?: string[];
157
+ requireApprovalForRisk?: Risk[];
158
+ }): GuardPolicy;
159
+ /**
160
+ * Create a composable policy builder
161
+ */
162
+ declare class PolicyBuilder {
163
+ private classifiers;
164
+ private rules;
165
+ /**
166
+ * Add a classifier function
167
+ */
168
+ addClassifier(classifier: (toolName: string, input: unknown) => {
169
+ risk: Risk;
170
+ reason?: string;
171
+ } | null): this;
172
+ /**
173
+ * Add a decision rule
174
+ */
175
+ addRule(rule: (args: {
176
+ toolName: string;
177
+ input: unknown;
178
+ ctx: GuardContext;
179
+ risk: Risk;
180
+ reason?: string;
181
+ }) => GuardDecision | null): this;
182
+ /**
183
+ * Build the final policy
184
+ */
185
+ build(): GuardPolicy;
186
+ }
187
+
188
+ /**
189
+ * In-memory audit sink that stores events in an array
190
+ */
191
+ declare class InMemoryAuditSink implements AuditSink {
192
+ private events;
193
+ emit(event: AuditEvent): void;
194
+ /**
195
+ * Get all stored events
196
+ */
197
+ getEvents(): ReadonlyArray<AuditEvent>;
198
+ /**
199
+ * Clear all stored events
200
+ */
201
+ clear(): void;
202
+ /**
203
+ * Get events for a specific request
204
+ */
205
+ getEventsForRequest(requestId: string): AuditEvent[];
206
+ }
207
+ /**
208
+ * Console audit sink that logs events to console
209
+ */
210
+ declare class ConsoleAuditSink implements AuditSink {
211
+ private prefix;
212
+ constructor(prefix?: string);
213
+ emit(event: AuditEvent): void;
214
+ }
215
+ /**
216
+ * File audit sink that writes events to a JSONL file
217
+ * Note: This is for Node.js environments only
218
+ */
219
+ declare class FileAuditSink implements AuditSink {
220
+ private writeStream;
221
+ constructor(filePath: string);
222
+ emit(event: AuditEvent): void;
223
+ /**
224
+ * Close the file stream
225
+ */
226
+ close(): void;
227
+ }
228
+
229
+ /**
230
+ * Create a regex-based redactor
231
+ */
232
+ declare function createRegexRedactor(patterns: RegExp[], replacement?: string): Redactor;
233
+ /**
234
+ * Create a default redactor with common secret and PII patterns
235
+ */
236
+ declare function createDefaultRedactor(): Redactor;
237
+ /**
238
+ * Field-based redactor that redacts specific fields
239
+ */
240
+ declare function createFieldRedactor(fieldsToRedact: string[], replacement?: string): Redactor;
241
+ /**
242
+ * Composite redactor that chains multiple redactors
243
+ */
244
+ declare function composeRedactors(...redactors: Redactor[]): Redactor;
245
+
246
+ export { type AuditEvent, type AuditSink, ConsoleAuditSink, FileAuditSink, type GuardContext, type GuardDecision, type GuardPolicy, type GuardToolsOptions, InMemoryAuditSink, PolicyBuilder, type Redactor, type Risk, type ToolLike, composeRedactors, createDefaultContext, createDefaultRedactor, createFieldRedactor, createRegexRedactor, createSimplePolicy, guardTools, withTimeout };