一位监管人员走进你的办公室,提出了安全团队反复演练过的那个问题:“请展示客户数据存放的每一个地方。” 你的数据团队拿出了清单。主数据库在上面。分析型数据仓库在上面。对象存储、队列、搜索索引、备份目的地——统统都在上面,附带着分类标签、保留政策、加密详情和负责人姓名。接着,房间里有人提到了 Agent 工作线程池,而清单上却对此只字未提。这个线程池已经运行了九个月。每个工作线程都有一个本地磁盘。这些线程上的 Agent 一直在解析 PDF、转录音频、下载邮件附件,并在工具调用之间缓存中间 JSON,而这一切从未停止过。却没有人将这些内容放入资产登记表。
这就是“临时目录问题”(scratch directory problem)。每一个长期运行的 Agent 工作线程都会积累一个临时文件系统,随着新工具的加入而有机增长——PDF 解析器提取的文本、Whisper 步骤转录的音频、Gmail 工具下载的附件、浏览器使用步骤的截图、为下一轮对话缓存的向量搜索片段、Agent 在两次工具调用之间生成的中间 JSON(以便第二次调用不必重新推导)。与数据库、队列和存储桶不同,这个表面没有保留政策,没有静态加密标准,没有 DLP 扫描器过滤,也没有出现在数据分类电子表格中。平台团队认为 “Agent 状态”指的是推理提供商的上下文窗口。SRE 团队认为 “Agent 状态”指的是持久化数据库。而工作线程的 /tmp/agent-workspace-${session_id}/ 目录则是客户数据的第三份副本,且处于无人管理的状态。
为什么清单会遗漏它
传统的数据分类计划建立在一个已不再成立的假设之上:数据存在于命名的系统中。CRM 有名字。数据仓库有名字。存储桶有名字。你通过查询云 API、阅读部署清单或查看采购电子表格来发现它们。分类团队不需要在文件系统中进行 grep 搜索,因为拥有敏感数据的系统都有可以查询的控制平面。
Agent 工作线程打破了这一假设。持有数据的“系统”是无状态容器内的一个目录路径,编排器可以随时替换它。没有 API 调用可以列出“Agent 工作线程临时目录中的所有客户数据”,因为这些目录在任何地方都没有被追踪——它们是由恰好需要临时文件的工具按需创建的。云原生数据发现扫描工具(Wiz、Macie、Microsoft Purview)可以在存储账户级别识别资源并发现敏感内容模式,但它们的默认覆盖范围很难映射到“跨越所有副本、所有 Agent 工作线程 Pod 在部署期间的所有 /tmp/* 的并集”。数据是真实的,暴露面是巨大的;只是清单里没写。
造成这种差距的组织动态甚至比技术原因更可靠。构建工作线程池的 AI 工程团队将其视为计算资源,而非存储资源——一个运行 Agent 循环的地方,而不是存储数据的地方。运营该线程池的 SRE 团队将“数据”视为他们备份的持久层。负责数据分类的安全团队则认为 “Agent 状态”是指推理提供商在其后端处理的内容。这三个团队中没有一个关注磁盘。每个人对自己负责的部分都有一个看似正确的心理模型。他们共同产生了一个盲点,而这个盲点的大小恰好等于工作线程的本地卷。
故障模式枯燥而具体
这里的故障模式并非臆测。每一种都有清晰的物理机制,理应很容易防御——但事实并非如此,因为这个暴露面不在清单上。
工作线程在会话中间重启,编排器将下一个会话调度到具有相同路径方案的同一个节点上。新租户的会话继承了前一个租户的临时目录,因为路径是确定性的——例如 /tmp/agent-workspace-current/ 而非 /tmp/agent-workspace-${session_id}/,或者 session_id 的熵值不够高,亦或是清理钩子在 try 块中运行并静默忽略了 rm -rf 错误。Daily.dev 团队在记录其组织级 Agent 时就曾发布过这类 Bug:前一个用户的写入令牌持久化到了新用户的回合中,因为凭据表面是进程全局的,而非按回合隔离。同样的模式在文件系统状态上也会重演——任何没有被显式按回合隔离的内容,都隐含地跨回合共享。
工作线程卷的备份快照捕获了长达六周的客户附件,因为文件系统级的备份工具不知道要排除 /tmp/agent-workspace。云环境中的卷快照不会读取你的 .gitignore 等效文件。配置备份的人告诉它捕获整个磁盘,基于一个合理的假设:“磁盘上只有系统文件和应用程序二进制文件”。接着,一个需要解析 PDF 的工具将提取的文本丢到了 /var/lib/agent/cache/ 中,下一个快照捕获了它,而快照保留期是 90 天,现在你就拥有了在不符合其分类等级的备份层中存放了两个月的客户 PDF。
一条调试日志记录了 wrote 4.2MB to /tmp/agent-workspace-abc/contract.pdf 并发送到集中日志存储系统。日志中虽然没有内容,但路径在——而路径本身就是一个信号。六个月后查看日志的事故响应人员看到这条消息,并得知了三件事:该工作线程处理看起来像合同的 PDF,工作线程将其存储在本地磁盘,且存储路径方案是 /tmp/agent-workspace-${session_id}/${original_filename}。日志中的原始文件名可能包含客户或事项标识符。即便磁盘本身已加密,日志表面现在也在泄露关于磁盘表面的元数据。
监管机构询问“客户数据存放在哪里”,而安全团队提供的清单中完全缺失了工作线程池。这种故障模式让其他所有问题都变得至关重要。在 SOC 2 或 HIPAA 清单中遗漏一个表面,这种发现会从技术债工单升级为“停止发版”级别的问题,因为监管机构的下一个问题将是:“你们还漏掉了什么?”那个没有将 Agent 临时目录命名为数据存储的团队,无法给出合理的解释。
必须落地的纪律 修复方法不在于架构的复杂性 —— 而在于为这一层命名。一个“智能体临时存储”(agent ephemeral storage)层,应具备与任何其他主存储系统相同的数据分类、保留、加密和删除保证。一旦该层被命名并列入清单,其余的控制措施就会自动纳入组织已经为 bucket 和数据库运行的相同操作规范中。
单会话生命周期是核心的承重原语。暂存目录必须在会话开始时创建一个具有高熵(high-entropy)会话范围路径的目录,仅由在该会话中运行的代码写入,并在会话结束时通过验证读取(verification read)进行擦除,而不是简单的“发后即忘”式 rm -rf。验证环节是大多数团队都会忽略的部分 —— 删除调用返回成功并不意味着磁盘已空,尤其是在文件系统错误或清理程序在孤儿进程恢复路径中运行时。AWS 对多租户智能体 AI 的规范性指南对此有明确规定:每个请求都会获得 /tmp/sandbox/tenants/<hash>/<request_id>/,并在请求完成时的 finally 块中销毁,外加一个后台扫描程序来清理在进程崩溃中幸存的陈旧工作区。后台扫描是弥补“我们编写了清理代码”与“磁盘实际上已干净”之间差距的关键。
单租户子目录命名空间化必须像行级过滤器(row-level filters)一样接受审计。数据库中 WHERE tenant_id = ? 的行级过滤器会在代码审查中被检查,通过跨租户探测进行测试,并在运行时监控是否存在。文件系统的等效项 —— /tmp/sandbox/tenants/${tenant_hash}/ —— 值得同样深度的审查,因为缺失租户范围的失败模式是完全相同的:租户 A 读取了租户 B 的数据。Cloudflare 关于 isolate 优于容器的论点就基于此 —— 容器启动速度太慢,导致团队会在不同任务之间复用它们,而复用正是创造跨租户攻击面的根源。如果你正在运行容器,单任务隔离必须由容器启动速度以外的手段来强制执行。
定期的资产发现扫描需要重新训练,以识别符合客户数据特征的文件系统路径,而不仅仅是存储账号级别的资源。大多数数据发现工具运行在云控制平面:它们枚举 bucket、数据库和磁盘,然后对每个进行抽样。智能体暂存表面位于更深的一层 —— 在一个已被归类为“系统”的磁盘内部。扫描需要深入 worker 的文件系统,寻找符合组织标记模式的路径(PDF 文本、转录音频、任何看起来像邮件附件的内容),然后将其作为新条目呈现在清单中。这在操作上可能令人感到不适,因为这意味着安全工具需要拥有对临时 worker 文件系统的读取权限,但这是随着新工具不断加入,保持清单真实性的唯一方法。
组织的认知觉醒 这种风险面之所以会累积,是因为它掉进了一个极其明显的组织缝隙中。构建智能体的 AI 团队认为他们在编写应用程序代码,而应用程序代码通常不负责自己的数据分类 —— 那是平台的事情。运行 worker 池的平台团队认为他们在提供算力,而算力通常不负责数据分类 —— 那是数据团队的事情。负责分类的数据团队认为他们在对数据库和 bucket 进行编目,他们通常不会深入到应用程序的二进制文件中 —— 那是应用团队的事情。每个团队都有辩护理由称这不是他们的问题。然而,无论如何,磁盘里还是塞满了客户的 PDF。
弥补这一差距的架构认知是:智能体的暂存目录就是一个临时数据仓库 —— 那些还没有为此命名的团队,正在交付一个合规漏洞,其表面积随着每一个写入磁盘的新工具而增长。智能体集成的第一个 PDF 解析器只是一个微小、可控的足迹。Whisper 转录工具紧随其后,足迹稍大一些。浏览器截图工具又增加了一个更大的足迹。到智能体拥有 15 个工具时,磁盘已经成了由每个交付过工具的团队所塑造的客户数据拼贴画,而没有一个唯一的负责人拥有全局视野。
解决方法是在交付下一个工具之前为这一层命名,而不是在下一次监管调查之后。命名迫使清单录入,清单录入迫使保留和加密决策,而这些决策迫使负责 worker 池的团队真正负责其磁盘上的数据。在完成命名之前,worker 的本地卷的受保护程度正如所有人预想的那样 —— 毫无保护。
会员专享
余下内容仅对会员开放。 会员可读完整内容 —— 每一个公开发布的观点背后,那些框架、决策与推理的全貌。
— 完整文章,包含未公开存档的部分 — 可落地的工作框架,附带权衡与决策依据 — 新文章抢先看,先于公开发布 登录以继续阅读→ 随时取消 · 一次订阅,畅读全部