Agent 安全盲区在于工具名在白名单但入参可携带跨租户 secrets 或攻击者指令,提出在每个敏感 sink 处追踪数据流标签并强制预算的方案。
工具许可列表只回答一个问题:Agent 可以调用哪些函数?
它没有回答更难的问题:哪些信息可以流入这些调用,结果又可以去往何处?
这个差距在 Agent 读取工单、网页、邮件、仓库或 MCP 响应,然后用这些内容构造请求时尤为重要。工具本身可能已获批准,但参数中却可能包含密钥、攻击者控制的指令,或者来自当前运行实例根本不该访问的租户的数据。
实用的修复方案是:在整个运行过程中追踪数据流标签,并在每个敏感接收端执行预算控制。
模型不是策略边界
将模型输出和工具结果视为数据,而不是授权依据。策略层应该在检查以下内容后再决定是否允许某个拟议调用:
这类似于网络出口策略。服务可能允许发起 HTTPS 请求,但不允许将数据库导出发送到任意主机。Agent 可能允许调用浏览器工具,但不允许将不受信任的页面加上 API 密钥一起复制到表单提交中。
使用描述来源而非意图的标签
从一个小型词汇表开始。保持足够通用,让每个适配器都能一致地应用它。
type DataLabel =
| "PUBLIC"
| "USER_INPUT"
| "UNTRUSTED_EXTERNAL"
| "TENANT_PRIVATE"
| "SECRET"
| "DERIVED";
一个值可以携带多个标签。例如,从私有文档生成的摘要仍然是租户私有的,即使模型生成了该摘要。从网页复制过来的值仍然是不可信的外部内容,即使模型称其为指令。
不要让模型分配或移除标签。适配器应在入口处为值打标签:
UNTRUSTED_EXTERNAL 开始TENANT_PRIVATE 和租户 IDSECRET,通常应该是不可导出的USER_INPUT,即使它看起来像系统指令定义接收端,而不仅仅是工具
单个工具可能暴露多个风险各不相同的接收端。在策略中要将它们分开。
这里可能涉及到托管决策,但它本身并非安全控制。对于常驻的 OpenClaw 或浏览器工作流,在 Ampere 上托管的 OpenClaw 托管可以是需要评估的运行时选项之一。数据流策略、凭证范围和审批检查仍然属于应用程序层面。
让预算变得明确
预算限制了在一次运行中可以通过接收端的敏感数据量。可以按记录数、字节数、字段数或批准的目标来计数。
type FlowBudget = {
runId: string;
tenantId: string;
remainingPrivateFields: number;
allowedExternalHosts: Set;
deniedLabels: Set;
policyVersion: number;
};
function authorizeSink(input: {
sink: string;
host?: string;
labels: Set;
privateFieldCount: number;
budget: FlowBudget;
}) {
const { sink, host, labels, privateFieldCount, budget } = input;
for (const label of labels) {
if (budget.deniedLabels.has(label)) {
return { allowed: false, reason: `label_denied:${label}` };
}
}
if (host && !budget.allowedExternalHosts.has(host)) {
return { allowed: false, reason: "host_not_allowlisted" };
}
if (privateFieldCount > budget.remainingPrivateFields) {
return { allowed: false, reason: "private_field_budget_exceeded" };
}
return { allowed: true, reason: "policy_match" };
}
检查必须在分发的立即前执行,而不仅仅在模型提议调用时。在提议和分发之间,审批可能过期、租户可能变更,或者另一个 worker 可能消耗了剩余预算。
与操作记录一起原子性地预留预算。如果提供方结果在超时后未知,不要自动用新的预留重试。通过提供方请求 ID 或幂等键对第一次尝试进行协调,然后决定是否安全进行另一次传输。
用敌意 fixture 测试边界
有用的测试套件不仅仅问正常提示是否成功。它在每个入口注入数据,并尝试将其移动到每个接收端。
记录决策、策略版本、标签、接收端、目标、预算前后变化以及稳定的操作 ID。从证据链中删除值的具体内容。审计记录应该证明为什么允许某个调用,而不会成为另一条外泄通道。
小型上线清单
在真实数据上启用 Agent 前:
UNKNOWN 结果告警工具许可列表仍然有用。它只是外围栅栏。防止看似无害的已批准工具成为外泄通道的控制,是在接收端执行的数据流契约。