MukundaKatta/agentguard

GitHub: MukundaKatta/agentguard

专为 AI 智能体设计的轻量级网络出站防火墙,通过声明式域名白名单和请求预算限制拦截非授权外联,防止提示注入等攻击导致的数据泄露。

Stars: 0 | Forks: 0

# agentguard [![npm 版本](https://img.shields.io/npm/v/@mukundakatta/agentguard.svg)](https://www.npmjs.com/package/@mukundakatta/agentguard) [![npm 下载量](https://img.shields.io/npm/dm/@mukundakatta/agentguard.svg)](https://www.npmjs.com/package/@mukundakatta/agentguard) [![许可证: MIT](https://img.shields.io/badge/license-MIT-blue.svg)](./LICENSE) [![Node](https://img.shields.io/node/v/@mukundakatta/agentguard.svg)](https://nodejs.org) [![测试](https://img.shields.io/badge/tests-47%2F47-brightgreen.svg)](./test) **AI 智能体的网络出站防火墙。** 通过声明式域名允许列表控制智能体工具可获取的资源;对其他任何请求则抛出异常(或返回 403)。零运行时依赖。可直接嵌入任何调用 `fetch()` 的代码,包括您无法控制的 SDK 客户端。 ``` npm install @mukundakatta/agentguard ``` ``` import { firewall, policy, PolicyViolation } from '@mukundakatta/agentguard'; const safe = policy({ network: { allow: ['api.openai.com', 'api.anthropic.com', '*.example.com'], methods: ['GET', 'POST'], }, budget: { maxRequests: 50 }, violations: 'throw', }); await firewall(safe, async () => { await myAgent.run('summarize today\'s news'); // any fetch outside the allowlist throws }); ``` 如果工具调用(或模型驱动的 SDK 请求)试图访问不在列表中的主机,将抛出 `PolicyViolation` 并附带 `reason`、`detail`、`url` 和 `method`。您可以捕获它、记录它、给自己发送告警,或者转交给人工审批。无论您的安全模型是什么,这都为您提供了介入的空间。 TypeScript 类型随包一起提供。 ### 查看实际运行效果 ``` git clone https://github.com/MukundaKatta/agentguard && cd agentguard node examples/demo-block.js ``` 三种场景——正常通过、拦截提示注入驱动的数据泄露抛出异常,以及相同场景在 `block` 模式下(返回 403 而不是抛出异常)。 ## 为什么需要 当您赋予 LLM 使用 `fetch` 的工具访问权限(或任何底层使用 fetch 的 SDK)时,您是在信任模型不会去调用您不希望访问的主机。在以下情况中,这种信任会被打破: - **提示注入**诱使模型获取攻击者控制的 URL(通过 URL 参数、DNS 查询等进行数据泄露)。 - **模型升级**悄然改变了智能体决定调用的 API。 - 工具或 SDK 的**依赖更新**悄悄添加了新的端点(遥测、备用主机)。 - **CI 测试运行**因为有人忘记 mock 而意外访问了生产环境的 API。 `agentguard` 默认将智能体驱动的 HTTP 请求视为不受信任,并为您提供只需一行代码即可配置允许访问的规则。 ## API ### `policy(spec) → Policy` 验证并冻结策略声明。如果规范格式错误,则抛出 `TypeError`。 ``` const p = policy({ network: { allow: ['api.openai.com'], deny: ['*.internal.corp'], methods: ['GET', 'POST'], }, budget: { maxRequests: 100 }, violations: 'throw', }); ``` 主机模式: - 精确匹配主机:`'api.openai.com'` - 通配符子域:`'*.example.com'`(匹配 `example.com` 及其任何子域) - 全局通配符:`'*'`(在 `deny` 中用作全捕获规则非常有用) 拒绝规则优先于允许规则。 ### `firewall(spec, fn) → Promise` 通过包装 `globalThis.fetch` 来强制执行策略并运行 `fn`。退出时(包括发生异常时)会自动恢复原状。并发的 `firewall()` 调用各自拥有独立的 AsyncLocalStorage 帧,互不冲突。 ``` await firewall(p, async () => { await myAgent.run('do task'); // any fetch inside is policy-checked }); ``` ### `wrapFetch(spec) → fetch` 获取一个应用了策略的 fetch 函数,而无需对全局对象进行猴子补丁。当您可以将 `fetch` 直接传递给 SDK 时,请使用此方法: ``` import Anthropic from '@anthropic-ai/sdk'; import { wrapFetch, policy } from '@mukundakatta/agentguard'; const client = new Anthropic({ fetch: wrapFetch(policy({ network: { allow: ['api.anthropic.com'] } })), }); ``` 每次 `wrapFetch()` 调用都会返回一个带有独立内部请求计数器的新 fetch 函数;预算限制是针对每个 fetch 实例的。 ### `check(policy, url, init?) → Decision` 纯粹的决策函数。无副作用。如果您想在 fetch 以外的传输层(例如 HTTP/2 客户端)强制执行策略,或者独立测试策略,请使用此函数。 ``` const decision = check(p, 'https://evil.com', { method: 'GET' }); // { action: 'deny', reason: 'not_in_allowlist', detail: 'evil.com' } ``` ### `PolicyViolation` 当请求被拒绝时(默认行为),由 `firewall()` 抛出。可通过编程方式捕获: ``` try { await firewall(p, fn); } catch (err) { if (err instanceof PolicyViolation) { console.error(err.reason, err.url, err.detail); } } ``` 稳定的 `reason` 代码: - `not_in_allowlist` — 主机未匹配到任何 `allow` 模式 - `denylist_match` — 主机匹配到了 `deny` 模式 - `method_blocked` — HTTP 方法不在 `network.methods` 中 - `budget_exceeded` — 超过了 `budget.maxRequests` 预算限制 - `invalid_url` — 无法解析 URL ## 配置方案 ### 不得访问生产环境的 CI 智能体 ``` const ciPolicy = policy({ network: { allow: ['localhost', '127.0.0.1', '*.test.invalid'], deny: ['*'], }, }); await firewall(ciPolicy, () => runMyAgentTests()); ``` ### 生产环境中限制严格的智能体:仅允许访问其已知的 LLM 提供商 ``` const prodPolicy = policy({ network: { allow: ['api.anthropic.com'] }, budget: { maxRequests: 200 }, }); await firewall(prodPolicy, () => myAgent.handle(userRequest)); ``` ### 需要访问整个网络但不能访问内部网络的智能体 ``` const webPolicy = policy({ network: { deny: ['*.internal.corp', '169.254.169.254', 'localhost', '127.0.0.1'], // no allow → everything else is permitted }, }); await firewall(webPolicy, () => researchAgent.run(query)); ``` (`169.254.169.254` 是 EC2/GCP/Azure 元数据服务——一个经典的 SSRF 目标。) ### `block` 模式:返回 403 而不是抛出异常 ``` const blockingPolicy = policy({ network: { allow: ['api.openai.com'] }, violations: 'block', }); await firewall(blockingPolicy, async () => { // blocked requests now return a synthetic 403 Response with // `x-agentguard-block: 1` headers. Useful when you want the agent to // see the rejection and recover, rather than crashing. }); ``` ## CLI `@mukundakatta/agentguard` 附带了一个 `agentguard` 二进制文件,用于一次性 URL 检查和 CI 期间的策略验证: ``` # 在部署前验证 policy 文件 npx -p @mukundakatta/agentguard agentguard validate-policy --policy policy.json # 根据 policy 检查单个 URL(如果被阻止则退出码为 1) npx -p @mukundakatta/agentguard agentguard check https://api.openai.com/v1/chat \ --policy policy.json --method POST # 从文件(或通过 `-` 从 stdin)批量检查 URL;如果任一被拒绝则退出码为 1 cat candidate-urls.txt | npx -p @mukundakatta/agentguard agentguard check-batch - \ --policy policy.json ``` 标准输出上每次检查输出一个 JSON 对象(使用 `--pretty` 可进行缩进格式化)。允许/有效时退出代码为 `0`,拒绝/无效时为 `1`,使用错误时为 `2`。运行 `agentguard --help` 获取完整的子命令参考。 ## 本项目不是 - **不是沙箱。** 坚决的恶意代码可以通过猴子补丁绕过 `fetch` 本身,或使用其他传输方式(`net.connect`、`dgram`、原生 HTTP/2)。如需实现硬隔离,请使用操作系统级别的网络命名空间、Linux `iptables`、k8s `NetworkPolicy` 或 Firecracker microVM(e2b 等)。 - **不是身份验证。** 它按主机进行拦截,而不是按用户。请与 API 层的适当身份验证结合使用。 - **不是面面俱到。** v0.1 仅覆盖基于 fetch 的出站流量。文件和 Shell 出站不在此范围内(这需要对 `node:fs` 和 `node:child_process` 进行猴子补丁,这种侵入性足以破坏其他库的假设)。 正确定位是:`agentguard` 是*工具使用的安全带*。它能捕获意外情况和大多数机会主义攻击。请将其与沙箱、机密管理和身份验证结合使用,以实现深度防御。 ## 相关库 智能体可靠性技术栈的一部分——全部位于 `@mukundakatta/*` 作用域下,全部零依赖: - [`@mukundakatta/agentfit`](https://www.npmjs.com/package/@mukundakatta/agentfit) — 按预算适配消息。*适配它。* - [`@mukundakatta/agentsnap`](https://www.npmjs.com/package/@mukundakatta/agentsnap) — 工具调用轨迹的快照测试。*测试它。* - **`@mukundakatta/agentguard`** — 网络出站防火墙。*沙箱化。*(本库) - [`@mukundakatta/agentvet`](https://www.npmjs.com/package/@mukundakatta/agentvet) — 工具参数验证器。*审查它。* - [`@mukundakatta/agentcast`](https://www.npmjs.com/package/@mukundakatta/agentcast) — 结构化输出强制器。*验证它。* 自然流程:**fit → guard → snap → vet → cast**。 ## 状态 v0.1.2 — 安全修复版本。核心 API 稳定。包含 TypeScript 类型。通过 47/47 项测试,支持 Node 20/22/24 上的 CI。 **v0.2 计划**(基于真实世界反馈后): - 按工具限制速率(例如 "search_web: 10/min") - 成本跟踪集成(根据请求量估算 $/run) - fetch 以外的可插拔传输层(OpenAI streaming,MCP stdio) - 审计日志钩子(每次允许/拒绝 → 发送到您选择的目标)
标签:AI Agent安全, API网关安全, Fetch拦截, GNU通用公共许可证, IP 地址批量处理, Lerna, LLM工具调用安全, MITM代理, Node.js, NPM包, OSV-Scalibr, TypeScript, 出站防火墙, 域名白名单, 声明式策略, 安全插件, 提示注入防护, 暗色界面, 模型越狱防护, 策略执行, 网络安全, 网络数据泄露防护, 网络访问控制, 自定义脚本, 隐私保护, 零依赖