ChatGPT Agent 会签名访问网页后,站点别再只靠 User-Agent 放行

摘要: AI Agent 真正进入日常工作流以后,会遇到一个过去不太显眼、但很快会变成基础设施问题的环节:站点怎么识别“这是一个真实的 AI Agent 正在替用户访问”,而不是普通爬虫、伪造客户端或攻击流量。 以前讨论 Agent,更多是在应用内部:模型如何规划、如何调用工具、如何读文件、如何执行代码。现...

AI Agent 真正进入日常工作流以后,会遇到一个过去不太显眼、但很快会变成基础设施问题的环节:站点怎么识别“这是一个真实的 AI Agent 正在替用户访问”,而不是普通爬虫、伪造客户端或攻击流量。
以前讨论 Agent,更多是在应用内部:模型如何规划、如何调用工具、如何读文件、如何执行代码。现在问题开始外溢到 Web 边界。ChatGPT agent、浏览器 Agent、企业工作区 Agent 都会代表用户访问外部页面、读取资料、登录系统、提交表单,甚至触发购买、预约、发邮件这类真实动作。
这时,如果站点仍然只靠 User-Agent、IP 段、简单 bot 规则来判断流量,就会很尴尬:

  • 放得太宽,伪造的 Agent 流量也能混进来;
  • 拦得太死,真实用户委托的 Agent 无法完成任务;
  • 全部走人机验证,Agent 体验会碎掉;
  • 业务系统看不到“谁替谁做了什么”,后续审计很难补。

所以这次值得关注的变化,不是某个模型又多会点网页操作,而是 AI Agent 流量开始带着可验证身份进入 HTTP 层。这会倒逼应用团队把 Agent 接入从“反爬策略”升级成“边缘鉴权策略”。

这次变化具体是什么

ChatGPT agent 的出站 HTTP 请求已经可以通过签名来识别。它会在请求里携带 HTTP Message Signatures 相关头部,例如 SignatureSignature-Input,并通过 Signature-Agent 标明签名主体。
更关键的是,站点不需要只相信一个字符串。接入层可以通过公开的 key directory 获取验证材料,再按 RFC 9421 的规则验证签名,判断请求是否确实来自对应的 Agent 运行环境。
这和传统 bot 识别有本质区别。
过去的典型做法是:

User-Agent 像不像 IP 是否在已知网段 行为模式是否异常 是否触发挑战页 

这些信号都有价值,但它们更像风险评分。它们不能稳定回答一个问题:这个请求是不是某个声明的 Agent 真的发出的。
签名机制补上的正是这一层身份确认。
在 CDN、WAF 或边缘平台上,这件事会表现为两种路径:

  • 平台已经维护了 verified bot / signed agent 目录,应用只需要用平台暴露的 bot id 或策略开关放行;
  • 平台没有内置目录,应用需要自己在边缘函数、网关或中间件里验证签名。

这意味着,站点的 AI Agent 接入不再应该写成一串 User-Agent contains "ChatGPT" 的规则,而应该写成一套可审计的准入策略。

为什么这对开发者很重要

Agent 流量和普通爬虫最大的不同在于:它经常不是“平台想抓你的内容”,而是“用户让一个 Agent 来替自己完成任务”。
这会让访问语义变复杂。
一个搜索爬虫访问商品页,通常只是读取公开内容。一个用户委托的 Agent 访问同一个商品页,可能会继续登录、比价、加入购物车、填写地址,最后等待用户确认付款。它不是人类浏览器,但也不完全是爬虫。
如果把所有 AI 流量都当爬虫,业务会错过新入口。
如果把所有 Agent 请求都当人类请求,安全边界会变薄。
更合理的方式,是把 Agent 流量分成至少三层:

层级 例子 默认策略
公开读取 文档、价格页、帮助中心、公开商品页 可放行,记录 Agent 身份
登录后读取 订单、工单、企业知识库、报表 需要用户会话和细粒度授权
写入动作 下单、发信、改配置、删数据、创建日程 需要二次确认、风控或人工审批

签名只能证明“这个 Agent 是谁”,不能证明“这个动作一定应该被允许”。
真正的工程边界,应该是 Agent 身份 + 用户身份 + 动作风险 + 业务权限 一起判断。

边缘层应该怎么改

最实用的落点,是先把 Agent 准入放到边缘层,而不是散落在业务代码里。
原因很简单:Agent 流量进入应用之前,已经会经过 CDN、WAF、API Gateway 或 Ingress。这里最适合做三件事:

  • 验证请求是不是可信 Agent;
  • 给请求打上统一的 Agent 身份标签;
  • 按路径、方法和风险等级决定放行、挑战、降级或阻断。

可以先用一份策略文件描述边界,而不是直接把判断写死在代码里:

