别把“不让 Agent 读文件”当成权限系统

很多 Agent 项目的第一版安全设计只有一张排除表:

yaml 复制代码
exclude:
  - finance/**
  - secrets/**
  - customers/raw/**

然后开发者会自然地得出一个结论:这些目录模型看不到,所以 Agent 是安全的。

问题在于,Agent 不只通过"把文件塞进 prompt"获取信息。它还可能调用搜索、浏览器、数据库、索引和发布工具;它读取的也不只原始文件,还有摘要、类型信息、缓存和派生产物。

GitHub 9 月 2 日宣布 Copilot app 与 CLI 正式支持管理员配置的内容排除策略。官方文档也很坦诚地列出边界:部分编辑器的 Edit/Agent 模式暂不支持;IDE 可能间接提供类型、符号定义和构建配置;符号链接和远程文件系统也有当前限制。

这不是在挑 Copilot 的毛病。恰恰相反,它把一个容易被忽略的事实摆到了台面上:context exclusion 是过滤器,不是完整的 authorization system。

一个反例:文件没读,秘密还是出去了

假设运营 Agent 不允许读取 finance/budget.xlsx,但可以:

  • 查询一个已经索引了预算表的知识库;
  • 读取昨天由财务 Agent 生成的摘要;
  • 打开项目看板里的预算卡片;
  • 把当前上下文发布到公开博客。

排除规则可以百分之百命中,事故仍然会发生。因为策略只拦了原始路径,没有管数据的派生关系和输出通道。

把它抽象成一条数据流会更清楚:

text 复制代码
source file
   ├─> embedding index
   ├─> generated summary
   ├─> task log
   └─> dashboard card
              └─> public publisher

如果安全标签只挂在 source file 上,任何一次转换都可能把标签洗掉。

权限请求至少要有五个维度

路径匹配器通常只接收一个字符串。真正的 Agent 权限请求应至少包含:

typescript 复制代码
type AgentAccess = {
  principal: string;      // 谁在工作
  taskId: string;         // 为哪次任务工作
  resource: ResourceRef;  // 要访问什么
  action: Action;         // 要做什么
  channel?: Channel;      // 结果要去哪里
};

例如同一份品牌资料:

  • 研究 Agent 可以 read
  • 写作 Agent 可以读取并生成内部草稿;
  • 发布 Agent 只能读取已审批版本;
  • 任何 Agent 都不能把客户原始名单写入公开平台。

权限边界因此可以写成五层:

需要回答的问题
Identity Agent 以哪个岗位、哪个委托人的身份运行?
Resource 原始数据和派生数据是否允许访问?
Action read、write、delete、publish 是否分别授权?
Channel 结果能否流向当前平台、Webhook 或公开页面?
Evidence 能否还原实际读取、调用和提交结果?

deny list 不够,默认值应该是 deny

仅靠黑名单的问题不是规则写少了,而是未知对象默认放行。

更稳妥的策略顺序是:

typescript 复制代码
function authorize(req: AgentAccess, p: Policy): Decision {
  if (!p.identities.includes(req.principal)) return DENY;
  if (p.resources.deny.some(x => x.matches(req.resource))) return DENY;
  if (!p.resources.allow.some(x => x.matches(req.resource))) return DENY;
  if (!p.actions.allow.includes(req.action)) return DENY;
  if (req.channel && !p.channels.allow.includes(req.channel)) return DENY;
  if (p.actions.requireApproval.includes(req.action)) return REQUIRE_APPROVAL;
  return ALLOW;
}

实际工程里还要处理优先级、继承和策略版本,但有两个原则不要变:

  1. 没匹配到 allow 时是拒绝,不是放行;
  2. "可读"不会隐式推出"可发布"。

派生产物要继承来源标签

当 Agent 生成摘要、截图或中间文件时,给产物保存 provenance:

json 复制代码
{
  "id": "artifact:campaign-summary",
  "derivedFrom": [
    "workspace://finance/budget.xlsx",
    "workspace://marketing/plan.md"
  ],
  "classification": "CONFIDENTIAL",
  "allowedActions": ["read", "summarize"],
  "allowedChannels": ["internal_report"]
}

最保守的合并规则是:产物继承所有来源中最高的敏感等级,除非经过一个有记录、可复核的降级流程。

这会增加元数据维护成本,但它直接堵住了"原文件禁止访问,摘要却可以随便外发"的洞。

高风险动作不要发长期钥匙

Agent 如果只负责预填文章,就不应该长期持有最终发布能力。可以在页面检查通过后签发一次性 capability:

typescript 复制代码
type Capability = {
  principal: "agent:publisher";
  action: "platform.publish";
  subject: "draft:42@sha256:7af1...";
  destination: "csdn";
  expiresAt: string;
  maxUses: 1;
};

标题、正文、目标账号或可见范围改变后,旧 capability 立即失效。执行器还要用幂等键和页面回读避免"不知道是否成功时再点一次"。

权限控制因此不是 UI 上多一个确认框,而是执行器在最后一刻重新证明:主体、对象版本、动作和通道仍与授权一致。

一组比单元测试更有用的越权用例

正向测试只能证明允许路径可用。权限系统更需要负向测试:

yaml 复制代码
cases:
  - name: denied source through search index
    expect: DENY
  - name: confidential summary to public publisher
    expect: DENY
  - name: symlink points outside workspace
    expect: DENY
  - name: publish capability expired
    expect: DENY
  - name: draft hash changed after approval
    expect: REQUIRE_APPROVAL
  - name: audit sink unavailable during publish
    expect: DENY

每次替换模型、升级 IDE、增加 MCP 或新增数据源后,都应该重新跑这些用例。因为权限边界不是只由模型决定的,工具和运行环境同样会改变可达路径。

我们做 Tipkay 时的一个取舍

Tipkay 是面向小微企业、一人公司和小团队的按需 AI 员工平台。这也是我们做产品时很在意的一个边界:平台登录态保留在本地,私有扩展留在本机,减少凭据在外部系统之间搬运。

但我们不会把"本地"当成安全结论。不同岗位助手仍要按职责拆分 Skill、MCP、工具和业务资料;从写稿继续到配图、排版和平台预填时,最终外发动作还需要检查真实页面状态。

一个人的生意,也能有一支专业团队。只是这支团队同样需要岗位权限,不能因为成员是 AI,就把所有系统的钥匙放进同一个工具箱。

最后

内容排除值得做,它能减少敏感内容进入上下文的机会。但要把 Agent 放进真实业务,还需要补上资源白名单、动作级 capability、派生数据标签、输出通道控制和审计证据。

判断一套 Agent 权限设计是否成熟,可以问一个简单问题:

它只能说明"某个文件没被放进 prompt",还是能证明"这个岗位在这次任务里,只对这个版本做了被允许的动作,并且结果去了被允许的地方"?

两者之间,就是过滤器与权限系统的距离。

参考资料:

  • GitHub Changelog:《Content exclusions generally available in Copilot app and CLI》,2026-09-02
  • GitHub Docs:《Content exclusion for GitHub Copilot》,2026-09-03 访问
相关推荐
huashengzsj1 小时前
智汇前沿 洞见未来 | 2026人工智能前沿学术会议将于10月在安徽合肥举办
人工智能·百度
xiaoduo AI1 小时前
抖音小店客服机器人哪个好?选择AI客服主要看哪些功能?
大数据·人工智能·机器人
2501_927283581 小时前
数据采集,正在让工厂从“凭经验”走向“看数据”
运维·人工智能·自动化·数据采集·agv·立体仓库
小柯南敲键盘1 小时前
跨马翻译:图片翻译软件批量处理,跨境电商视频字幕AI智能抠图
人工智能·python·音视频
EasyCVR1 小时前
空地联动!RTMP/GB28181/RTSP/ONVIF视频汇聚平台EasyCVR地质灾害视频监测+无人机巡检救援救援方案
人工智能·easycvr·国标gb28181
m4Rk_1 小时前
【论文阅读】Agent 记忆机制(59):Synapse——让相关记忆沿情景—语义图被逐步激活
论文阅读·人工智能·学习·开源·github
格林威1 小时前
C#图像夜间识别率提升:使用OpenCvSharp和Halcon融合DeepSORT实现复杂场景下准确识别
开发语言·人工智能·数码相机·机器学习·计算机视觉·c#·视觉检测
袁俪1 小时前
智能体搭建
人工智能
开源量化GO1 小时前
先确认策略想法能不能变成规则
人工智能·python