问题:无护栏的智能体
许多工程团队正在尝试超越传统的脚本和管道进行自动化。一些组织开始将操作任务委托给自主或半自主智能体,而不是人类通过仪表板点击或手动批准更改,这种做法通常被称为“点击操作”。这些智能体可能会生成基础设施变更、触发部署或响应操作信号,几乎不需要或根本不需要人为干预。与传统的 CI/CD 机器人不同,它们执行预定义的管道,具有静态权限和确定性输入,智能体驱动的系统在运行时引入了动态决策和跨系统操作。
这种转变引入了一类新的风险。与传统自动化不同,传统自动化通常限于单一工具或工作流程,AI 驱动的智能体通常跨多个系统操作:CI/CD 平台、云 API、基础设施即代码工具和内部服务。当这些智能体被赋予广泛或持久的权限时,它们实际上继承了与高度特权的人类操作员相同的访问级别,但却没有相同的上下文判断或问责机制。
例如,在多区域部署中,一个备用区域可能不会主动为流量提供服务,但对于故障转移至关重要。响应成本优化或修复信号的智能体可能会将流量不足误解为未使用的容量,并修改或终止备用区域中的资源,当稍后的流量从主区域故障转移时,由于没有明确的批准轨迹或人为决策点来追究责任,从而造成严重影响。
在这个领域失败的后果是显而易见的。智能体对指令的错误解释可能会启动具有破坏性的基础设施更改,例如破坏环境或修改生产资源。被泄露的智能体身份可能被滥用以窃取机密、创建未经授权的工作负载或大规模消耗资源。在实践中,团队通常很晚才发现这些问题,因为传统的日志记录了发生了什么,但没有记录智能体决定首先采取行动的原因。
对于组织来说,这种责任带来了操作和治理方面的挑战。事件变得更难调查,变更批准被无意地绕过,安全团队留下了不完整的审计跟踪。随着时间的推移,这个问题会侵蚀对自动化本身的信任,迫使团队要么回滚智能体的使用,要么接受不断增加的未管理风险。
一种方法是完全限制或阻止智能体驱动的操作,但这种操作破坏了智能体要提供的价值。一种更可持续的方法是在智能体和它们所操作的系统之间引入一个显式的控制层。在本文中,我们重点讨论 AI 智能体网关,这是一个专用的边界,它验证意图,将策略作为代码强制执行,并在任何基础设施或服务 API 被调用之前隔离执行。
该模型没有将智能体视为有特权的参与者,而是将其视为不可信的请求者,其行为必须被授权、约束、观察和包含。
设计原则
在深入研究单个原则之前,它有助于在结构层面上建立什么是 AI 智能体网关,借鉴已建立的生产安全和平台模式,而不是特定于 AI 的理论。
在核心层面,网关充当自主智能体和基础设施系统之间的控制边界。智能体从不直接与基础架构 API 交互。相反,每个请求都要通过一个集中式网关,该网关验证意图,强制执行授权规则,并将执行委托给隔离的、短暂的环境。这种分离允许组织引入人工智能驱动的自动化,而无需让智能体持续或无限制地访问关键系统。
图 1 提供了此架构的宏观层次视图,并显示了来自 AI 智能体的请求如何通过策略评估、受控执行和可观测性流。与简单的 API 包装器或代理不同,网关不直接转发智能体请求。它将意图验证、策略决策和执行外部化到单独的组件中,防止智能体持有凭据或调用基础设施 api 本身。
图 1:AI 智能体网关的宏观架构(Debnath,2026)
有了这种结构,网关架构遵循以下设计原则:
策略作为代码将授权逻辑外部化为声明性策略(OPA),避免在应用程序代码中硬编码访问规则。
最小权限防止智能体直接与基础设施 API 通信。网关调解每个请求,并将执行限制在所需的最低权限。
短暂的执行迫使操作在短暂的、隔离的环境中运行,这些环境在执行后立即被销毁。
默认的可观测性跟踪每个请求和执行,产生跟踪、指标和审计日志,并启用检查和事后分析。
版本控制和可审计性通过使用计划哈希、幂等键和不可变作业元数据来跟踪请求,确保可重复性和可追溯性。
本地优先,云就绪在本地运行相同的架构进行实验和测试,同时保持可移植到生产环境。
参考架构
网关架构遵循深度防御模型,这是基础设施和云系统中一个确立已久的安全原则。深度防御不是依赖单一控制来防止滥用,而是应用多个独立的安全措施,以便一个层次的失败不会导致整个系统的妥协。这种方法通常用于零信任网络、云 IAM 设计和生产级 CI/CD 管道。在智能体驱动的系统中,依赖单一控制(如提示约束或静态工具允许列表)是不够的,因为智能体在运行时做出决策,并且可能以无法完全预测或由单一安全措施限制的方式跨多个工具和系统行动。
在 AI 驱动自动化的背景下,深度防御意味着没有任何单一组件(无论是智能体、网关还是执行环境)本身拥有足够的权限来造成损害。每一层执行一个狭窄、明确定义的角色,并且每一层之间的过渡都要经过验证。
这个原则反映在架构如何有意地将请求操作的人与执行操作的地方分开。AI 智能体被视为不受信任的请求者。它们可以发现能力和提交结构化请求,但它们从不直接与基础设施 API 交互。所有执行都发生在一个严格的网关后面,该网关执行验证、授权和隔离。
系统的流程故意设计成单向的,强制执行不变性,即没有事先授权和隔离执行,任何执行都不会发生:
发现:智能体使用模型上下文协议(MCP)发现哪些工具可用以及它们需要什么输入。
请求:智能体使用 JSON-RPC 调用调用工具(例如,apply_infra)。
验证:网关验证请求模式,计算计划哈希,用身份和上下文丰富请求,并将其发送到 OPA 进行授权。
决策:如果 OPA 拒绝请求,网关返回 403 响应,执行停止。如果获得批准,请求被转换为作业并放入执行队列。
执行:一个短暂的运行器拉取作业,创建一个隔离的命名空间,应用基础设施计划,并在完成后删除环境。
可观测性:在每个阶段都会发出度量和跟踪,允许仪表板实时跟踪策略决策、执行延迟和故障模式。
这种分离确保即使智能体由于提示错误、配置错误或妥协而表现出意外,爆炸半径也会受到限制。授权决策是在执行之前做出的,执行是在隔离的环境中进行的,并且每一步都是可观测和可审计的。
在图 2 中,我们可以看到 AI 智能体网关执行的完整的请求到执行工作流程。图表显示了智能体请求是如何被验证、授权、排队、在隔离环境中执行和完全观测的,当策略拒绝操作时有明确的停止点。
图 2:AI 智能体网关的端到端请求和执行工作流程(Debnath,2026)
关于这个参考实现
本文介绍的一个参考实现,旨在说明 AI 驱动自动化的治理边界,而不是提出一个生产硬化的安全平台。
附带的存储库有意地将架构的清晰性置于完整性之上。它展示了意图、授权和执行如何通过网关模式分离和执行,同时保持实现最小化和本地可运行。
因此,本文中讨论的一些控制被显示为架构模式而不是完全强制的保证。例如,Kubernetes 命名空间为临时执行提供逻辑隔离,但尚未通过作用域服务账户、网络策略或工作负载身份强制执行最少权限访问。同样,计划完整性在策略层使用哈希进行验证,但这些哈希没有与运行器执行的签名工件进行加密绑定。可观测性是根据基于 OpenTelemetry 的跟踪和度量来描述的,但参考代码说明了仪器属于哪里,而不是连接一个完整的遥测管道。
项目蓝图
AI 智能体网关被设计为范围狭窄的组件的组合,而不是单一的、单体的服务。每个组件处理不同的职责:请求中介、授权或执行,以便智能体行为可以独立于基础设施执行细节而进行治理、审计和演化。这种分离是有意的,反映了最小化爆炸半径的核心设计目标,同时保持系统的可理解性和可测试性。
本节概述 AI 智能体网关是如何由一组专注的小组件构建的,每个组件负责单一的关注点。目标是通过设计使系统可理解、可审计和可演进,而不是将策略、执行和编排逻辑嵌入到单个服务中。
在高层次上,架构分为三个部分,每个部分都通过定义良好的契约进行通信,以支持可替换性和可测试性:
网关(API 层)接受智能体请求、验证意图、强制授权决策并协调执行。
策略层使用策略作为代码封装所有授权和安全规则。
执行层在隔离的、生存期短的环境中执行经过批准的操作。
这种分离允许每个层独立演进。策略可以在不重新部署网关的情况下进行更改,执行环境可以在不涉及授权逻辑的情况下进行加固,智能体可以在不影响基础设施控制的情况下进行替换或升级。
下面的小节将详细介绍每个组件,从请求处理开始,然后是策略实施,最后是隔离执行。
组件的概述
项目布局明确地反映了这种分离。存储库不是按语言或部署单元对文件进行分组,而是按职责组织的。这种结构针对架构清晰度进行了优化,而不是针对语言或框架特定的约定:
agent-gateway/ ├── mcp/ # 组件1:TypeScript网关服务 │ └── server.ts # - 处理JSON-RPC和OPA检查 ├── policies/ # 组件2:OPA策略引擎 │ └── agent_authz.rego # - 定义“谁能做什么” ├── runner/ # 组件3:临时运行器 │ └── runner.py # - Python脚本在Kind中执行Terraform ├── infra/ # 示例基础设施(OpenTofu计划) └── docker-compose.yml # 编排这里使用 Terraform/OpenTofu 作为一个具体的执行示例,但相同的执行模式适用于其他后端,如云 CLI、部署工具或内部自动化脚本。
此构建的先决条件包括 Docker、Kind(Kubernetes v1.26+)、Node.js v20+、Python 3.11+和 OPA CLI。
参考实现
本文的完整、可运行的参考实现作为 GitHub 上的开源项目提供,旨在作为描述的架构模式的参考和演示,而不是作为生产硬基准。仓库包含 MCP 网关、OPA 策略、临时运行器和基于 Docker 的本地设置,允许读者复现本文中描述的示例和实验。
网关(MCP 层)
我们从构建系统的协调层开始,而不是决策组件。我们特别选择了模型上下文协议(MCP),因为它将智能体从工具定义中解耦出来。这个决定允许我们在不重写我们的治理层的情况下交换 LLM 或智能体框架,这是避免供应商锁定的关键要求。
我们在 mcp/server.ts 文件中实现了网关逻辑,以处理两个关键任务:发现和执行。
首先,我们定义了 apply_infra 工具结构,以便智能体理解所需的输入(计划、路径、哈希和环境),将智能体行为限制为明确声明的能力,并防止其发明或调用未声明的操作:
// mcp/server.ts - 工具定义 if (method === "tools/list") { return res.json(rpcResult(id, { tools: [ { name: "apply_infra", description: "在沙箱中应用OpenTofu/Terraform计划", inputSchema: ApplyInfraParams.shape } ] }));}接下来,当工具被调用时,我们依赖 Zod 进行严格的模式验证。然后我们将上下文传递给 OPA。注意,我们这里不执行基础设施变更;我们只是将其排队。
// mcp/server.ts - 工具执行if (method === "tools/call") { const { name, arguments: args } = params; // 1. 验证模式 const parsed = ApplyInfraParams.safeParse(args); if (!parsed.success) return res.json(rpcError(id, -32602, "Invalid params")); // 2. 通过OPA授权 const decision = await authorize({ action: name, actor, // 从JWT/mTLS提取 plan: { path: args.planPath, hash: args.planHash, env: args.env }, time: new Date().toISOString() }); if (!decision) return res.json(rpcError(id, 403, "Policy denied")); // 3. 排队作业(异步) const job = await enqueueApply({ ...args, actor: actor.id }, args.idempotencyKey); return res.json(rpcResult(id, { accepted: true, jobId: job.id }));}策略即代码
我们将授权逻辑从 TypeScript 代码中移出,进入 Open Policy Agent(OPA)。这个决定允许我们在不重新部署网关的情况下执行复杂的业务规则。
对于策略引擎,我们定义了 policies/agent_authz.rego 以执行四个不可协商的规则:
RBAC (sre-bot 具有完全访问权限;deploy-bot 仅限于非 prod)。
完整性(计划散列必须匹配已注册的工件)。
安全(计划以毁灭告终。计划明显受阻)。
变更管理(部署只允许在周一到周五,09:00-17:00 UTC)。
# policies/agent_authz.regopackage agent.authzdefault allow = falseallow { input.action == "apply_infra" allow_actor[input.actor.id][input.plan.env] # RBAC plan_is_registered[input.plan.hash] # 完整性 not is_destroy_plan(input.plan.path) # 安全 in_change_window(time.parse_rfc3339_ns(input.time)) # 变更窗口}# 角色定义allow_actor := { "sre-bot": {"dev":true, "staging":true, "prod":true}, "deploy-bot": {"dev":true, "staging":true}}is_destroy_plan(path) { endswith(path, "-destroy.plan")}# 周一至周五 9am-5pmin_change_window(t) { ns := time.parse_rfc3339_ns(input.time) day := time.weekday([ns, "Local"]) is_weekday(day) clock := time.clock([ns, "America/New_York"]) hour := clock[0] hour >= 9 hour < 17}is_weekday(day) { weekdays := {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday"} weekdays[day]}临时运行器
运行器是系统的“手”。我们使用 Python 来管理生命周期。它确保在执行前后环境是干净的。
运行器,用 Python 实现( runner/runner.py ),遵循严格的工作流程:
生成一个唯一的命名空间(run-uuid)。
使用 kubectl 和 tofu 执行计划。
即使作业失败,也总是删除命名空间。
# runner/runner.pydef main(): job = json.loads(sys.stdin.read()) namespace = f"run-{uuid.uuid4().hex[:8]}" with tracer.start_as_current_span("apply_infra_execution") as span: try: # 1. 创建沙箱 subprocess.run(["kubectl", "create", "ns", namespace], check=True) # 2. 执行基础设施即代码 subprocess.run(["tofu", "apply", "-chdir=infra", "-auto-approve"], check=True) span.set_status(trace.Status(trace.StatusCode.OK)) finally: # 3. 强制清理 subprocess.run(["kubectl", "delete", "ns", namespace, "--wait"], check=False)这个工作流程保证了我们永远不会在集群中留下“孤儿”资源在运行。
执行和结果
构建好组件后,我们现在可以组装系统了。
引导集群
初始化一个本地 Kind 集群作为我们的“云”。
make bootstrap # 用于:kind create cluster播种数据
将样本 Terraform 计划推送到 infra/ 目录,并计算它们的 SHA-256 哈希值以在 OPA 中注册它们。
测试快乐路径
模拟一个有效的智能体请求。你应该看到网关接受 JSON-RPC 调用,几秒钟内,一个新的命名空间将出现在你的 Kind 集群中并消失。
# 预期:{"accepted": true, "jobId": "..".}curl -X POST http://localhost:8080/rpc ...测试护栏
尝试修改请求以使用未经授权的智能体或破坏性计划( infra/app-destroy.plan )。网关应该立即返回 403 Forbidden 错误,证明 OPA 在请求到达运行器之前拦截了请求。
我们必须预测这个系统如何崩溃。架构考虑了这些特定的风险:
扩展到企业
到目前为止描述的架构是故意最小化的,适合本地实验和受控环境。然而,随着团队从个人工作流程转向全组织采用,系统的许多方面需要发展,同时保持相同的控制平面语义。这些变化不是关于增加复杂性,而是关于满足在规模上出现的运维、安全和合规约束。
第一个压力点是执行隔离。Kubernetes 命名空间为本地测试和早期原型提供了合理的沙箱,但在受监管或多租户环境中往往不够。随着采用的增长,团队通常将临时运行器移动到更强的隔离边界,例如轻量级虚拟机(例如 Firecracker 或 Kata Containers)或专用的短暂 Kubernetes 集群。这种转变允许组织在不改变智能体或策略定义的情况下,实施更严格的租户分离并满足审计要求。
另一个扩展问题是工件信任。在早期阶段,在策略内部验证计划哈希通常足以防止意外漂移。在企业规模上,这种方法并不适用。计划必须是可追踪、可验证和可归因的。许多团队通过引入由内部工件注册或工具(如 Sigstore)支持的签名计划目录来解决这个问题。这使得策略层不仅可以验证计划的完整性,还可以验证谁在何时产生了计划,从而将执行变成可验证的监管链,而不是竭尽全力的保障。
随着变化的影响增加,完全自动化的执行很少是可接受的。高风险操作,如生产变更或破坏性操作通常需要明确的人类批准。与其将审批逻辑嵌入智能体或运行器中,不如将网关作为协调点。当需要批准时,网关返回一个待定状态,并指示智能体在通过 Slack 或 Jira 等外部系统发出签名批准令牌后重试。这使得人类决策保持可见和可审计,同时不削弱自动化边界。
最后,地理成为治理问题。在多区域环境中,执行必须靠近被管理的基础设施,而控制逻辑保持集中。智能体不应决定工作运行的位置。相反,临时运行器在区域部署,政策决定允许执行的位置。这一政策决策防止智能体跨越监管或数据居住边界,同时保持单一、一致的控制平面。
这些变化共同保留了网关的核心设计原则,同时允许它在现实世界的企业约束下运行。系统通过收紧执行边界和明确信任来扩展,而不是赋予智能体更多权力。
运维 SLOs
性能在智能体治理中并非次要问题。如果授权或执行变得缓慢或不可预测,团队将绕过系统。
以下服务水平目标(SLOs)旨在保护开发者信任和运维安全:
政策决策延迟(<100 毫秒):授权必须足够快,以对智能体不可见。慢速政策检查会导致重试、超时或直接通过网关访问 API。
运行器启动延迟(<2 秒开发/<5 秒暂存): 如果启动成本保持低,临时执行才是可行的。更长的启动时间通常意味着运行器设置有问题,无论是镜像太重、集群过载还是隔离规则减慢了速度。
拒绝操作(≤2%):高拒绝率通常表明工具设计不佳或政策过于粗略。这个指标帮助团队在智能体被重新训练以绕过控制之前识别摩擦。
沙箱拆除时间(<30 秒):清理延迟直接影响爆炸半径。长期存在的沙箱增加成本,泄露凭证,并使事件响应复杂化。
审计日志可用性(<5 分钟): 如果证据在事后到达,治理就无效。在事件期间必须可以查询审计数据。
这些 SLOs 通过警报强制执行。当它们降级时,自动化需要暂停。
结论
在本地构建和练习这个系统,有意识地触发政策违规、执行失败和清理边缘情况,很快就清楚了一件事:智能体安全不是通过文档或模型调整来改造的。只有当护栏作为系统本身的一部分执行时,它才有效。
最有效的控制是将治理放在执行路径之外。在自动化实验期间,静态指南、访问审查和最佳实践文件很容易被绕过。相比之下,由网关强制执行并在每个请求上评估的控制始终有效,因为智能体从未直接与基础设施 API 交互。将治理视为系统边界而不是事后的想法,改变了自动化可以安全发展的方式。
将意图与执行分开也证明是关键。让智能体描述他们想要做什么,而运行器控制它如何发生,简化了安全性和调试。政策违规、无效请求和执行失败作为不同的信号出现,而不是纠缠在一起。这种分离使得在不破坏工作流的情况下收紧政策成为可能,并且在不触及授权逻辑的情况下加强执行。
即使在本地设置中,可观测性也扮演了同样重要的角色。捕获政策决策、执行步骤和沙箱清理的跟踪和日志使智能体行为可检查而不是假设。我们不是相信智能体“做了正确的事情”,而是可以验证发生了什么,何时发生,以及为什么允许或拒绝决策。
最后,临时执行从根本上改变了风险实验的感觉。知道每个操作都在短暂的环境中运行,并且必须拆除,使得测试破坏性场景变得安全,而不会留下残留状态。这种方法降低了失败的成本,并鼓励了更严格的政策,因为错误被设计为包含。
综合来看,这些教训指向了一个更广泛的结论:AI 驱动的自动化的安全性通过更明确的、可执行的边界而不是更智能的模型来提高。通过解耦意图(智能体)、授权(政策作为代码)和执行(临时运行器),最小权限 AI 智能体网关将抽象的 AI 风险转化为具体的工程约束。在这个模型中,对智能体的信任不是一种信念,而是你可以观察、测量和强制的东西。
原文链接:
https://www.infoq.com/articles/building-ai-agent-gateway-mcp/