agents:
  chatgpt.com:
    verify:http-message-signature
    key_directory:https://chatgpt.com/.well-known/http-message-signatures-directory
    allow:
      -method:GET
        path:/docs/**
      -method:GET
        path:/pricing
    require_user_session:
      -method:GET
        path:/account/**
      -method:GET
        path:/orders/**
    require_step_up:
      -method:POST
        path:/checkout/**
      -method:POST
        path:/calendar/events
    block:
      -method:POST
        path:/admin/**

这份配置的重点不是语法,而是边界思路:先识别 Agent,再按动作风险分级。
如果你们已经使用 Cloudflare、Akamai、Vercel 这类平台,优先使用平台自带的 signed agent / verified bot 能力。平台能处理目录维护、签名验证和部分流量分类,应用侧只需要把它映射到自己的访问策略。
如果需要自己做验证,不建议只写一个头部判断:

// 不要把这当成安全校验
const isChatGPT = req.headers["signature-agent"] === '"https://chatgpt.com"';

这只能说明请求声称自己是谁,不能说明它真的由对应主体签名。
更合理的结构是把签名验证做成独立中间件,并且只向业务层暴露验证后的结果:

app.use(async (req, res, next) => {
const agent = await verifySignedAgentRequest(req);

if (agent.verified) {
    req.agentIdentity = {
      id: agent.id,
      operator: agent.operator,
      verifiedAt: newDate().toISOString(),
    };
  }

  next();
});

app.post("/checkout/confirm", requireUserSession, requireStepUp, (req, res) => {
  audit.log({
    actor: req.user.id,
    agent: req.agentIdentity?.id ?? null,
    action: "checkout.confirm",
  });

  res.json({ ok: true });
});

这里的 verifySignedAgentRequest 不应该手写半套 RFC 解析逻辑。生产里更稳的做法,是复用成熟库或网关能力,并把 key 缓存、算法白名单、时间窗口、签名覆盖字段、代理转发后的头部保留都纳入测试。

不要把“可信 Agent”误解成“可信动作”

这是最容易踩坑的地方。
一个请求通过签名验证,只说明它来自某个已识别 Agent。它不代表用户真的授权了当前动作,也不代表业务可以绕过原有安全控制。
比如:

  • Agent 读取公开文档,可以直接放行;
  • Agent 读取用户订单,仍然要有用户登录态;
  • Agent 修改企业配置,仍然要检查 RBAC;
  • Agent 触发付款、发邮件、删除数据,仍然需要确认和审计;
  • Agent 访问高风险路径,仍然可以被风控降级或拦截。

也就是说,签名身份应该进入你的权限系统,而不是替代权限系统。
一个更好的内部模型是:

human_user   delegates_to -> ai_agent   accesses     -> business_resource   performs     -> action   constrained_by -> policy + session + risk + audit 

有了这个模型,系统就不会把 Agent 当成神秘的新角色。它只是访问链路里的一个已验证执行方。

应用团队可以从五个检查点开始

第一,梳理入口路径。
把站点路径按公开读取、登录后读取、低风险写入、高风险写入、后台管理分层。不要等 Agent 大规模访问后再临时补规则。
第二,确认边缘平台能力。
如果 CDN 或 WAF 已经支持 signed agent、verified bot、Web Bot Auth 或 detection id,就优先在边缘层打标签。应用层不应该重复解析一遍所有原始信号。
第三,保留签名相关头部。
很多系统会经过反向代理、网关、服务网格。要确认 SignatureSignature-InputSignature-Agent 这类头部不会被清理、改写或丢失。否则你以为自己做了验证,实际请求到应用时已经没有可验证材料。
第四,写审计日志。
日志里至少应该包含:

{
  "user_id": "u_123",
  "agent_id": "chatgpt.com",
  "agent_verified": true,
  "method": "POST",
  "path": "/calendar/events",
  "policy": "require_step_up",
  "decision": "approved"
}

这类日志的价值不只是安全追溯,也能帮助产品团队判断哪些页面正在被 Agent 使用、哪些流程经常卡住、哪些动作应该提供更适合 Agent 的 API。
第五,做负向测试。
不要只测“真实 Agent 能访问”。还要测:

  • 没有签名能不能混进来;
  • 伪造 Signature-Agent 会不会被放行;
  • 签名过期或重放会不会被拒绝;
  • 中间代理删除头部后系统是否降级到安全状态;
  • 写入动作是否仍然需要用户授权。

这类测试应该进入网关策略和关键业务接口的回归测试,而不是只靠安全同学手工检查。

这件事的长期影响

AI Agent 访问 Web,不会只是“多一种爬虫”。它更像是在浏览器、人类用户、企业 SaaS、支付系统和自动化脚本之间,插入了一个新的执行层。
这个执行层如果没有身份,站点只能粗暴拦截。
这个执行层如果有身份但没有权限模型,站点会过度信任。
真正可持续的方式,是让 Agent 流量具备三个特征:

  • 可识别:请求能证明自己来自哪个 Agent;
  • 可约束:不同 Agent、不同动作、不同用户会话对应不同策略;
  • 可追溯:每次关键动作都能回到用户、Agent、资源和决策依据。

对 AI 应用团队来说,这也是一个提醒:Agent 能不能完成任务,不只取决于模型会不会操作网页,还取决于目标系统是否愿意、是否安全地接纳 Agent 流量。
接下来做面向 Agent 的产品,可能不只是多写几个 API。你还需要设计一套“Agent 接入层”:哪些页面允许读取,哪些动作必须确认,哪些 Agent 可以被信任,哪些日志必须沉淀。
模型能力会继续变强,但生产系统最终要回答的问题很朴素:
当一个 Agent 敲门时,你怎么知道它是谁,又准备让它做到哪一步。

转自:https://mp.weixin.qq.com/s/JuqKiQvmRXgKpnItp9RSYA