由 AgentPolicy (LX AI)

允许的工具与开放式代理

开放式代理的吸引力是真实的:给它一个 shell、一个浏览器和一个邮箱,它就可以解决你没有预先编写脚本的问题。然而,其代价是影响范围。每添加一个工具,就会增加一个注入指令可以传播的路径。设计问题不在于是否授予能力,而在于如何狭义地授予能力,以便错误的步骤仍然可以被控制。

最小权限工具定义

我首先编写一个工具合同,明确规定代理可以执行什么操作和不能执行什么操作。一个“读取票据”工具应该只暴露一个GET操作,用于获取特定的票据标识符,不允许修改票据、附加文件或调用其他端点。一个“发送电子邮件”工具应该只接受预定义的收件人列表、固定的主题行模板和经过新行注入清理的正文。通过缩小合同范围,模型输出中的单个错误变成了一个有界事件,而不是一个连锁反应。

定义动词集

列出工具需要的每个HTTP方法、数据库命令或文件操作。如果工具只需要读取,省略POST、PUT、DELETE和任何管理命令。我保持一个电子表格,映射每个工具名称到允许的动词,并在添加新端点时进行审查。

约束参数

对于每个参数,我指定类型、长度限制和允许的字符集。票据ID可能是一个UUID,限制为36个字符。文件路径可能被限制在/ var / agent / data子目录下,不得包含“..”或绝对路径。我使用一个模式验证库,在工具运行之前拒绝任何不符合的请求。

版本化合同

我将工具定义存储为版本控制中的JSON文件。任何更改都会触发一个需要安全审查人员签署的拉取请求。这创建了一个审计跟踪,显示权限表面何时扩展以及原因。

要了解提示注入如何滥用过于宽泛的工具,请查看OWASP LLM01指南:https://genai.owasp.org/llmrisk/llm01-prompt-injection。抄袭表显示了具体示例,其中模型被欺骗以调用shell命令,因为工具接受不受限制的输入。

工具名称 | 允许的动词 | 参数约束 | 示例安全调用 read_ticket | GET | ticket_id:UUID,36个字符 | /tickets/123e4567-e89b-12d3-a456-426614174000 send_email | POST | to:来自approved_domains的列表,subject:最大78个字符,body:清理 | {"to":["user@example.com"],"subject":"更新","body":"请查看附加的报告。"} list_files | GET | path:必须以 /var/agent/data/ 开头,无“..” | /var/agent/data/logs/2024-09-01.txt

不可逆操作的确认

改变代理沙盒外部状态的操作,例如发送消息、删除记录或部署构建,必须由代理无法自行调用的一步单独批准来控制。我将这些视为单向门,并设计策略以要求在工具执行之前需要人工令牌或短期批准服务。

单独的批准端点

我公开了一个内部API,接受来自代理的签名请求,记录请求,然后等待人在UI中单击“批准”或响应聊天命令。代理只接收到待处理的标识符;它无法轮询批准端点以强制授予。

时间限制令牌

当批准被授予时,系统发出一个仅有效一次且在五分钟后过期的令牌。工具端点在继续之前检查令牌的签名和过期时间。如果令牌丢失或过期,工具返回错误并记录尝试。

记录门

每个批准请求和决定都写入带有时间戳、代理标识符、工具名称和呈现的参数的不可变日志。该日志允许我重现是否有毒指令能够绕过门或在批准步骤中停止。

有关在自动化管道中保护凭证卫生的指导,请参阅OWASP CI/CD安全风险表:https://owasp.org/www-project-top-10-ci-cd-security-risks/CICD-SEC-06-Insufficient-Credential-Hygiene。它强调了永远不应将机密存储在代理可以在没有明确批准流的情况下读取的地方的原则。

审计日志作为控制,而不是事后思考

我将审计日志视为政策执行的主要证据。如果没有可靠的日志,关于最小权限的声明就不能被验证。我设计日志层从代理的角度来看是只写的,并存储在代理无法修改或删除的系统中。

要记录的内容

- 带有毫秒精度的时间戳 - 代理标识符(模型版本、部署 ID) - 工具名称和调用的确切动词 - 验证后传递给工具的所有参数 - 结果状态代码和任何返回的数据摘要(大小,而不是完整内容) - 请求来源(用户启动、计划触发器或策略引擎)

存储保证

我将每个日志条目写入一个追加仅存储区,例如启用对象版本控制的云存储桶中的预写日志。桶策略拒绝代理服务帐户的任何删除或覆盖操作。这确保即使模型被泄露,历史记录仍保持完整。

查询调查

当报告事件时,我针对日志索引运行一个简单的类似 SQL 的查询,以在时间窗口内找到特定工具的所有运行。我避免可能很慢的复杂联结;相反,我依赖按日期和工具名称划分的表。查询返回我然后用于更深入的法医分析的标识符列表。

要了解输入验证如何防止恶意参数达到工具,请参阅 SQL 注入防御备忘录:https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html。该备忘录显示了参数化查询和严格类型,这与我为代理工具使用的参数验证方法相似。

何时开放访问是合理的

存在一些合理的案例,代理需要更广泛的访问权限,例如在隔离环境中进行探索性数据分析或威胁狩猎。在这些情况下,我仅在将代理放在阻止任何路径到生产数据或外部支付系统的沙盒中后才授予开放访问权限。

沙盒边界

沙盒提供一个shell、浏览器引擎和只能向专用测试域发送消息的邮件客户端。网络策略阻止所有出站流量到公司内部CIDR范围内的任何IP地址。仅允许向一组批准的公共镜像进行包安装的出站流量。

凭证隔离

不将生产密钥挂载到沙盒文件系统中。相反,代理接收一个临时令牌,该令牌可以从公共数据集存储桶中读取。如果代理尝试在允许的挂载点之外读取文件,内核将返回权限错误并记录尝试。

时间限制会话

每个沙盒会话最长持续两个小时。超时后,环境将被拆除,新镜像将被启动。这限制了误behaving代理可以探索或泄露数据的时间窗口。

我仍然在沙盒内应用最小权限工具定义;区别在于,错误的后果仅限于可丢弃的环境,而不是生产系统。

将生成的策略视为草稿

当一个模型或一名初级工程师生成一个策略文件时,我会像审查即将部署到关键服务的不受信任的代码一样审查它。审查清单包括验证每个规则与实际工具定义、确认拒绝路径的存在以及确保文件已版本化。

规则到工具映射

我创建一个电子表格,一个轴上列出每个工具,另一个轴上列出每个策略规则。对于每个单元格,我标记规则是否允许、拒绝或对工具的操作保持沉默。任何沉默的单元格都会触发一个评论,要求作者澄清意图。

默认拒绝检查

我运行一个静态分析脚本,尝试以一组格式错误的参数调用每个工具。如果脚本找到一个组合,该策略允许但应该被拒绝(例如,接受通配符标识符的“删除”工具),则脚本会使构建失败,策略必须被修订。

版本控制和审查

策略文件位于一个具有分支保护的Git存储库中,需要两个批准才能合并。我为每个发布版本标记一个语义版本号(例如v1.2.0),并附上相应的工具定义快照。这使得如果新版本引入过度宽松的规则,可以回滚到已知的良好状态。

我从不认为生成的策略是最终的,直到它通过了这个审查周期。一个从不被审查的策略会产生虚假的安全感,并可能隐藏只有在现实世界负载下才会出现的差距。

什么这不是

本指南并不承诺按照这些步骤就能消除每一种可能的故障模式。我并不声称可以100%地防止提示注入、凭证泄露或逻辑错误。我也不声称代理永远不会错过恶意指令;检测取决于日志的质量、人工审查的及时性以及工具合同的正确性。将这些模式视为风险减少措施,而不是绝对安全的保证。

相关文章

- 通过 NIST AI RMF 视角的 AI 代理策略包 - 探索完整的 AI 微 SaaS 主题矩阵 →

Is an open-ended agent always a bad idea?

No. Broad reach is justified for research or triage inside a sandbox with no production credentials and no external egress. The rule is to earn openness with isolation rather than grant it by default.

What is the single most important tool control?

Confirmation on irreversible actions such as send, delete, transfer, and deploy. A gate the agent cannot trigger itself breaks the chain from a poisoned instruction to an external effect.

Why are audit logs part of the policy?

Logs prove which tools ran and with what arguments. Without them, least-privilege is a claim you cannot verify, and an incident becomes impossible to reconstruct.

Should I trust a generated policy pack as written?

Treat it as a draft. Verify each rule against the real tool definitions, confirm the deny paths exist, and version the result. A policy never read is worse than none, because it implies coverage that is not there.

仅供决策参考,不构成法律建议或合规证书。

← 返回博客

这次结果有帮助吗?反馈